RESTinio
from_string_details.ipp
Go to the documentation of this file.
1 namespace restinio
2 {
3 
4 namespace utils
5 {
6 
7 namespace details
8 {
9 
10 template< typename C >
11 const C * digits_mapping()
12 {
13  static constexpr C table[] = {
14  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
15  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
16  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
17 
18  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
19 
20  0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
21  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
22  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
23  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
24  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
25  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
26  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
27  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
28  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
29  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
30  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
31  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
32  return table;
33 }
34 
36 {
37  using type_t = std::int8_t;
38 
39  static constexpr std::size_t
41  {
42  return 3;
43  }
44 
45  static const char *
47  {
48  static constexpr char r[] = "128";
49  return r;
50  }
51 
52  static const char *
54  {
55  static constexpr char r[] = "127";
56  return r;
57  }
58 
59  static const char * type_name()
60  {
61  static constexpr char r[] = "int8_t";
62  return r;
63  }
64 };
65 
67 {
68  using type_t = std::uint8_t;
69 
70  static constexpr std::size_t
72  {
73  return 3;
74  }
75 
76  static const char *
78  {
79  static constexpr char r[] = "0";
80  return r;
81  }
82 
83  static const char *
85  {
86  static constexpr char r[] = "255";
87  return r;
88  }
89 
90  static const char * type_name()
91  {
92  static constexpr char r[] = "uint8_t";
93  return r;
94  }
95 };
96 
98 {
99  using type_t = std::int16_t;
100 
101  static constexpr std::size_t
103  {
104  return 5;
105  }
106 
107  static const char *
109  {
110  static constexpr char r[] = "32768";
111  return r;
112  }
113 
114  static const char *
116  {
117  static constexpr char r[] = "32767";
118  return r;
119  }
120 
121  static const char * type_name()
122  {
123  static constexpr char r[] = "int16_t";
124  return r;
125  }
126 };
127 
129 {
130  using type_t = std::uint16_t;
131 
132  static constexpr std::size_t
134  {
135  return 5;
136  }
137 
138  static const char *
140  {
141  static constexpr char r[] = "0";
142  return r;
143  }
144 
145  static const char *
147  {
148  static constexpr char r[] = "65535";
149  return r;
150  }
151 
152  static const char * type_name()
153  {
154  static constexpr char r[] = "uint16_t";
155  return r;
156  }
157 };
158 
160 {
161  using type_t = std::int32_t;
162 
163  static constexpr std::size_t
165  {
166  return 10;
167  }
168 
169  static const char *
171  {
172  static constexpr char r[] = "2147483648";
173  return r;
174  }
175 
176  static const char *
178  {
179  static constexpr char r[] = "2147483647";
180  return r;
181  }
182 
183  static const char * type_name()
184  {
185  static constexpr char r[] = "int32_t";
186  return r;
187  }
188 };
189 
191 {
192  using type_t = std::uint32_t;
193 
194  static constexpr std::size_t
196  {
197  return 10;
198  }
199 
200  static const char *
202  {
203  static constexpr char r[] = "0";
204  return r;
205  }
206 
207  static const char *
209  {
210  static constexpr char r[] = "4294967295";
211  return r;
212  }
213 
214  static const char * type_name()
215  {
216  static constexpr char r[] = "uint32_t";
217  return r;
218  }
219 };
220 
222 {
223  using type_t = std::int64_t;
224 
225  static constexpr std::size_t
227  {
228  return 19;
229  }
230 
231  static const char *
233  {
234  static constexpr char r[] = "9223372036854775808";
235  return r;
236  }
237 
238  static const char *
240  {
241  static constexpr char r[] = "9223372036854775807";
242  return r;
243  }
244 
245  static const char * type_name()
246  {
247  static constexpr char r[] = "int64_t";
248  return r;
249  }
250 };
251 
253 {
254  using type_t = std::uint64_t;
255 
256  static constexpr std::size_t
258  {
259  return 20;
260  }
261 
262  static const char *
264  {
265  static constexpr char r[] = "0";
266  return r;
267  }
268 
269  static const char *
271  {
272  static constexpr char r[] = "18446744073709551615";
273  return r;
274  }
275 
276  static const char * type_name()
277  {
278  static constexpr char r[] = "uint64_t";
279  return r;
280  }
281 };
282 
283 template < typename Integer >
284 Integer
286  const std::uint8_t * const mapping_table,
287  const char * data_begin,
288  const char * data_end,
289  bool apply_minus_sign,
290  std::true_type /* is signed */)
291 {
292  Integer result = 0;
293 
294  if( apply_minus_sign )
295  while( data_begin != data_end )
296  {
297  result = result*10 - mapping_table[ static_cast< std::size_t >( *data_begin++ ) ];
298  }
299  else
300  while( data_begin != data_end )
301  {
302  result = result*10 + mapping_table[ static_cast< std::size_t >( *data_begin++ ) ];
303  }
304 
305  return result;
306 }
307 
308 template < typename Integer >
309 Integer
311  const std::uint8_t * const mapping_table,
312  const char * data_begin,
313  const char * data_end,
314  bool ,
315  std::false_type /* is signed */ )
316 {
317  Integer result = 0;
318 
319  while( data_begin != data_end )
320  {
321  result = result * 10 + mapping_table[ static_cast< std::size_t >( *data_begin++ ) ];
322  }
323 
324  return result;
325 }
326 
327 template < typename Traits >
328 typename Traits::type_t
329 parse_integer( const char * data_begin, const char * data_end )
330 {
331  bool apply_minus_sign = false;
332  if( '-' == *data_begin )
333  {
334  if( !std::is_signed< typename Traits::type_t >::value )
335  {
336  throw exception_t{
337  fmt::format(
338  "invalid {} value: unsigned starts with minus",
339  Traits::type_name() ) };
340  }
341 
342  // else:
343  apply_minus_sign = true;
344  ++data_begin;
345  }
346  else if( '+' == *data_begin )
347  {
348  ++data_begin;
349  }
350 
351  const auto representation_size = static_cast< std::size_t >( data_end - data_begin );
352 
353  if( 0 == representation_size )
354  throw exception_t{ fmt::format( "invalid {} value: empty string", Traits::type_name() ) };
355 
356  if( Traits::digits_representation_max_size() < representation_size )
357  throw exception_t{
358  fmt::format(
359  "invalid {} value: max digits for type is {}",
360  Traits::type_name(),
361  Traits::digits_representation_max_size() ) };
362 
363  const std::uint8_t * const mapping_table = digits_mapping< std::uint8_t >();
364 
365  if( std::any_of(
366  data_begin,
367  data_end,
368  [&]( auto d ){ return 0xFF == mapping_table[ static_cast< std::size_t >( d ) ]; } ) )
369  {
370  throw exception_t{
371  fmt::format( "invalid {} value: invalid digit", Traits::type_name() ) };
372  }
373 
374  if( Traits::digits_representation_max_size() == representation_size )
375  {
376  const char * const posssible_max = apply_minus_sign ?
377  Traits::min_representation() : Traits::max_representation();
378 
379  if( 0 < std::memcmp( data_begin, posssible_max, representation_size ) )
380  throw std::out_of_range{
381  fmt::format( "invalid {} value: out of range", Traits::type_name() ) };
382  }
383 
384  using is_signed_t = typename std::is_signed< typename Traits::type_t >::type;
385 
386  return
387  parse_integer_no_checks< typename Traits::type_t >(
388  mapping_table,
389  data_begin,
390  data_end,
391  apply_minus_sign,
392  is_signed_t{} );
393 }
394 
395 } /* namespace details */
396 
397 } /* namespace utils */
398 
399 } /* namespace restinio */
restinio::exception_t
Exception class for all exceptions thrown by RESTinio.
Definition: exception.hpp:26
restinio::utils::details::int8_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:59
restinio::utils::details::uint8_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:84
restinio::utils::details::int64_parse_traits_t
Definition: from_string_details.ipp:222
restinio::utils::details::uint16_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:139
restinio::utils::details::uint32_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:195
restinio::utils::details::int8_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:53
restinio::utils::details::uint32_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:201
restinio::utils::details::uint8_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:90
restinio::utils::details::int16_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:115
restinio::utils::details::int16_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:102
restinio::utils::details::uint64_parse_traits_t::type_t
std::uint64_t type_t
Definition: from_string_details.ipp:254
restinio::utils::details::uint64_parse_traits_t
Definition: from_string_details.ipp:253
restinio::utils::details::int32_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:170
restinio::utils::details::int32_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:177
restinio::utils::details::int32_parse_traits_t::type_t
std::int32_t type_t
Definition: from_string_details.ipp:161
restinio::utils::details::uint64_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:257
restinio::utils::details::uint32_parse_traits_t
Definition: from_string_details.ipp:191
restinio::utils::details::int64_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:226
restinio::utils::details::int32_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:183
restinio::utils::details::int8_parse_traits_t::type_t
std::int8_t type_t
Definition: from_string_details.ipp:37
restinio::utils::details::uint8_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:71
restinio::utils::details::parse_integer_no_checks
Integer parse_integer_no_checks(const std::uint8_t *const mapping_table, const char *data_begin, const char *data_end, bool apply_minus_sign, std::true_type)
Definition: from_string_details.ipp:285
restinio::utils::details::uint32_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:208
restinio::utils::details::int64_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:245
restinio::utils::details::int16_parse_traits_t::type_t
std::int16_t type_t
Definition: from_string_details.ipp:99
restinio::utils::details::int64_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:232
restinio::utils::details::uint64_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:276
restinio::utils::details::int32_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:164
restinio::utils::details::int16_parse_traits_t
Definition: from_string_details.ipp:98
restinio::utils::details::uint16_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:152
restinio::utils::details::int8_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:46
restinio::utils::details::uint64_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:270
restinio::utils::details::uint16_parse_traits_t
Definition: from_string_details.ipp:129
restinio::utils::details::digits_mapping
const C * digits_mapping()
Definition: from_string_details.ipp:11
restinio::utils::details::int16_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:121
restinio::utils::details::int8_parse_traits_t
Definition: from_string_details.ipp:36
restinio::utils::details::uint16_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:133
restinio::utils::details::parse_integer
Traits::type_t parse_integer(const char *data_begin, const char *data_end)
Definition: from_string_details.ipp:329
restinio
Definition: asio_include.hpp:21
restinio::utils::details::int16_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:108
restinio::utils::details::int32_parse_traits_t
Definition: from_string_details.ipp:160
restinio::utils::details::int64_parse_traits_t::type_t
std::int64_t type_t
Definition: from_string_details.ipp:223
restinio::utils::details::uint8_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:77
restinio::utils::details::uint8_parse_traits_t
Definition: from_string_details.ipp:67
restinio::utils::details::int8_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:40
restinio::utils::details::int64_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:239
restinio::utils::details::uint32_parse_traits_t::type_t
std::uint32_t type_t
Definition: from_string_details.ipp:192
restinio::utils::details::uint64_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:263
restinio::utils::tuple_algorithms::any_of
RESTINIO_NODISCARD bool any_of(Tuple &&tuple, Predicate &&predicate)
Definition: tuple_algorithms.hpp:117
restinio::utils::details::uint16_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:146
restinio::utils::details::uint32_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:214
restinio::utils::details::uint8_parse_traits_t::type_t
std::uint8_t type_t
Definition: from_string_details.ipp:68
restinio::utils::details::uint16_parse_traits_t::type_t
std::uint16_t type_t
Definition: from_string_details.ipp:130