libstdc++
charconv
Go to the documentation of this file.
1 // Primitive numeric conversions (to_chars and from_chars) -*- C++ -*-
2 
3 // Copyright (C) 2017-2020 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file include/charconv
26  * This is a Standard C++ Library header.
27  */
28 
29 #ifndef _GLIBCXX_CHARCONV
30 #define _GLIBCXX_CHARCONV 1
31 
32 #pragma GCC system_header
33 
34 #if __cplusplus >= 201402L
35 
36 #include <type_traits>
37 #include <limits>
38 #include <bit> // for __log2p1
39 #include <cctype> // for isdigit
40 #include <bits/charconv.h> // for __to_chars_len, __to_chars_10_impl
41 #include <bits/error_constants.h> // for std::errc
42 
43 // Define when floating point is supported: #define __cpp_lib_to_chars 201611L
44 
45 namespace std _GLIBCXX_VISIBILITY(default)
46 {
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
48 
49  /// Result type of std::to_chars
51  {
52  char* ptr;
53  errc ec;
54  };
55 
56  /// Result type of std::from_chars
58  {
59  const char* ptr;
60  errc ec;
61  };
62 
63 namespace __detail
64 {
65  template<typename _Tp>
66  using __integer_to_chars_result_type
68  __is_unsigned_integer<_Tp>,
71 
72  // Pick an unsigned type of suitable size. This is used to reduce the
73  // number of specializations of __to_chars_len, __to_chars etc. that
74  // get instantiated. For example, to_chars<char> and to_chars<short>
75  // and to_chars<unsigned> will all use the same code, and so will
76  // to_chars<long> when sizeof(int) == sizeof(long).
77  template<typename _Tp>
78  struct __to_chars_unsigned_type : __make_unsigned_selector_base
79  {
80  using _UInts = _List<unsigned int, unsigned long, unsigned long long
81 #if _GLIBCXX_USE_INT128
82  , unsigned __int128
83 #endif
84  >;
85  using type = typename __select<sizeof(_Tp), _UInts>::__type;
86  };
87 
88  template<typename _Tp>
89  using __unsigned_least_t = typename __to_chars_unsigned_type<_Tp>::type;
90 
91  // Generic implementation for arbitrary bases.
92  // Defined in <bits/charconv.h>.
93  template<typename _Tp>
94  constexpr unsigned
95  __to_chars_len(_Tp __value, int __base /* = 10 */) noexcept;
96 
97  template<typename _Tp>
98  constexpr unsigned
99  __to_chars_len_2(_Tp __value) noexcept
100  { return std::__log2p1(__value); }
101 
102  // Generic implementation for arbitrary bases.
103  template<typename _Tp>
104  to_chars_result
105  __to_chars(char* __first, char* __last, _Tp __val, int __base) noexcept
106  {
107  static_assert(is_integral<_Tp>::value, "implementation bug");
108  static_assert(is_unsigned<_Tp>::value, "implementation bug");
109 
110  to_chars_result __res;
111 
112  const unsigned __len = __to_chars_len(__val, __base);
113 
114  if (__builtin_expect((__last - __first) < __len, 0))
115  {
116  __res.ptr = __last;
117  __res.ec = errc::value_too_large;
118  return __res;
119  }
120 
121  unsigned __pos = __len - 1;
122 
123  static constexpr char __digits[] = {
124  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
125  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
126  'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
127  'u', 'v', 'w', 'x', 'y', 'z'
128  };
129 
130  while (__val >= __base)
131  {
132  auto const __quo = __val / __base;
133  auto const __rem = __val % __base;
134  __first[__pos--] = __digits[__rem];
135  __val = __quo;
136  }
137  *__first = __digits[__val];
138 
139  __res.ptr = __first + __len;
140  __res.ec = {};
141  return __res;
142  }
143 
144  template<typename _Tp>
145  __integer_to_chars_result_type<_Tp>
146  __to_chars_16(char* __first, char* __last, _Tp __val) noexcept
147  {
148  static_assert(is_integral<_Tp>::value, "implementation bug");
149  static_assert(is_unsigned<_Tp>::value, "implementation bug");
150 
151  to_chars_result __res;
152 
153  const unsigned __len = (__to_chars_len_2(__val) + 3) / 4;
154 
155  if (__builtin_expect((__last - __first) < __len, 0))
156  {
157  __res.ptr = __last;
158  __res.ec = errc::value_too_large;
159  return __res;
160  }
161 
162  static constexpr char __digits[] = {
163  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
164  'a', 'b', 'c', 'd', 'e', 'f'
165  };
166  unsigned __pos = __len - 1;
167  while (__val >= 0x100)
168  {
169  auto __num = __val & 0xF;
170  __val >>= 4;
171  __first[__pos] = __digits[__num];
172  __num = __val & 0xF;
173  __val >>= 4;
174  __first[__pos - 1] = __digits[__num];
175  __pos -= 2;
176  }
177  if (__val >= 0x10)
178  {
179  const auto __num = __val & 0xF;
180  __val >>= 4;
181  __first[1] = __digits[__num];
182  __first[0] = __digits[__val];
183  }
184  else
185  __first[0] = __digits[__val];
186  __res.ptr = __first + __len;
187  __res.ec = {};
188  return __res;
189  }
190 
191  template<typename _Tp>
192  inline __integer_to_chars_result_type<_Tp>
193  __to_chars_10(char* __first, char* __last, _Tp __val) noexcept
194  {
195  static_assert(is_integral<_Tp>::value, "implementation bug");
196  static_assert(is_unsigned<_Tp>::value, "implementation bug");
197 
198  to_chars_result __res;
199 
200  const unsigned __len = __to_chars_len(__val, 10);
201 
202  if (__builtin_expect((__last - __first) < __len, 0))
203  {
204  __res.ptr = __last;
205  __res.ec = errc::value_too_large;
206  return __res;
207  }
208 
209  __detail::__to_chars_10_impl(__first, __len, __val);
210  __res.ptr = __first + __len;
211  __res.ec = {};
212  return __res;
213  }
214 
215  template<typename _Tp>
216  __integer_to_chars_result_type<_Tp>
217  __to_chars_8(char* __first, char* __last, _Tp __val) noexcept
218  {
219  static_assert(is_integral<_Tp>::value, "implementation bug");
220  static_assert(is_unsigned<_Tp>::value, "implementation bug");
221 
222  to_chars_result __res;
223  unsigned __len;
224 
225  if _GLIBCXX17_CONSTEXPR (numeric_limits<_Tp>::digits <= 16)
226  {
227  __len = __val > 077777u ? 6u
228  : __val > 07777u ? 5u
229  : __val > 0777u ? 4u
230  : __val > 077u ? 3u
231  : __val > 07u ? 2u
232  : 1u;
233  }
234  else
235  __len = (__to_chars_len_2(__val) + 2) / 3;
236 
237  if (__builtin_expect((__last - __first) < __len, 0))
238  {
239  __res.ptr = __last;
240  __res.ec = errc::value_too_large;
241  return __res;
242  }
243 
244  unsigned __pos = __len - 1;
245  while (__val >= 0100)
246  {
247  auto __num = __val & 7;
248  __val >>= 3;
249  __first[__pos] = '0' + __num;
250  __num = __val & 7;
251  __val >>= 3;
252  __first[__pos - 1] = '0' + __num;
253  __pos -= 2;
254  }
255  if (__val >= 010)
256  {
257  auto const __num = __val & 7;
258  __val >>= 3;
259  __first[1] = '0' + __num;
260  __first[0] = '0' + __val;
261  }
262  else
263  __first[0] = '0' + __val;
264  __res.ptr = __first + __len;
265  __res.ec = {};
266  return __res;
267  }
268 
269  template<typename _Tp>
270  __integer_to_chars_result_type<_Tp>
271  __to_chars_2(char* __first, char* __last, _Tp __val) noexcept
272  {
273  static_assert(is_integral<_Tp>::value, "implementation bug");
274  static_assert(is_unsigned<_Tp>::value, "implementation bug");
275 
276  to_chars_result __res;
277 
278  const unsigned __len = __to_chars_len_2(__val);
279 
280  if (__builtin_expect((__last - __first) < __len, 0))
281  {
282  __res.ptr = __last;
283  __res.ec = errc::value_too_large;
284  return __res;
285  }
286 
287  unsigned __pos = __len - 1;
288 
289  while (__pos)
290  {
291  __first[__pos--] = '0' + (__val & 1);
292  __val >>= 1;
293  }
294  // First digit is always '1' because __to_chars_len_2 skips
295  // leading zero bits and std::to_chars handles zero values
296  // directly.
297  __first[0] = '1';
298 
299  __res.ptr = __first + __len;
300  __res.ec = {};
301  return __res;
302  }
303 
304 } // namespace __detail
305 
306  template<typename _Tp>
307  __detail::__integer_to_chars_result_type<_Tp>
308  __to_chars_i(char* __first, char* __last, _Tp __value, int __base = 10)
309  {
310  __glibcxx_assert(2 <= __base && __base <= 36);
311 
312  using _Up = __detail::__unsigned_least_t<_Tp>;
313  _Up __unsigned_val = __value;
314 
315  if (__value == 0 && __first != __last)
316  {
317  *__first = '0';
318  return { __first + 1, errc{} };
319  }
320 
321  if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
322  if (__value < 0)
323  {
324  if (__builtin_expect(__first != __last, 1))
325  *__first++ = '-';
326  __unsigned_val = _Up(~__value) + _Up(1);
327  }
328 
329  switch (__base)
330  {
331  case 16:
332  return __detail::__to_chars_16(__first, __last, __unsigned_val);
333  case 10:
334  return __detail::__to_chars_10(__first, __last, __unsigned_val);
335  case 8:
336  return __detail::__to_chars_8(__first, __last, __unsigned_val);
337  case 2:
338  return __detail::__to_chars_2(__first, __last, __unsigned_val);
339  default:
340  return __detail::__to_chars(__first, __last, __unsigned_val, __base);
341  }
342  }
343 
344 #define _GLIBCXX_TO_CHARS(T) \
345  inline to_chars_result \
346  to_chars(char* __first, char* __last, T __value, int __base = 10) \
347  { return std::__to_chars_i<T>(__first, __last, __value, __base); }
348 _GLIBCXX_TO_CHARS(char)
349 _GLIBCXX_TO_CHARS(signed char)
350 _GLIBCXX_TO_CHARS(unsigned char)
351 _GLIBCXX_TO_CHARS(signed short)
352 _GLIBCXX_TO_CHARS(unsigned short)
353 _GLIBCXX_TO_CHARS(signed int)
354 _GLIBCXX_TO_CHARS(unsigned int)
355 _GLIBCXX_TO_CHARS(signed long)
356 _GLIBCXX_TO_CHARS(unsigned long)
357 _GLIBCXX_TO_CHARS(signed long long)
358 _GLIBCXX_TO_CHARS(unsigned long long)
359 #if defined(__GLIBCXX_TYPE_INT_N_0)
360 _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_0)
361 _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_0)
362 #endif
363 #if defined(__GLIBCXX_TYPE_INT_N_1)
364 _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_1)
365 _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_1)
366 #endif
367 #if defined(__GLIBCXX_TYPE_INT_N_2)
368 _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_2)
369 _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_2)
370 #endif
371 #if defined(__GLIBCXX_TYPE_INT_N_3)
372 _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_3)
373 _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_3)
374 #endif
375 #undef _GLIBCXX_TO_CHARS
376 
377  // _GLIBCXX_RESOLVE_LIB_DEFECTS
378  // 3266. to_chars(bool) should be deleted
379  to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
380 
381 namespace __detail
382 {
383  template<typename _Tp>
384  bool
385  __raise_and_add(_Tp& __val, int __base, unsigned char __c)
386  {
387  if (__builtin_mul_overflow(__val, __base, &__val)
388  || __builtin_add_overflow(__val, __c, &__val))
389  return false;
390  return true;
391  }
392 
393  /// std::from_chars implementation for integers in base 2.
394  template<typename _Tp>
395  bool
396  __from_chars_binary(const char*& __first, const char* __last, _Tp& __val)
397  {
398  static_assert(is_integral<_Tp>::value, "implementation bug");
399  static_assert(is_unsigned<_Tp>::value, "implementation bug");
400 
401  const ptrdiff_t __len = __last - __first;
402  int __i = 0;
403  while (__i < __len)
404  {
405  const unsigned char __c = (unsigned)__first[__i] - '0';
406  if (__c < 2)
407  __val = (__val << 1) | __c;
408  else
409  break;
410  __i++;
411  }
412  __first += __i;
413  return __i <= numeric_limits<_Tp>::digits;
414  }
415 
416  /// std::from_chars implementation for integers in bases 3 to 10.
417  template<typename _Tp>
418  bool
419  __from_chars_digit(const char*& __first, const char* __last, _Tp& __val,
420  int __base)
421  {
422  static_assert(is_integral<_Tp>::value, "implementation bug");
423  static_assert(is_unsigned<_Tp>::value, "implementation bug");
424 
425  auto __matches = [__base](char __c) {
426  return '0' <= __c && __c <= ('0' + (__base - 1));
427  };
428 
429  while (__first != __last)
430  {
431  const char __c = *__first;
432  if (__matches(__c))
433  {
434  if (!__raise_and_add(__val, __base, __c - '0'))
435  {
436  while (++__first != __last && __matches(*__first))
437  ;
438  return false;
439  }
440  __first++;
441  }
442  else
443  return true;
444  }
445  return true;
446  }
447 
448  constexpr unsigned char
449  __from_chars_alpha_to_num(char __c)
450  {
451  switch (__c)
452  {
453  case 'a':
454  case 'A':
455  return 10;
456  case 'b':
457  case 'B':
458  return 11;
459  case 'c':
460  case 'C':
461  return 12;
462  case 'd':
463  case 'D':
464  return 13;
465  case 'e':
466  case 'E':
467  return 14;
468  case 'f':
469  case 'F':
470  return 15;
471  case 'g':
472  case 'G':
473  return 16;
474  case 'h':
475  case 'H':
476  return 17;
477  case 'i':
478  case 'I':
479  return 18;
480  case 'j':
481  case 'J':
482  return 19;
483  case 'k':
484  case 'K':
485  return 20;
486  case 'l':
487  case 'L':
488  return 21;
489  case 'm':
490  case 'M':
491  return 22;
492  case 'n':
493  case 'N':
494  return 23;
495  case 'o':
496  case 'O':
497  return 24;
498  case 'p':
499  case 'P':
500  return 25;
501  case 'q':
502  case 'Q':
503  return 26;
504  case 'r':
505  case 'R':
506  return 27;
507  case 's':
508  case 'S':
509  return 28;
510  case 't':
511  case 'T':
512  return 29;
513  case 'u':
514  case 'U':
515  return 30;
516  case 'v':
517  case 'V':
518  return 31;
519  case 'w':
520  case 'W':
521  return 32;
522  case 'x':
523  case 'X':
524  return 33;
525  case 'y':
526  case 'Y':
527  return 34;
528  case 'z':
529  case 'Z':
530  return 35;
531  }
533  }
534 
535  /// std::from_chars implementation for integers in bases 11 to 26.
536  template<typename _Tp>
537  bool
538  __from_chars_alnum(const char*& __first, const char* __last, _Tp& __val,
539  int __base)
540  {
541  bool __valid = true;
542  while (__first != __last)
543  {
544  unsigned char __c = *__first;
545  if (std::isdigit(__c))
546  __c -= '0';
547  else
548  {
549  __c = __from_chars_alpha_to_num(__c);
550  if (__c >= __base)
551  break;
552  }
553 
554  if (__builtin_expect(__valid, 1))
555  __valid = __raise_and_add(__val, __base, __c);
556  __first++;
557  }
558  return __valid;
559  }
560 
561  template<typename _Tp>
562  using __integer_from_chars_result_type
564  __is_unsigned_integer<_Tp>,
567 
568 } // namespace __detail
569 
570  /// std::from_chars for integral types.
571  template<typename _Tp>
572  __detail::__integer_from_chars_result_type<_Tp>
573  from_chars(const char* __first, const char* __last, _Tp& __value,
574  int __base = 10)
575  {
576  __glibcxx_assert(2 <= __base && __base <= 36);
577 
578  from_chars_result __res{__first, {}};
579 
580  int __sign = 1;
581  if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
582  if (__first != __last && *__first == '-')
583  {
584  __sign = -1;
585  ++__first;
586  }
587 
588  using _Up = __detail::__unsigned_least_t<_Tp>;
589  _Up __val = 0;
590 
591  const auto __start = __first;
592  bool __valid;
593  if (__base == 2)
594  __valid = __detail::__from_chars_binary(__first, __last, __val);
595  else if (__base <= 10)
596  __valid = __detail::__from_chars_digit(__first, __last, __val, __base);
597  else
598  __valid = __detail::__from_chars_alnum(__first, __last, __val, __base);
599 
600  if (__builtin_expect(__first == __start, 0))
601  __res.ec = errc::invalid_argument;
602  else
603  {
604  __res.ptr = __first;
605  if (!__valid)
606  __res.ec = errc::result_out_of_range;
607  else
608  {
609  if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
610  {
611  _Tp __tmp;
612  if (__builtin_mul_overflow(__val, __sign, &__tmp))
613  __res.ec = errc::result_out_of_range;
614  else
615  __value = __tmp;
616  }
617  else
618  {
619  if _GLIBCXX17_CONSTEXPR
621  {
622  if (__val > numeric_limits<_Tp>::max())
623  __res.ec = errc::result_out_of_range;
624  else
625  __value = __val;
626  }
627  else
628  __value = __val;
629  }
630  }
631  }
632  return __res;
633  }
634 
635  /// floating-point format for primitive numerical conversion
636  enum class chars_format
637  {
638  scientific = 1, fixed = 2, hex = 4, general = fixed | scientific
639  };
640 
641  constexpr chars_format
642  operator|(chars_format __lhs, chars_format __rhs) noexcept
643  { return (chars_format)((unsigned)__lhs | (unsigned)__rhs); }
644 
645  constexpr chars_format
646  operator&(chars_format __lhs, chars_format __rhs) noexcept
647  { return (chars_format)((unsigned)__lhs & (unsigned)__rhs); }
648 
649  constexpr chars_format
650  operator^(chars_format __lhs, chars_format __rhs) noexcept
651  { return (chars_format)((unsigned)__lhs ^ (unsigned)__rhs); }
652 
653  constexpr chars_format
654  operator~(chars_format __fmt) noexcept
655  { return (chars_format)~(unsigned)__fmt; }
656 
657  constexpr chars_format&
658  operator|=(chars_format& __lhs, chars_format __rhs) noexcept
659  { return __lhs = __lhs | __rhs; }
660 
661  constexpr chars_format&
662  operator&=(chars_format& __lhs, chars_format __rhs) noexcept
663  { return __lhs = __lhs & __rhs; }
664 
665  constexpr chars_format&
666  operator^=(chars_format& __lhs, chars_format __rhs) noexcept
667  { return __lhs = __lhs ^ __rhs; }
668 
669 _GLIBCXX_END_NAMESPACE_VERSION
670 } // namespace std
671 #endif // C++14
672 #endif // _GLIBCXX_CHARCONV
std::chars_format
chars_format
floating-point format for primitive numerical conversion
Definition: charconv:636
std::hex
ios_base & hex(ios_base &__base)
Calls base.setf(ios_base::hex, ios_base::basefield).
Definition: ios_base.h:1031
std::is_integral
is_integral
Definition: type_traits:365
std::scientific
ios_base & scientific(ios_base &__base)
Calls base.setf(ios_base::scientific, ios_base::floatfield).
Definition: ios_base.h:1056
__gnu_debug::__base
constexpr _Iterator __base(_Iterator __it)
Definition: helper_functions.h:299
std::fixed
ios_base & fixed(ios_base &__base)
Calls base.setf(ios_base::fixed, ios_base::floatfield).
Definition: ios_base.h:1048
std::from_chars_result
Result type of std::from_chars.
Definition: charconv:57
std::__detail::__from_chars_digit
bool __from_chars_digit(const char *&__first, const char *__last, _Tp &__val, int __base)
std::from_chars implementation for integers in bases 3 to 10.
Definition: charconv:419
std::operator&
bitset< _Nb > operator&(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition: bitset:1433
std
ISO C++ entities toplevel namespace is std.
cctype
std::isdigit
bool isdigit(_CharT __c, const locale &__loc)
Convenience interface to ctype.is(ctype_base::digit, __c).
Definition: locale_facets.h:2605
limits
std::numeric_limits::max
static constexpr _Tp max() noexcept
Definition: limits:321
std::from_chars
__detail::__integer_from_chars_result_type< _Tp > from_chars(const char *__first, const char *__last, _Tp &__value, int __base=10)
std::from_chars for integral types.
Definition: charconv:573
error_constants.h
type_traits
std::__detail::__from_chars_binary
bool __from_chars_binary(const char *&__first, const char *__last, _Tp &__val)
std::from_chars implementation for integers in base 2.
Definition: charconv:396
charconv.h
std::to_chars_result
Result type of std::to_chars.
Definition: charconv:50
std::__detail::__from_chars_alnum
bool __from_chars_alnum(const char *&__first, const char *__last, _Tp &__val, int __base)
std::from_chars implementation for integers in bases 11 to 26.
Definition: charconv:538
std::numeric_limits
Properties of fundamental types.
Definition: limits:312
std::is_same
is_same
Definition: type_traits:582
std::enable_if_t
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
Definition: type_traits:2553
std::__numeric_limits_base::digits
static constexpr int digits
Definition: limits:211
bit