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