Home | History | Annotate | Download | only in include
      1 // -*- C++ -*-
      2 //===------------------------------ charconv ------------------------------===//
      3 //
      4 //                     The LLVM Compiler Infrastructure
      5 //
      6 // This file is dual licensed under the MIT and the University of Illinois Open
      7 // Source Licenses. See LICENSE.TXT for details.
      8 //
      9 //===----------------------------------------------------------------------===//
     10 
     11 #ifndef _LIBCPP_CHARCONV
     12 #define _LIBCPP_CHARCONV
     13 
     14 /*
     15     charconv synopsis
     16 
     17 namespace std {
     18 
     19   // floating-point format for primitive numerical conversion
     20   enum class chars_format {
     21     scientific = unspecified,
     22     fixed = unspecified,
     23     hex = unspecified,
     24     general = fixed | scientific
     25   };
     26 
     27   // 23.20.2, primitive numerical output conversion
     28   struct to_chars_result {
     29     char* ptr;
     30     errc ec;
     31   };
     32 
     33   to_chars_result to_chars(char* first, char* last, see below value,
     34                            int base = 10);
     35 
     36   to_chars_result to_chars(char* first, char* last, float value);
     37   to_chars_result to_chars(char* first, char* last, double value);
     38   to_chars_result to_chars(char* first, char* last, long double value);
     39 
     40   to_chars_result to_chars(char* first, char* last, float value,
     41                            chars_format fmt);
     42   to_chars_result to_chars(char* first, char* last, double value,
     43                            chars_format fmt);
     44   to_chars_result to_chars(char* first, char* last, long double value,
     45                            chars_format fmt);
     46 
     47   to_chars_result to_chars(char* first, char* last, float value,
     48                            chars_format fmt, int precision);
     49   to_chars_result to_chars(char* first, char* last, double value,
     50                            chars_format fmt, int precision);
     51   to_chars_result to_chars(char* first, char* last, long double value,
     52                            chars_format fmt, int precision);
     53 
     54   // 23.20.3, primitive numerical input conversion
     55   struct from_chars_result {
     56     const char* ptr;
     57     errc ec;
     58   };
     59 
     60   from_chars_result from_chars(const char* first, const char* last,
     61                                see below& value, int base = 10);
     62 
     63   from_chars_result from_chars(const char* first, const char* last,
     64                                float& value,
     65                                chars_format fmt = chars_format::general);
     66   from_chars_result from_chars(const char* first, const char* last,
     67                                double& value,
     68                                chars_format fmt = chars_format::general);
     69   from_chars_result from_chars(const char* first, const char* last,
     70                                long double& value,
     71                                chars_format fmt = chars_format::general);
     72 
     73 } // namespace std
     74 
     75 */
     76 
     77 #include <__errc>
     78 #include <type_traits>
     79 #include <limits>
     80 #include <stdint.h>
     81 #include <string.h>
     82 #include <math.h>
     83 
     84 #include <__debug>
     85 
     86 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
     87 #pragma GCC system_header
     88 #endif
     89 
     90 _LIBCPP_PUSH_MACROS
     91 #include <__undef_macros>
     92 
     93 _LIBCPP_BEGIN_NAMESPACE_STD
     94 
     95 namespace __itoa {
     96 _LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer);
     97 _LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer);
     98 }
     99 
    100 #if _LIBCPP_STD_VER > 11
    101 
    102 enum class _LIBCPP_ENUM_VIS chars_format
    103 {
    104     scientific = 0x1,
    105     fixed = 0x2,
    106     hex = 0x4,
    107     general = fixed | scientific
    108 };
    109 
    110 struct _LIBCPP_TYPE_VIS to_chars_result
    111 {
    112     char* ptr;
    113     errc ec;
    114 };
    115 
    116 struct _LIBCPP_TYPE_VIS from_chars_result
    117 {
    118     const char* ptr;
    119     errc ec;
    120 };
    121 
    122 void to_chars(char*, char*, bool, int = 10) = delete;
    123 void from_chars(const char*, const char*, bool, int = 10) = delete;
    124 
    125 namespace __itoa
    126 {
    127 
    128 static constexpr uint64_t __pow10_64[] = {
    129     UINT64_C(0),
    130     UINT64_C(10),
    131     UINT64_C(100),
    132     UINT64_C(1000),
    133     UINT64_C(10000),
    134     UINT64_C(100000),
    135     UINT64_C(1000000),
    136     UINT64_C(10000000),
    137     UINT64_C(100000000),
    138     UINT64_C(1000000000),
    139     UINT64_C(10000000000),
    140     UINT64_C(100000000000),
    141     UINT64_C(1000000000000),
    142     UINT64_C(10000000000000),
    143     UINT64_C(100000000000000),
    144     UINT64_C(1000000000000000),
    145     UINT64_C(10000000000000000),
    146     UINT64_C(100000000000000000),
    147     UINT64_C(1000000000000000000),
    148     UINT64_C(10000000000000000000),
    149 };
    150 
    151 static constexpr uint32_t __pow10_32[] = {
    152     UINT32_C(0),          UINT32_C(10),       UINT32_C(100),
    153     UINT32_C(1000),       UINT32_C(10000),    UINT32_C(100000),
    154     UINT32_C(1000000),    UINT32_C(10000000), UINT32_C(100000000),
    155     UINT32_C(1000000000),
    156 };
    157 
    158 template <typename _Tp, typename = void>
    159 struct _LIBCPP_HIDDEN __traits_base
    160 {
    161     using type = uint64_t;
    162 
    163 #if !defined(_LIBCPP_COMPILER_MSVC)
    164     static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v)
    165     {
    166         auto __t = (64 - __builtin_clzll(__v | 1)) * 1233 >> 12;
    167         return __t - (__v < __pow10_64[__t]) + 1;
    168     }
    169 #endif
    170 
    171     static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p)
    172     {
    173         return __u64toa(__v, __p);
    174     }
    175 
    176     static _LIBCPP_INLINE_VISIBILITY auto& __pow() { return __pow10_64; }
    177 };
    178 
    179 template <typename _Tp>
    180 struct _LIBCPP_HIDDEN
    181     __traits_base<_Tp, decltype(void(uint32_t{declval<_Tp>()}))>
    182 {
    183     using type = uint32_t;
    184 
    185 #if !defined(_LIBCPP_COMPILER_MSVC)
    186     static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v)
    187     {
    188         auto __t = (32 - __builtin_clz(__v | 1)) * 1233 >> 12;
    189         return __t - (__v < __pow10_32[__t]) + 1;
    190     }
    191 #endif
    192 
    193     static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p)
    194     {
    195         return __u32toa(__v, __p);
    196     }
    197 
    198     static _LIBCPP_INLINE_VISIBILITY auto& __pow() { return __pow10_32; }
    199 };
    200 
    201 template <typename _Tp>
    202 inline _LIBCPP_INLINE_VISIBILITY bool
    203 __mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r)
    204 {
    205     auto __c = __a * __b;
    206     __r = __c;
    207     return __c > (numeric_limits<unsigned char>::max)();
    208 }
    209 
    210 template <typename _Tp>
    211 inline _LIBCPP_INLINE_VISIBILITY bool
    212 __mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r)
    213 {
    214     auto __c = __a * __b;
    215     __r = __c;
    216     return __c > (numeric_limits<unsigned short>::max)();
    217 }
    218 
    219 template <typename _Tp>
    220 inline _LIBCPP_INLINE_VISIBILITY bool
    221 __mul_overflowed(_Tp __a, _Tp __b, _Tp& __r)
    222 {
    223     static_assert(is_unsigned<_Tp>::value, "");
    224 #if !defined(_LIBCPP_COMPILER_MSVC)
    225     return __builtin_mul_overflow(__a, __b, &__r);
    226 #else
    227     bool __did = __b && ((numeric_limits<_Tp>::max)() / __b) < __a;
    228     __r = __a * __b;
    229     return __did;
    230 #endif
    231 }
    232 
    233 template <typename _Tp, typename _Up>
    234 inline _LIBCPP_INLINE_VISIBILITY bool
    235 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r)
    236 {
    237     return __mul_overflowed(__a, static_cast<_Tp>(__b), __r);
    238 }
    239 
    240 template <typename _Tp>
    241 struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp>
    242 {
    243     static constexpr int digits = numeric_limits<_Tp>::digits10 + 1;
    244     using __traits_base<_Tp>::__pow;
    245     using typename __traits_base<_Tp>::type;
    246 
    247     // precondition: at least one non-zero character available
    248     static _LIBCPP_INLINE_VISIBILITY char const*
    249     __read(char const* __p, char const* __ep, type& __a, type& __b)
    250     {
    251         type __cprod[digits];
    252         int __j = digits - 1;
    253         int __i = digits;
    254         do
    255         {
    256             if (!('0' <= *__p && *__p <= '9'))
    257                 break;
    258             __cprod[--__i] = *__p++ - '0';
    259         } while (__p != __ep && __i != 0);
    260 
    261         __a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1,
    262                               __cprod[__i]);
    263         if (__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b))
    264             --__p;
    265         return __p;
    266     }
    267 
    268     template <typename _It1, typename _It2, class _Up>
    269     static _LIBCPP_INLINE_VISIBILITY _Up
    270     __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init)
    271     {
    272         for (; __first1 < __last1; ++__first1, ++__first2)
    273             __init = __init + *__first1 * *__first2;
    274         return __init;
    275     }
    276 };
    277 
    278 }  // namespace __itoa
    279 
    280 template <typename _Tp>
    281 inline _LIBCPP_INLINE_VISIBILITY _Tp
    282 __complement(_Tp __x)
    283 {
    284     static_assert(is_unsigned<_Tp>::value, "cast to unsigned first");
    285     return _Tp(~__x + 1);
    286 }
    287 
    288 template <typename _Tp>
    289 inline _LIBCPP_INLINE_VISIBILITY auto
    290 __to_unsigned(_Tp __x)
    291 {
    292     return static_cast<make_unsigned_t<_Tp>>(__x);
    293 }
    294 
    295 template <typename _Tp>
    296 inline _LIBCPP_INLINE_VISIBILITY to_chars_result
    297 __to_chars_itoa(char* __first, char* __last, _Tp __value, true_type)
    298 {
    299     auto __x = __to_unsigned(__value);
    300     if (__value < 0 && __first != __last)
    301     {
    302         *__first++ = '-';
    303         __x = __complement(__x);
    304     }
    305 
    306     return __to_chars_itoa(__first, __last, __x, false_type());
    307 }
    308 
    309 template <typename _Tp>
    310 inline _LIBCPP_INLINE_VISIBILITY to_chars_result
    311 __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type)
    312 {
    313     using __tx = __itoa::__traits<_Tp>;
    314     auto __diff = __last - __first;
    315 
    316 #if !defined(_LIBCPP_COMPILER_MSVC)
    317     if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
    318         return {__tx::__convert(__value, __first), {}};
    319     else
    320         return {__last, errc::value_too_large};
    321 #else
    322     if (__tx::digits <= __diff)
    323         return {__tx::__convert(__value, __first), {}};
    324     else
    325     {
    326         char __buf[__tx::digits];
    327         auto __p = __tx::__convert(__value, __buf);
    328         auto __len = __p - __buf;
    329         if (__len <= __diff)
    330         {
    331             memcpy(__first, __buf, __len);
    332             return {__first + __len, {}};
    333         }
    334         else
    335             return {__last, errc::value_too_large};
    336     }
    337 #endif
    338 }
    339 
    340 template <typename _Tp>
    341 inline _LIBCPP_INLINE_VISIBILITY to_chars_result
    342 __to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
    343                     true_type)
    344 {
    345     auto __x = __to_unsigned(__value);
    346     if (__value < 0 && __first != __last)
    347     {
    348         *__first++ = '-';
    349         __x = __complement(__x);
    350     }
    351 
    352     return __to_chars_integral(__first, __last, __x, __base, false_type());
    353 }
    354 
    355 template <typename _Tp>
    356 inline _LIBCPP_INLINE_VISIBILITY to_chars_result
    357 __to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
    358                     false_type)
    359 {
    360     if (__base == 10)
    361         return __to_chars_itoa(__first, __last, __value, false_type());
    362 
    363     auto __p = __last;
    364     while (__p != __first)
    365     {
    366         auto __c = __value % __base;
    367         __value /= __base;
    368         *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c];
    369         if (__value == 0)
    370             break;
    371     }
    372 
    373     auto __len = __last - __p;
    374     if (__value != 0 || !__len)
    375         return {__last, errc::value_too_large};
    376     else
    377     {
    378         memmove(__first, __p, __len);
    379         return {__first + __len, {}};
    380     }
    381 }
    382 
    383 template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0>
    384 inline _LIBCPP_INLINE_VISIBILITY to_chars_result
    385 to_chars(char* __first, char* __last, _Tp __value)
    386 {
    387     return __to_chars_itoa(__first, __last, __value, is_signed<_Tp>());
    388 }
    389 
    390 template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0>
    391 inline _LIBCPP_INLINE_VISIBILITY to_chars_result
    392 to_chars(char* __first, char* __last, _Tp __value, int __base)
    393 {
    394     _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
    395     return __to_chars_integral(__first, __last, __value, __base,
    396                                is_signed<_Tp>());
    397 }
    398 
    399 template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
    400 inline _LIBCPP_INLINE_VISIBILITY from_chars_result
    401 __sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args)
    402 {
    403     using __tl = numeric_limits<_Tp>;
    404     decltype(__to_unsigned(__value)) __x;
    405 
    406     bool __neg = (__first != __last && *__first == '-');
    407     auto __r = __f(__neg ? __first + 1 : __first, __last, __x, __args...);
    408     switch (__r.ec)
    409     {
    410     case errc::invalid_argument:
    411         return {__first, __r.ec};
    412     case errc::result_out_of_range:
    413         return __r;
    414     default:
    415         break;
    416     }
    417 
    418     if (__neg)
    419     {
    420         if (__x <= __complement(__to_unsigned(__tl::min())))
    421         {
    422             __x = __complement(__x);
    423             memcpy(&__value, &__x, sizeof(__x));
    424             return __r;
    425         }
    426     }
    427     else
    428     {
    429         if (__x <= (__tl::max)())
    430         {
    431             __value = __x;
    432             return __r;
    433         }
    434     }
    435 
    436     return {__r.ptr, errc::result_out_of_range};
    437 }
    438 
    439 template <typename _Tp>
    440 inline _LIBCPP_INLINE_VISIBILITY bool
    441 __in_pattern(_Tp __c)
    442 {
    443     return '0' <= __c && __c <= '9';
    444 }
    445 
    446 struct _LIBCPP_HIDDEN __in_pattern_result
    447 {
    448     bool __ok;
    449     int __val;
    450 
    451     explicit _LIBCPP_INLINE_VISIBILITY operator bool() const { return __ok; }
    452 };
    453 
    454 template <typename _Tp>
    455 inline _LIBCPP_INLINE_VISIBILITY __in_pattern_result
    456 __in_pattern(_Tp __c, int __base)
    457 {
    458     if (__base <= 10)
    459         return {'0' <= __c && __c < '0' + __base, __c - '0'};
    460     else if (__in_pattern(__c))
    461         return {true, __c - '0'};
    462     else if ('a' <= __c && __c < 'a' + __base - 10)
    463         return {true, __c - 'a' + 10};
    464     else
    465         return {'A' <= __c && __c < 'A' + __base - 10, __c - 'A' + 10};
    466 }
    467 
    468 template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
    469 inline _LIBCPP_INLINE_VISIBILITY from_chars_result
    470 __subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f,
    471                          _Ts... __args)
    472 {
    473     auto __find_non_zero = [](_It __first, _It __last) {
    474         for (; __first != __last; ++__first)
    475             if (*__first != '0')
    476                 break;
    477         return __first;
    478     };
    479 
    480     auto __p = __find_non_zero(__first, __last);
    481     if (__p == __last || !__in_pattern(*__p, __args...))
    482     {
    483         if (__p == __first)
    484             return {__first, errc::invalid_argument};
    485         else
    486         {
    487             __value = 0;
    488             return {__p, {}};
    489         }
    490     }
    491 
    492     auto __r = __f(__p, __last, __value, __args...);
    493     if (__r.ec == errc::result_out_of_range)
    494     {
    495         for (; __r.ptr != __last; ++__r.ptr)
    496         {
    497             if (!__in_pattern(*__r.ptr, __args...))
    498                 break;
    499         }
    500     }
    501 
    502     return __r;
    503 }
    504 
    505 template <typename _Tp, enable_if_t<is_unsigned<_Tp>::value, int> = 0>
    506 inline _LIBCPP_INLINE_VISIBILITY from_chars_result
    507 __from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
    508 {
    509     using __tx = __itoa::__traits<_Tp>;
    510     using __output_type = typename __tx::type;
    511 
    512     return __subject_seq_combinator(
    513         __first, __last, __value,
    514         [](const char* __first, const char* __last,
    515            _Tp& __value) -> from_chars_result {
    516             __output_type __a, __b;
    517             auto __p = __tx::__read(__first, __last, __a, __b);
    518             if (__p == __last || !__in_pattern(*__p))
    519             {
    520                 __output_type __m = (numeric_limits<_Tp>::max)();
    521                 if (__m >= __a && __m - __a >= __b)
    522                 {
    523                     __value = __a + __b;
    524                     return {__p, {}};
    525                 }
    526             }
    527             return {__p, errc::result_out_of_range};
    528         });
    529 }
    530 
    531 template <typename _Tp, enable_if_t<is_signed<_Tp>::value, int> = 0>
    532 inline _LIBCPP_INLINE_VISIBILITY from_chars_result
    533 __from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
    534 {
    535     using __t = decltype(__to_unsigned(__value));
    536     return __sign_combinator(__first, __last, __value, __from_chars_atoi<__t>);
    537 }
    538 
    539 template <typename _Tp, enable_if_t<is_unsigned<_Tp>::value, int> = 0>
    540 inline _LIBCPP_INLINE_VISIBILITY from_chars_result
    541 __from_chars_integral(const char* __first, const char* __last, _Tp& __value,
    542                       int __base)
    543 {
    544     if (__base == 10)
    545         return __from_chars_atoi(__first, __last, __value);
    546 
    547     return __subject_seq_combinator(
    548         __first, __last, __value,
    549         [](const char* __p, const char* __last, _Tp& __value,
    550            int __base) -> from_chars_result {
    551             using __tl = numeric_limits<_Tp>;
    552             auto __digits = __tl::digits / log2f(float(__base));
    553             _Tp __a = __in_pattern(*__p++, __base).__val, __b = 0;
    554 
    555             for (int __i = 1; __p != __last; ++__i, ++__p)
    556             {
    557                 if (auto __c = __in_pattern(*__p, __base))
    558                 {
    559                     if (__i < __digits - 1)
    560                         __a = __a * __base + __c.__val;
    561                     else
    562                     {
    563                         if (!__itoa::__mul_overflowed(__a, __base, __a))
    564                             ++__p;
    565                         __b = __c.__val;
    566                         break;
    567                     }
    568                 }
    569                 else
    570                     break;
    571             }
    572 
    573             if (__p == __last || !__in_pattern(*__p, __base))
    574             {
    575                 if ((__tl::max)() - __a >= __b)
    576                 {
    577                     __value = __a + __b;
    578                     return {__p, {}};
    579                 }
    580             }
    581             return {__p, errc::result_out_of_range};
    582         },
    583         __base);
    584 }
    585 
    586 template <typename _Tp, enable_if_t<is_signed<_Tp>::value, int> = 0>
    587 inline _LIBCPP_INLINE_VISIBILITY from_chars_result
    588 __from_chars_integral(const char* __first, const char* __last, _Tp& __value,
    589                       int __base)
    590 {
    591     using __t = decltype(__to_unsigned(__value));
    592     return __sign_combinator(__first, __last, __value,
    593                              __from_chars_integral<__t>, __base);
    594 }
    595 
    596 template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0>
    597 inline _LIBCPP_INLINE_VISIBILITY from_chars_result
    598 from_chars(const char* __first, const char* __last, _Tp& __value)
    599 {
    600     return __from_chars_atoi(__first, __last, __value);
    601 }
    602 
    603 template <typename _Tp, enable_if_t<is_integral<_Tp>::value, int> = 0>
    604 inline _LIBCPP_INLINE_VISIBILITY from_chars_result
    605 from_chars(const char* __first, const char* __last, _Tp& __value, int __base)
    606 {
    607     _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
    608     return __from_chars_integral(__first, __last, __value, __base);
    609 }
    610 
    611 #endif  // _LIBCPP_STD_VER > 11
    612 
    613 _LIBCPP_END_NAMESPACE_STD
    614 
    615 _LIBCPP_POP_MACROS
    616 
    617 #endif  // _LIBCPP_CHARCONV
    618