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