Back to home page

EIC code displayed by LXR

 
 

    


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

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