1337143Sdim// -*- C++ -*-
2337143Sdim//===------------------------------ charconv ------------------------------===//
3337143Sdim//
4353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5353358Sdim// See https://llvm.org/LICENSE.txt for license information.
6353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7337143Sdim//
8337143Sdim//===----------------------------------------------------------------------===//
9337143Sdim
10337143Sdim#ifndef _LIBCPP_CHARCONV
11337143Sdim#define _LIBCPP_CHARCONV
12337143Sdim
13337143Sdim/*
14337143Sdim    charconv synopsis
15337143Sdim
16337143Sdimnamespace std {
17337143Sdim
18337143Sdim  // floating-point format for primitive numerical conversion
19337143Sdim  enum class chars_format {
20337143Sdim    scientific = unspecified,
21337143Sdim    fixed = unspecified,
22337143Sdim    hex = unspecified,
23337143Sdim    general = fixed | scientific
24337143Sdim  };
25337143Sdim
26337143Sdim  // 23.20.2, primitive numerical output conversion
27337143Sdim  struct to_chars_result {
28337143Sdim    char* ptr;
29337143Sdim    errc ec;
30337143Sdim  };
31337143Sdim
32337143Sdim  to_chars_result to_chars(char* first, char* last, see below value,
33337143Sdim                           int base = 10);
34337143Sdim
35337143Sdim  to_chars_result to_chars(char* first, char* last, float value);
36337143Sdim  to_chars_result to_chars(char* first, char* last, double value);
37337143Sdim  to_chars_result to_chars(char* first, char* last, long double value);
38337143Sdim
39337143Sdim  to_chars_result to_chars(char* first, char* last, float value,
40337143Sdim                           chars_format fmt);
41337143Sdim  to_chars_result to_chars(char* first, char* last, double value,
42337143Sdim                           chars_format fmt);
43337143Sdim  to_chars_result to_chars(char* first, char* last, long double value,
44337143Sdim                           chars_format fmt);
45337143Sdim
46337143Sdim  to_chars_result to_chars(char* first, char* last, float value,
47337143Sdim                           chars_format fmt, int precision);
48337143Sdim  to_chars_result to_chars(char* first, char* last, double value,
49337143Sdim                           chars_format fmt, int precision);
50337143Sdim  to_chars_result to_chars(char* first, char* last, long double value,
51337143Sdim                           chars_format fmt, int precision);
52337143Sdim
53337143Sdim  // 23.20.3, primitive numerical input conversion
54337143Sdim  struct from_chars_result {
55337143Sdim    const char* ptr;
56337143Sdim    errc ec;
57337143Sdim  };
58337143Sdim
59337143Sdim  from_chars_result from_chars(const char* first, const char* last,
60337143Sdim                               see below& value, int base = 10);
61337143Sdim
62337143Sdim  from_chars_result from_chars(const char* first, const char* last,
63337143Sdim                               float& value,
64337143Sdim                               chars_format fmt = chars_format::general);
65337143Sdim  from_chars_result from_chars(const char* first, const char* last,
66337143Sdim                               double& value,
67337143Sdim                               chars_format fmt = chars_format::general);
68337143Sdim  from_chars_result from_chars(const char* first, const char* last,
69337143Sdim                               long double& value,
70337143Sdim                               chars_format fmt = chars_format::general);
71337143Sdim
72337143Sdim} // namespace std
73337143Sdim
74337143Sdim*/
75337143Sdim
76337143Sdim#include <__errc>
77337143Sdim#include <type_traits>
78337143Sdim#include <limits>
79337143Sdim#include <stdint.h>
80337143Sdim#include <string.h>
81337143Sdim#include <math.h>
82337143Sdim
83337143Sdim#include <__debug>
84337143Sdim
85337143Sdim#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
86337143Sdim#pragma GCC system_header
87337143Sdim#endif
88337143Sdim
89344779Sdim_LIBCPP_PUSH_MACROS
90344779Sdim#include <__undef_macros>
91344779Sdim
92337143Sdim_LIBCPP_BEGIN_NAMESPACE_STD
93337143Sdim
94344779Sdimnamespace __itoa {
95344779Sdim_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer);
96344779Sdim_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer);
97344779Sdim}
98344779Sdim
99353358Sdim#ifndef _LIBCPP_CXX03_LANG
100337143Sdim
101337143Sdimenum class _LIBCPP_ENUM_VIS chars_format
102337143Sdim{
103337143Sdim    scientific = 0x1,
104337143Sdim    fixed = 0x2,
105337143Sdim    hex = 0x4,
106337143Sdim    general = fixed | scientific
107337143Sdim};
108337143Sdim
109337143Sdimstruct _LIBCPP_TYPE_VIS to_chars_result
110337143Sdim{
111337143Sdim    char* ptr;
112337143Sdim    errc ec;
113337143Sdim};
114337143Sdim
115337143Sdimstruct _LIBCPP_TYPE_VIS from_chars_result
116337143Sdim{
117337143Sdim    const char* ptr;
118337143Sdim    errc ec;
119337143Sdim};
120337143Sdim
121337143Sdimvoid to_chars(char*, char*, bool, int = 10) = delete;
122337143Sdimvoid from_chars(const char*, const char*, bool, int = 10) = delete;
123337143Sdim
124337143Sdimnamespace __itoa
125337143Sdim{
126337143Sdim
127353358Sdimstatic _LIBCPP_CONSTEXPR uint64_t __pow10_64[] = {
128337143Sdim    UINT64_C(0),
129337143Sdim    UINT64_C(10),
130337143Sdim    UINT64_C(100),
131337143Sdim    UINT64_C(1000),
132337143Sdim    UINT64_C(10000),
133337143Sdim    UINT64_C(100000),
134337143Sdim    UINT64_C(1000000),
135337143Sdim    UINT64_C(10000000),
136337143Sdim    UINT64_C(100000000),
137337143Sdim    UINT64_C(1000000000),
138337143Sdim    UINT64_C(10000000000),
139337143Sdim    UINT64_C(100000000000),
140337143Sdim    UINT64_C(1000000000000),
141337143Sdim    UINT64_C(10000000000000),
142337143Sdim    UINT64_C(100000000000000),
143337143Sdim    UINT64_C(1000000000000000),
144337143Sdim    UINT64_C(10000000000000000),
145337143Sdim    UINT64_C(100000000000000000),
146337143Sdim    UINT64_C(1000000000000000000),
147337143Sdim    UINT64_C(10000000000000000000),
148337143Sdim};
149337143Sdim
150353358Sdimstatic _LIBCPP_CONSTEXPR uint32_t __pow10_32[] = {
151337143Sdim    UINT32_C(0),          UINT32_C(10),       UINT32_C(100),
152337143Sdim    UINT32_C(1000),       UINT32_C(10000),    UINT32_C(100000),
153337143Sdim    UINT32_C(1000000),    UINT32_C(10000000), UINT32_C(100000000),
154337143Sdim    UINT32_C(1000000000),
155337143Sdim};
156337143Sdim
157337143Sdimtemplate <typename _Tp, typename = void>
158337143Sdimstruct _LIBCPP_HIDDEN __traits_base
159337143Sdim{
160337143Sdim    using type = uint64_t;
161337143Sdim
162337143Sdim#if !defined(_LIBCPP_COMPILER_MSVC)
163337143Sdim    static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v)
164337143Sdim    {
165337143Sdim        auto __t = (64 - __builtin_clzll(__v | 1)) * 1233 >> 12;
166337143Sdim        return __t - (__v < __pow10_64[__t]) + 1;
167337143Sdim    }
168337143Sdim#endif
169337143Sdim
170337143Sdim    static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p)
171337143Sdim    {
172337143Sdim        return __u64toa(__v, __p);
173337143Sdim    }
174337143Sdim
175353358Sdim    static _LIBCPP_INLINE_VISIBILITY decltype(__pow10_64)& __pow() { return __pow10_64; }
176337143Sdim};
177337143Sdim
178337143Sdimtemplate <typename _Tp>
179337143Sdimstruct _LIBCPP_HIDDEN
180337143Sdim    __traits_base<_Tp, decltype(void(uint32_t{declval<_Tp>()}))>
181337143Sdim{
182337143Sdim    using type = uint32_t;
183337143Sdim
184337143Sdim#if !defined(_LIBCPP_COMPILER_MSVC)
185337143Sdim    static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v)
186337143Sdim    {
187337143Sdim        auto __t = (32 - __builtin_clz(__v | 1)) * 1233 >> 12;
188337143Sdim        return __t - (__v < __pow10_32[__t]) + 1;
189337143Sdim    }
190337143Sdim#endif
191337143Sdim
192337143Sdim    static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p)
193337143Sdim    {
194337143Sdim        return __u32toa(__v, __p);
195337143Sdim    }
196337143Sdim
197353358Sdim    static _LIBCPP_INLINE_VISIBILITY decltype(__pow10_32)& __pow() { return __pow10_32; }
198337143Sdim};
199337143Sdim
200337143Sdimtemplate <typename _Tp>
201337143Sdiminline _LIBCPP_INLINE_VISIBILITY bool
202337143Sdim__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r)
203337143Sdim{
204337143Sdim    auto __c = __a * __b;
205337143Sdim    __r = __c;
206337143Sdim    return __c > (numeric_limits<unsigned char>::max)();
207337143Sdim}
208337143Sdim
209337143Sdimtemplate <typename _Tp>
210337143Sdiminline _LIBCPP_INLINE_VISIBILITY bool
211337143Sdim__mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r)
212337143Sdim{
213337143Sdim    auto __c = __a * __b;
214337143Sdim    __r = __c;
215337143Sdim    return __c > (numeric_limits<unsigned short>::max)();
216337143Sdim}
217337143Sdim
218337143Sdimtemplate <typename _Tp>
219337143Sdiminline _LIBCPP_INLINE_VISIBILITY bool
220337143Sdim__mul_overflowed(_Tp __a, _Tp __b, _Tp& __r)
221337143Sdim{
222337143Sdim    static_assert(is_unsigned<_Tp>::value, "");
223337143Sdim#if !defined(_LIBCPP_COMPILER_MSVC)
224337143Sdim    return __builtin_mul_overflow(__a, __b, &__r);
225337143Sdim#else
226337143Sdim    bool __did = __b && ((numeric_limits<_Tp>::max)() / __b) < __a;
227337143Sdim    __r = __a * __b;
228337143Sdim    return __did;
229337143Sdim#endif
230337143Sdim}
231337143Sdim
232337143Sdimtemplate <typename _Tp, typename _Up>
233337143Sdiminline _LIBCPP_INLINE_VISIBILITY bool
234337143Sdim__mul_overflowed(_Tp __a, _Up __b, _Tp& __r)
235337143Sdim{
236337143Sdim    return __mul_overflowed(__a, static_cast<_Tp>(__b), __r);
237337143Sdim}
238337143Sdim
239337143Sdimtemplate <typename _Tp>
240337143Sdimstruct _LIBCPP_HIDDEN __traits : __traits_base<_Tp>
241337143Sdim{
242353358Sdim    static _LIBCPP_CONSTEXPR int digits = numeric_limits<_Tp>::digits10 + 1;
243337143Sdim    using __traits_base<_Tp>::__pow;
244337143Sdim    using typename __traits_base<_Tp>::type;
245337143Sdim
246337143Sdim    // precondition: at least one non-zero character available
247337143Sdim    static _LIBCPP_INLINE_VISIBILITY char const*
248337143Sdim    __read(char const* __p, char const* __ep, type& __a, type& __b)
249337143Sdim    {
250337143Sdim        type __cprod[digits];
251337143Sdim        int __j = digits - 1;
252337143Sdim        int __i = digits;
253337143Sdim        do
254337143Sdim        {
255337143Sdim            if (!('0' <= *__p && *__p <= '9'))
256337143Sdim                break;
257337143Sdim            __cprod[--__i] = *__p++ - '0';
258337143Sdim        } while (__p != __ep && __i != 0);
259337143Sdim
260337143Sdim        __a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1,
261337143Sdim                              __cprod[__i]);
262337143Sdim        if (__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b))
263337143Sdim            --__p;
264337143Sdim        return __p;
265337143Sdim    }
266337143Sdim
267337143Sdim    template <typename _It1, typename _It2, class _Up>
268337143Sdim    static _LIBCPP_INLINE_VISIBILITY _Up
269337143Sdim    __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init)
270337143Sdim    {
271337143Sdim        for (; __first1 < __last1; ++__first1, ++__first2)
272337143Sdim            __init = __init + *__first1 * *__first2;
273337143Sdim        return __init;
274337143Sdim    }
275337143Sdim};
276337143Sdim
277337143Sdim}  // namespace __itoa
278337143Sdim
279337143Sdimtemplate <typename _Tp>
280337143Sdiminline _LIBCPP_INLINE_VISIBILITY _Tp
281337143Sdim__complement(_Tp __x)
282337143Sdim{
283337143Sdim    static_assert(is_unsigned<_Tp>::value, "cast to unsigned first");
284337143Sdim    return _Tp(~__x + 1);
285337143Sdim}
286337143Sdim
287337143Sdimtemplate <typename _Tp>
288353358Sdiminline _LIBCPP_INLINE_VISIBILITY typename make_unsigned<_Tp>::type
289337143Sdim__to_unsigned(_Tp __x)
290337143Sdim{
291353358Sdim    return static_cast<typename make_unsigned<_Tp>::type>(__x);
292337143Sdim}
293337143Sdim
294337143Sdimtemplate <typename _Tp>
295337143Sdiminline _LIBCPP_INLINE_VISIBILITY to_chars_result
296337143Sdim__to_chars_itoa(char* __first, char* __last, _Tp __value, true_type)
297337143Sdim{
298337143Sdim    auto __x = __to_unsigned(__value);
299337143Sdim    if (__value < 0 && __first != __last)
300337143Sdim    {
301337143Sdim        *__first++ = '-';
302337143Sdim        __x = __complement(__x);
303337143Sdim    }
304337143Sdim
305337143Sdim    return __to_chars_itoa(__first, __last, __x, false_type());
306337143Sdim}
307337143Sdim
308337143Sdimtemplate <typename _Tp>
309337143Sdiminline _LIBCPP_INLINE_VISIBILITY to_chars_result
310337143Sdim__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type)
311337143Sdim{
312337143Sdim    using __tx = __itoa::__traits<_Tp>;
313337143Sdim    auto __diff = __last - __first;
314337143Sdim
315337143Sdim#if !defined(_LIBCPP_COMPILER_MSVC)
316337143Sdim    if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
317353358Sdim        return {__tx::__convert(__value, __first), errc(0)};
318337143Sdim    else
319337143Sdim        return {__last, errc::value_too_large};
320337143Sdim#else
321337143Sdim    if (__tx::digits <= __diff)
322337143Sdim        return {__tx::__convert(__value, __first), {}};
323337143Sdim    else
324337143Sdim    {
325337143Sdim        char __buf[__tx::digits];
326337143Sdim        auto __p = __tx::__convert(__value, __buf);
327337143Sdim        auto __len = __p - __buf;
328337143Sdim        if (__len <= __diff)
329337143Sdim        {
330337143Sdim            memcpy(__first, __buf, __len);
331337143Sdim            return {__first + __len, {}};
332337143Sdim        }
333337143Sdim        else
334337143Sdim            return {__last, errc::value_too_large};
335337143Sdim    }
336337143Sdim#endif
337337143Sdim}
338337143Sdim
339337143Sdimtemplate <typename _Tp>
340337143Sdiminline _LIBCPP_INLINE_VISIBILITY to_chars_result
341337143Sdim__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
342337143Sdim                    true_type)
343337143Sdim{
344337143Sdim    auto __x = __to_unsigned(__value);
345337143Sdim    if (__value < 0 && __first != __last)
346337143Sdim    {
347337143Sdim        *__first++ = '-';
348337143Sdim        __x = __complement(__x);
349337143Sdim    }
350337143Sdim
351337143Sdim    return __to_chars_integral(__first, __last, __x, __base, false_type());
352337143Sdim}
353337143Sdim
354337143Sdimtemplate <typename _Tp>
355337143Sdiminline _LIBCPP_INLINE_VISIBILITY to_chars_result
356337143Sdim__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
357337143Sdim                    false_type)
358337143Sdim{
359337143Sdim    if (__base == 10)
360337143Sdim        return __to_chars_itoa(__first, __last, __value, false_type());
361337143Sdim
362337143Sdim    auto __p = __last;
363337143Sdim    while (__p != __first)
364337143Sdim    {
365337143Sdim        auto __c = __value % __base;
366337143Sdim        __value /= __base;
367337143Sdim        *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c];
368337143Sdim        if (__value == 0)
369337143Sdim            break;
370337143Sdim    }
371337143Sdim
372337143Sdim    auto __len = __last - __p;
373337143Sdim    if (__value != 0 || !__len)
374337143Sdim        return {__last, errc::value_too_large};
375337143Sdim    else
376337143Sdim    {
377337143Sdim        memmove(__first, __p, __len);
378337143Sdim        return {__first + __len, {}};
379337143Sdim    }
380337143Sdim}
381337143Sdim
382353358Sdimtemplate <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
383337143Sdiminline _LIBCPP_INLINE_VISIBILITY to_chars_result
384337143Sdimto_chars(char* __first, char* __last, _Tp __value)
385337143Sdim{
386337143Sdim    return __to_chars_itoa(__first, __last, __value, is_signed<_Tp>());
387337143Sdim}
388337143Sdim
389353358Sdimtemplate <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
390337143Sdiminline _LIBCPP_INLINE_VISIBILITY to_chars_result
391337143Sdimto_chars(char* __first, char* __last, _Tp __value, int __base)
392337143Sdim{
393337143Sdim    _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
394337143Sdim    return __to_chars_integral(__first, __last, __value, __base,
395337143Sdim                               is_signed<_Tp>());
396337143Sdim}
397337143Sdim
398337143Sdimtemplate <typename _It, typename _Tp, typename _Fn, typename... _Ts>
399337143Sdiminline _LIBCPP_INLINE_VISIBILITY from_chars_result
400337143Sdim__sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args)
401337143Sdim{
402337143Sdim    using __tl = numeric_limits<_Tp>;
403337143Sdim    decltype(__to_unsigned(__value)) __x;
404337143Sdim
405337143Sdim    bool __neg = (__first != __last && *__first == '-');
406337143Sdim    auto __r = __f(__neg ? __first + 1 : __first, __last, __x, __args...);
407337143Sdim    switch (__r.ec)
408337143Sdim    {
409337143Sdim    case errc::invalid_argument:
410337143Sdim        return {__first, __r.ec};
411337143Sdim    case errc::result_out_of_range:
412337143Sdim        return __r;
413337143Sdim    default:
414337143Sdim        break;
415337143Sdim    }
416337143Sdim
417337143Sdim    if (__neg)
418337143Sdim    {
419337143Sdim        if (__x <= __complement(__to_unsigned(__tl::min())))
420337143Sdim        {
421337143Sdim            __x = __complement(__x);
422337143Sdim            memcpy(&__value, &__x, sizeof(__x));
423337143Sdim            return __r;
424337143Sdim        }
425337143Sdim    }
426337143Sdim    else
427337143Sdim    {
428337143Sdim        if (__x <= (__tl::max)())
429337143Sdim        {
430337143Sdim            __value = __x;
431337143Sdim            return __r;
432337143Sdim        }
433337143Sdim    }
434337143Sdim
435337143Sdim    return {__r.ptr, errc::result_out_of_range};
436337143Sdim}
437337143Sdim
438337143Sdimtemplate <typename _Tp>
439337143Sdiminline _LIBCPP_INLINE_VISIBILITY bool
440337143Sdim__in_pattern(_Tp __c)
441337143Sdim{
442337143Sdim    return '0' <= __c && __c <= '9';
443337143Sdim}
444337143Sdim
445337143Sdimstruct _LIBCPP_HIDDEN __in_pattern_result
446337143Sdim{
447337143Sdim    bool __ok;
448337143Sdim    int __val;
449337143Sdim
450337143Sdim    explicit _LIBCPP_INLINE_VISIBILITY operator bool() const { return __ok; }
451337143Sdim};
452337143Sdim
453337143Sdimtemplate <typename _Tp>
454337143Sdiminline _LIBCPP_INLINE_VISIBILITY __in_pattern_result
455337143Sdim__in_pattern(_Tp __c, int __base)
456337143Sdim{
457337143Sdim    if (__base <= 10)
458337143Sdim        return {'0' <= __c && __c < '0' + __base, __c - '0'};
459337143Sdim    else if (__in_pattern(__c))
460337143Sdim        return {true, __c - '0'};
461337143Sdim    else if ('a' <= __c && __c < 'a' + __base - 10)
462337143Sdim        return {true, __c - 'a' + 10};
463337143Sdim    else
464337143Sdim        return {'A' <= __c && __c < 'A' + __base - 10, __c - 'A' + 10};
465337143Sdim}
466337143Sdim
467337143Sdimtemplate <typename _It, typename _Tp, typename _Fn, typename... _Ts>
468337143Sdiminline _LIBCPP_INLINE_VISIBILITY from_chars_result
469337143Sdim__subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f,
470337143Sdim                         _Ts... __args)
471337143Sdim{
472337143Sdim    auto __find_non_zero = [](_It __first, _It __last) {
473337143Sdim        for (; __first != __last; ++__first)
474337143Sdim            if (*__first != '0')
475337143Sdim                break;
476337143Sdim        return __first;
477337143Sdim    };
478337143Sdim
479337143Sdim    auto __p = __find_non_zero(__first, __last);
480337143Sdim    if (__p == __last || !__in_pattern(*__p, __args...))
481337143Sdim    {
482337143Sdim        if (__p == __first)
483337143Sdim            return {__first, errc::invalid_argument};
484337143Sdim        else
485337143Sdim        {
486337143Sdim            __value = 0;
487337143Sdim            return {__p, {}};
488337143Sdim        }
489337143Sdim    }
490337143Sdim
491337143Sdim    auto __r = __f(__p, __last, __value, __args...);
492337143Sdim    if (__r.ec == errc::result_out_of_range)
493337143Sdim    {
494337143Sdim        for (; __r.ptr != __last; ++__r.ptr)
495337143Sdim        {
496337143Sdim            if (!__in_pattern(*__r.ptr, __args...))
497337143Sdim                break;
498337143Sdim        }
499337143Sdim    }
500337143Sdim
501337143Sdim    return __r;
502337143Sdim}
503337143Sdim
504353358Sdimtemplate <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0>
505337143Sdiminline _LIBCPP_INLINE_VISIBILITY from_chars_result
506337143Sdim__from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
507337143Sdim{
508337143Sdim    using __tx = __itoa::__traits<_Tp>;
509337143Sdim    using __output_type = typename __tx::type;
510337143Sdim
511337143Sdim    return __subject_seq_combinator(
512337143Sdim        __first, __last, __value,
513337143Sdim        [](const char* __first, const char* __last,
514337143Sdim           _Tp& __value) -> from_chars_result {
515337143Sdim            __output_type __a, __b;
516337143Sdim            auto __p = __tx::__read(__first, __last, __a, __b);
517337143Sdim            if (__p == __last || !__in_pattern(*__p))
518337143Sdim            {
519337143Sdim                __output_type __m = (numeric_limits<_Tp>::max)();
520337143Sdim                if (__m >= __a && __m - __a >= __b)
521337143Sdim                {
522337143Sdim                    __value = __a + __b;
523337143Sdim                    return {__p, {}};
524337143Sdim                }
525337143Sdim            }
526337143Sdim            return {__p, errc::result_out_of_range};
527337143Sdim        });
528337143Sdim}
529337143Sdim
530353358Sdimtemplate <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0>
531337143Sdiminline _LIBCPP_INLINE_VISIBILITY from_chars_result
532337143Sdim__from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
533337143Sdim{
534337143Sdim    using __t = decltype(__to_unsigned(__value));
535337143Sdim    return __sign_combinator(__first, __last, __value, __from_chars_atoi<__t>);
536337143Sdim}
537337143Sdim
538353358Sdimtemplate <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0>
539337143Sdiminline _LIBCPP_INLINE_VISIBILITY from_chars_result
540337143Sdim__from_chars_integral(const char* __first, const char* __last, _Tp& __value,
541337143Sdim                      int __base)
542337143Sdim{
543337143Sdim    if (__base == 10)
544337143Sdim        return __from_chars_atoi(__first, __last, __value);
545337143Sdim
546337143Sdim    return __subject_seq_combinator(
547337143Sdim        __first, __last, __value,
548337143Sdim        [](const char* __p, const char* __last, _Tp& __value,
549337143Sdim           int __base) -> from_chars_result {
550337143Sdim            using __tl = numeric_limits<_Tp>;
551337143Sdim            auto __digits = __tl::digits / log2f(float(__base));
552337143Sdim            _Tp __a = __in_pattern(*__p++, __base).__val, __b = 0;
553337143Sdim
554337143Sdim            for (int __i = 1; __p != __last; ++__i, ++__p)
555337143Sdim            {
556337143Sdim                if (auto __c = __in_pattern(*__p, __base))
557337143Sdim                {
558337143Sdim                    if (__i < __digits - 1)
559337143Sdim                        __a = __a * __base + __c.__val;
560337143Sdim                    else
561337143Sdim                    {
562337143Sdim                        if (!__itoa::__mul_overflowed(__a, __base, __a))
563337143Sdim                            ++__p;
564337143Sdim                        __b = __c.__val;
565337143Sdim                        break;
566337143Sdim                    }
567337143Sdim                }
568337143Sdim                else
569337143Sdim                    break;
570337143Sdim            }
571337143Sdim
572337143Sdim            if (__p == __last || !__in_pattern(*__p, __base))
573337143Sdim            {
574337143Sdim                if ((__tl::max)() - __a >= __b)
575337143Sdim                {
576337143Sdim                    __value = __a + __b;
577337143Sdim                    return {__p, {}};
578337143Sdim                }
579337143Sdim            }
580337143Sdim            return {__p, errc::result_out_of_range};
581337143Sdim        },
582337143Sdim        __base);
583337143Sdim}
584337143Sdim
585353358Sdimtemplate <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0>
586337143Sdiminline _LIBCPP_INLINE_VISIBILITY from_chars_result
587337143Sdim__from_chars_integral(const char* __first, const char* __last, _Tp& __value,
588337143Sdim                      int __base)
589337143Sdim{
590337143Sdim    using __t = decltype(__to_unsigned(__value));
591337143Sdim    return __sign_combinator(__first, __last, __value,
592337143Sdim                             __from_chars_integral<__t>, __base);
593337143Sdim}
594337143Sdim
595353358Sdimtemplate <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
596337143Sdiminline _LIBCPP_INLINE_VISIBILITY from_chars_result
597337143Sdimfrom_chars(const char* __first, const char* __last, _Tp& __value)
598337143Sdim{
599337143Sdim    return __from_chars_atoi(__first, __last, __value);
600337143Sdim}
601337143Sdim
602353358Sdimtemplate <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
603337143Sdiminline _LIBCPP_INLINE_VISIBILITY from_chars_result
604337143Sdimfrom_chars(const char* __first, const char* __last, _Tp& __value, int __base)
605337143Sdim{
606337143Sdim    _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
607337143Sdim    return __from_chars_integral(__first, __last, __value, __base);
608337143Sdim}
609337143Sdim
610353358Sdim#endif  // _LIBCPP_CXX03_LANG
611337143Sdim
612337143Sdim_LIBCPP_END_NAMESPACE_STD
613337143Sdim
614344779Sdim_LIBCPP_POP_MACROS
615344779Sdim
616337143Sdim#endif  // _LIBCPP_CHARCONV
617