cppx-core
ascii-util.hpp
Go to the documentation of this file.
1 #pragma once // Source encoding: UTF-8 with BOM (π is a lowercase Greek "pi").
2 #include <cppx-core/collections/Range_.hpp> // cppx::Range
3 #include <cppx-core/language/syntax/macro-items_of.hpp> // CPPX_ITEMS_OF
4 #include <cppx-core/language/syntax/macro-use.hpp> // CPPX_USE_STD
5 #include <cppx-core/language/types/byte-types.hpp> // cppx::Byte
6 #include <cppx-core/language/types/Truth.hpp> // cppx::Truth
7 #include <cppx-core/language/types/type-makers.hpp> // cppx::(R_, P_, Unsigned_)
8 #include <cppx-core/meta-template/enable_if_.hpp> // cppx::Enable_if_
9 #include <cppx-core/meta-type/type-traits.hpp> // cppx::is_cpp03_char_type_
10 #include <cppx-core/text/data/ascii-character-names.hpp> // cppx::ascii::/names/
11 
12 #include <c/string.hpp> // strlen
13 #include <c/ctype.hpp> // isspace
14 #include <string> // std::(string, wstring)
15 #include <string_view> // std::string_view
16 #include <functional> // std::invoke
17 
18 namespace cppx::cstdlib
19 {
20  // Depends on the C level locale (setlocale)
21 
22  template<
23  class Char,
24  class = Enable_if_< is_a_cpp03_char_type_<Char> or is_a_char_variant_type_<Char> >
25  >
26  inline auto is_space( const Char ch )
27  -> Truth
28  { return !!::isspace( static_cast<Byte>( ch ) ); }
29 
30  template<>
31  inline auto is_space<wchar_t>( const wchar_t ch )
32  -> Truth
33  { return !!::iswspace( ch ); }
34 
35 } // namespace cppx::cstdlib
36 
37 namespace cppx::ascii
38 {
40  basic_string, basic_string_view, invoke, string, string_view, wstring, wstring_view
41  );
42 
43  //---------------------------------------- Is-ASCII checking:
44 
45  template< class Integer >
46  inline auto contains( const Integer v )
47  -> Truth
48  { return (static_cast<Unsigned_<Integer>>( v ) <= ascii::last_char); }
49 
50  template< class It >
51  inline auto contains_all_of( const It start, const It beyond )
52  -> Truth
53  {
54  for( It it = start; it != beyond; ++it )
55  {
56  if( not contains( *it ) ) { return false; }
57  }
58  return true;
59  }
60 
61  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
62  inline auto contains_all_of( const basic_string_view<Char>& sv )
63  -> Truth
64  { return contains_all_of( CPPX_ITEMS_OF( sv ) ); }
65 
66  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
67  inline auto contains_all_of( const P_<const Char> s )
68  -> Truth
69  { return contains_all_of( basic_string_view<Char>( s ) ); }
70 
71  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
72  inline auto contains_all_of( const basic_string<Char>& s )
73  -> Truth
74  { return contains_all_of( basic_string_view<Char>( s ) ); }
75 
76 
77  //---------------------------------------- ascii::to_wide:
78 
79  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
80  inline auto to_wide( const basic_string_view<Char>& v )
81  -> wstring
82  { return wstring( v.begin(), v.end() ); }
83 
84  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
85  inline auto to_wide( const P_<const Char> s )
86  -> wstring
87  { return to_wide( basic_string_view<Char>( s ) ); }
88 
89  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
90  inline auto to_wide( const basic_string<Char>& s )
91  -> wstring
92  { return to_wide( basic_string_view<Char>( s ) ); }
93 
94 
95  //---------------------------------------- Whitespace checking:
96 
97  // Is independent of locale
98  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
99  inline auto is_whitespace( const Char ch )
100  -> Truth
101  { return ascii::contains( ch ) and cstdlib::is_space( ch ); }
102 
103  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
104  inline auto is_all_whitespace( const basic_string_view<Char>& sv )
105  -> Truth
106  {
107  for( const Char ch : sv )
108  {
109  if( not is_whitespace( ch ) )
110  {
111  return false;
112  }
113  }
114  return true;
115  }
116 
117  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
118  inline auto is_all_whitespace( const basic_string<Char>& s )
119  -> Truth
120  { return is_all_whitespace( basic_string_view<Char>( s ) ); }
121 
122  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
123  inline auto is_all_whitespace( const P_<const Char> s )
124  -> Truth
125  { return is_all_whitespace( basic_string_view<Char>( s ) ); }
126 
127  inline auto whitespace_characters()
128  -> const string&
129  {
130  static const string the_chars = invoke([]() -> string
131  {
132  string result;
133  for( const int code: Range( 0, last_char ) )
134  {
135  if( is_whitespace( char( code ) ) )
136  {
137  result += char( code );
138  }
139  }
140  return result;
141  } );
142 
143  return the_chars;
144  }
145 
146  //---------------------------------------- Uppercase/lowercase:
147 
148  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
149  inline auto is_lowercase( const Char ch )
150  -> Truth
151  { return 'a' <= ch and ch <= 'z'; }
152 
153  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
154  inline auto is_uppercase( const Char ch )
155  -> Truth
156  { return 'A' <= ch and ch <= 'Z'; }
157 
158  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
159  inline auto to_lowercase( const Char ch )
160  -> Char
161  { return (is_uppercase( ch )? Char( ch - 'A' + 'a' ) : ch); }
162 
163  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
164  inline auto to_uppercase( const Char ch )
165  -> Char
166  { return (is_lowercase( ch )? Char( ch - 'a' + 'A' ) : ch); }
167 
168  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
169  inline auto to_lowercase( const basic_string_view<Char>& v )
170  -> basic_string<Char>
171  {
172  basic_string<Char> result;
173  result.reserve( v.size() );
174  for( const Char ch : v )
175  {
176  result += to_lowercase( ch );
177  }
178  return result;
179  }
180 
181  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
182  inline auto to_uppercase( const basic_string_view<Char>& v )
183  -> basic_string<Char>
184  {
185  basic_string<Char> result;
186  result.reserve( v.size() );
187  for( const Char ch : v )
188  {
189  result += to_uppercase( ch );
190  }
191  return result;
192  }
193 
194  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
195  inline auto to_lowercase( const P_<const Char> s )
196  -> basic_string<Char>
197  { return to_lowercase( basic_string_view<Char>( s ) ); }
198 
199  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
200  inline auto to_uppercase( const P_<const Char> s )
201  -> basic_string<Char>
202  { return to_uppercase( basic_string_view<Char>( s ) ); }
203 
204  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
205  inline auto to_lowercase( const basic_string<Char>& s )
206  -> basic_string<Char>
207  { return to_lowercase( basic_string_view<Char>( s ) ); }
208 
209  template< class Char, class = Enable_if_<is_a_cpp03_char_type_<Char>>>
210  inline auto to_uppercase( const basic_string<Char>& s )
211  -> basic_string<Char>
212  { return to_uppercase( basic_string_view<Char>( s ) ); }
213 
214 
215  //---------------------------------------- Misc:
216 
217  inline auto quoted( const string_view& sv )
218  -> string
219  {
220  string s;
221  s = "\"";
222  s += sv;
223  s += "\"";
224  return s;
225  }
226 
227  inline auto quoted( const char ch )
228  -> string
229  { return quoted( string_view( &ch, 1 ) ); }
230 
231 } // namespace cppx::ascii
Some_type * P_
Creates a raw pointer type.
auto contains_all_of(const basic_string< Char > &s) -> Truth
Definition: ascii-util.hpp:72
A drop-in replacement for bool without implicit conversion from/to types other than bool.
Definition: Truth.hpp:34
auto is_all_whitespace(const P_< const Char > s) -> Truth
Definition: ascii-util.hpp:123
auto is_whitespace(const Char ch) -> Truth
Definition: ascii-util.hpp:99
std::make_unsigned_t< Integer > Unsigned_
For an integer type, produces the corresponding unsigned type.
Definition: type-makers.hpp:49
Type_choice_, Unptr_, Unref_, Signed_, Unsigned_, Const_, Unconst_ and Array_of_.
Truth is a drop-in replacement for bool without implicit conversion from/to types other than bool.
auto is_space< wchar_t >(const wchar_t ch) -> Truth
Definition: ascii-util.hpp:31
CPPX_USE_STD(basic_string, basic_string_view, bitset, char_traits, size)
auto is_uppercase(const Char ch) -> Truth
Definition: ascii-util.hpp:154
auto to_lowercase(const basic_string< Char > &s) -> basic_string< Char >
Definition: ascii-util.hpp:205
auto to_uppercase(const basic_string< Char > &s) -> basic_string< Char >
Definition: ascii-util.hpp:210
$items_of eases use of standard library functions, e.g. sort( $items_of( numbers ) ).
auto quoted(const string_view &sv) -> string
Definition: string-util.hpp:60
Range_< int > Range
Definition: Range_.hpp:55
#define CPPX_ITEMS_OF(c)
$items_of(c) effectively expands to std::begin(c), std::end(c).
std::enable_if_t< condition, Result > Enable_if_
Just more readable than enable_if_t.
Macros for generating more concise and clear using statements, primarily $use_cppx and $use_std,...
Byte and Signed_byte, + std::byte support definitions as_number and as_std_byte.
auto is_space(const Char ch) -> Truth
Definition: ascii-util.hpp:26
auto is_lowercase(const Char ch) -> Truth
Definition: ascii-util.hpp:149
auto contains(const Integer v) -> Truth
Definition: ascii-util.hpp:46
auto to_wide(const basic_string< Char > &s) -> wstring
Definition: ascii-util.hpp:90
auto whitespace_characters() -> const string &
Definition: ascii-util.hpp:127