xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/std/charconv (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
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
49namespace 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
77namespace __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
396namespace __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
692