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