Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:24

0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 
0010 #ifndef _LIBCPP___CXX03___CHARCONV_TO_CHARS_INTEGRAL_H
0011 #define _LIBCPP___CXX03___CHARCONV_TO_CHARS_INTEGRAL_H
0012 
0013 #include <__cxx03/__algorithm/copy_n.h>
0014 #include <__cxx03/__assert>
0015 #include <__cxx03/__bit/countl.h>
0016 #include <__cxx03/__charconv/tables.h>
0017 #include <__cxx03/__charconv/to_chars_base_10.h>
0018 #include <__cxx03/__charconv/to_chars_result.h>
0019 #include <__cxx03/__charconv/traits.h>
0020 #include <__cxx03/__config>
0021 #include <__cxx03/__system_error/errc.h>
0022 #include <__cxx03/__type_traits/enable_if.h>
0023 #include <__cxx03/__type_traits/integral_constant.h>
0024 #include <__cxx03/__type_traits/is_same.h>
0025 #include <__cxx03/__type_traits/make_32_64_or_128_bit.h>
0026 #include <__cxx03/__type_traits/make_unsigned.h>
0027 #include <__cxx03/__utility/unreachable.h>
0028 #include <__cxx03/cstddef>
0029 #include <__cxx03/cstdint>
0030 #include <__cxx03/limits>
0031 
0032 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0033 #  pragma GCC system_header
0034 #endif
0035 
0036 _LIBCPP_PUSH_MACROS
0037 #include <__cxx03/__undef_macros>
0038 
0039 _LIBCPP_BEGIN_NAMESPACE_STD
0040 
0041 #if _LIBCPP_STD_VER >= 17
0042 
0043 to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
0044 
0045 template <typename _Tp>
0046 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0047 __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type);
0048 
0049 template <typename _Tp>
0050 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0051 __to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) {
0052   auto __x = std::__to_unsigned_like(__value);
0053   if (__value < 0 && __first != __last) {
0054     *__first++ = '-';
0055     __x        = std::__complement(__x);
0056   }
0057 
0058   return std::__to_chars_itoa(__first, __last, __x, false_type());
0059 }
0060 
0061 template <typename _Tp>
0062 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0063 __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) {
0064   using __tx  = __itoa::__traits<_Tp>;
0065   auto __diff = __last - __first;
0066 
0067   if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
0068     return {__tx::__convert(__first, __value), errc(0)};
0069   else
0070     return {__last, errc::value_too_large};
0071 }
0072 
0073 #  ifndef _LIBCPP_HAS_NO_INT128
0074 template <>
0075 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0076 __to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type) {
0077   // When the value fits in 64-bits use the 64-bit code path. This reduces
0078   // the number of expensive calculations on 128-bit values.
0079   //
0080   // NOTE the 128-bit code path requires this optimization.
0081   if (__value <= numeric_limits<uint64_t>::max())
0082     return __to_chars_itoa(__first, __last, static_cast<uint64_t>(__value), false_type());
0083 
0084   using __tx  = __itoa::__traits<__uint128_t>;
0085   auto __diff = __last - __first;
0086 
0087   if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
0088     return {__tx::__convert(__first, __value), errc(0)};
0089   else
0090     return {__last, errc::value_too_large};
0091 }
0092 #  endif
0093 
0094 template <class _Tp>
0095 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0096 __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type);
0097 
0098 template <typename _Tp>
0099 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0100 __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, true_type) {
0101   auto __x = std::__to_unsigned_like(__value);
0102   if (__value < 0 && __first != __last) {
0103     *__first++ = '-';
0104     __x        = std::__complement(__x);
0105   }
0106 
0107   return std::__to_chars_integral(__first, __last, __x, __base, false_type());
0108 }
0109 
0110 namespace __itoa {
0111 
0112 template <unsigned _Base>
0113 struct _LIBCPP_HIDDEN __integral;
0114 
0115 template <>
0116 struct _LIBCPP_HIDDEN __integral<2> {
0117   template <typename _Tp>
0118   _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
0119     // If value == 0 still need one digit. If the value != this has no
0120     // effect since the code scans for the most significant bit set. (Note
0121     // that __libcpp_clz doesn't work for 0.)
0122     return numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1);
0123   }
0124 
0125   template <typename _Tp>
0126   _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result
0127   __to_chars(char* __first, char* __last, _Tp __value) {
0128     ptrdiff_t __cap = __last - __first;
0129     int __n         = __width(__value);
0130     if (__n > __cap)
0131       return {__last, errc::value_too_large};
0132 
0133     __last                   = __first + __n;
0134     char* __p                = __last;
0135     const unsigned __divisor = 16;
0136     while (__value > __divisor) {
0137       unsigned __c = __value % __divisor;
0138       __value /= __divisor;
0139       __p -= 4;
0140       std::copy_n(&__base_2_lut[4 * __c], 4, __p);
0141     }
0142     do {
0143       unsigned __c = __value % 2;
0144       __value /= 2;
0145       *--__p = "01"[__c];
0146     } while (__value != 0);
0147     return {__last, errc(0)};
0148   }
0149 };
0150 
0151 template <>
0152 struct _LIBCPP_HIDDEN __integral<8> {
0153   template <typename _Tp>
0154   _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
0155     // If value == 0 still need one digit. If the value != this has no
0156     // effect since the code scans for the most significat bit set. (Note
0157     // that __libcpp_clz doesn't work for 0.)
0158     return ((numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1)) + 2) / 3;
0159   }
0160 
0161   template <typename _Tp>
0162   _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result
0163   __to_chars(char* __first, char* __last, _Tp __value) {
0164     ptrdiff_t __cap = __last - __first;
0165     int __n         = __width(__value);
0166     if (__n > __cap)
0167       return {__last, errc::value_too_large};
0168 
0169     __last             = __first + __n;
0170     char* __p          = __last;
0171     unsigned __divisor = 64;
0172     while (__value > __divisor) {
0173       unsigned __c = __value % __divisor;
0174       __value /= __divisor;
0175       __p -= 2;
0176       std::copy_n(&__base_8_lut[2 * __c], 2, __p);
0177     }
0178     do {
0179       unsigned __c = __value % 8;
0180       __value /= 8;
0181       *--__p = "01234567"[__c];
0182     } while (__value != 0);
0183     return {__last, errc(0)};
0184   }
0185 };
0186 
0187 template <>
0188 struct _LIBCPP_HIDDEN __integral<16> {
0189   template <typename _Tp>
0190   _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
0191     // If value == 0 still need one digit. If the value != this has no
0192     // effect since the code scans for the most significat bit set. (Note
0193     // that __libcpp_clz doesn't work for 0.)
0194     return (numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1) + 3) / 4;
0195   }
0196 
0197   template <typename _Tp>
0198   _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result
0199   __to_chars(char* __first, char* __last, _Tp __value) {
0200     ptrdiff_t __cap = __last - __first;
0201     int __n         = __width(__value);
0202     if (__n > __cap)
0203       return {__last, errc::value_too_large};
0204 
0205     __last             = __first + __n;
0206     char* __p          = __last;
0207     unsigned __divisor = 256;
0208     while (__value > __divisor) {
0209       unsigned __c = __value % __divisor;
0210       __value /= __divisor;
0211       __p -= 2;
0212       std::copy_n(&__base_16_lut[2 * __c], 2, __p);
0213     }
0214     if (__first != __last)
0215       do {
0216         unsigned __c = __value % 16;
0217         __value /= 16;
0218         *--__p = "0123456789abcdef"[__c];
0219       } while (__value != 0);
0220     return {__last, errc(0)};
0221   }
0222 };
0223 
0224 } // namespace __itoa
0225 
0226 template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) >= sizeof(unsigned)), int> = 0>
0227 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) {
0228   return __itoa::__integral<_Base>::__width(__value);
0229 }
0230 
0231 template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) < sizeof(unsigned)), int> = 0>
0232 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) {
0233   return std::__to_chars_integral_width<_Base>(static_cast<unsigned>(__value));
0234 }
0235 
0236 template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) >= sizeof(unsigned)), int> = 0>
0237 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0238 __to_chars_integral(char* __first, char* __last, _Tp __value) {
0239   return __itoa::__integral<_Base>::__to_chars(__first, __last, __value);
0240 }
0241 
0242 template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) < sizeof(unsigned)), int> = 0>
0243 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0244 __to_chars_integral(char* __first, char* __last, _Tp __value) {
0245   return std::__to_chars_integral<_Base>(__first, __last, static_cast<unsigned>(__value));
0246 }
0247 
0248 template <typename _Tp>
0249 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value, unsigned __base) {
0250   _LIBCPP_ASSERT_INTERNAL(__value >= 0, "The function requires a non-negative value.");
0251 
0252   unsigned __base_2 = __base * __base;
0253   unsigned __base_3 = __base_2 * __base;
0254   unsigned __base_4 = __base_2 * __base_2;
0255 
0256   int __r = 0;
0257   while (true) {
0258     if (__value < __base)
0259       return __r + 1;
0260     if (__value < __base_2)
0261       return __r + 2;
0262     if (__value < __base_3)
0263       return __r + 3;
0264     if (__value < __base_4)
0265       return __r + 4;
0266 
0267     __value /= __base_4;
0268     __r += 4;
0269   }
0270 
0271   __libcpp_unreachable();
0272 }
0273 
0274 template <typename _Tp>
0275 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0276 __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type) {
0277   if (__base == 10) [[likely]]
0278     return std::__to_chars_itoa(__first, __last, __value, false_type());
0279 
0280   switch (__base) {
0281   case 2:
0282     return std::__to_chars_integral<2>(__first, __last, __value);
0283   case 8:
0284     return std::__to_chars_integral<8>(__first, __last, __value);
0285   case 16:
0286     return std::__to_chars_integral<16>(__first, __last, __value);
0287   }
0288 
0289   ptrdiff_t __cap = __last - __first;
0290   int __n         = std::__to_chars_integral_width(__value, __base);
0291   if (__n > __cap)
0292     return {__last, errc::value_too_large};
0293 
0294   __last    = __first + __n;
0295   char* __p = __last;
0296   do {
0297     unsigned __c = __value % __base;
0298     __value /= __base;
0299     *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c];
0300   } while (__value != 0);
0301   return {__last, errc(0)};
0302 }
0303 
0304 template <typename _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0>
0305 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0306 to_chars(char* __first, char* __last, _Tp __value) {
0307   using _Type = __make_32_64_or_128_bit_t<_Tp>;
0308   static_assert(!is_same<_Type, void>::value, "unsupported integral type used in to_chars");
0309   return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>());
0310 }
0311 
0312 template <typename _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0>
0313 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0314 to_chars(char* __first, char* __last, _Tp __value, int __base) {
0315   _LIBCPP_ASSERT_UNCATEGORIZED(2 <= __base && __base <= 36, "base not in [2, 36]");
0316 
0317   using _Type = __make_32_64_or_128_bit_t<_Tp>;
0318   return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>());
0319 }
0320 
0321 #endif // _LIBCPP_STD_VER >= 17
0322 
0323 _LIBCPP_END_NAMESPACE_STD
0324 
0325 _LIBCPP_POP_MACROS
0326 
0327 #endif // _LIBCPP___CXX03___CHARCONV_TO_CHARS_INTEGRAL_H