Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:30:31

0001 // Copyright 2020-2023 Daniel Lemire
0002 // Copyright 2023 Matt Borland
0003 // Distributed under the Boost Software License, Version 1.0.
0004 // https://www.boost.org/LICENSE_1_0.txt
0005 //
0006 // Derivative of: https://github.com/fastfloat/fast_float
0007 
0008 #ifndef BOOST_CHARCONV_DETAIL_FASTFLOAT_FLOAT_COMMON_HPP
0009 #define BOOST_CHARCONV_DETAIL_FASTFLOAT_FLOAT_COMMON_HPP
0010 
0011 #include <boost/charconv/detail/fast_float/constexpr_feature_detect.hpp>
0012 #include <boost/charconv/detail/from_chars_result.hpp>
0013 #include <boost/charconv/detail/config.hpp>
0014 #include <boost/charconv/chars_format.hpp>
0015 #include <cfloat>
0016 #include <cstdint>
0017 #include <cassert>
0018 #include <cstring>
0019 #include <type_traits>
0020 #include <system_error>
0021 
0022 namespace boost { namespace charconv { namespace detail { namespace fast_float {
0023 
0024 
0025 template <typename UC>
0026 struct parse_options_t {
0027   constexpr explicit parse_options_t(chars_format fmt = chars_format::general,
0028     UC dot = UC('.'))
0029     : format(fmt), decimal_point(dot) {}
0030 
0031   /** Which number formats are accepted */
0032   chars_format format;
0033   /** The character used as decimal point */
0034   UC decimal_point;
0035 };
0036 using parse_options = parse_options_t<char>;
0037 
0038 }}}}
0039 
0040 #if BOOST_CHARCONV_FASTFLOAT_HAS_BIT_CAST
0041 #include <bit>
0042 #endif
0043 
0044 #if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)   \
0045        || defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) \
0046        || defined(__MINGW64__)                                          \
0047        || defined(__s390x__)                                            \
0048        || (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) )
0049 #define BOOST_CHARCONV_FASTFLOAT_64BIT 1
0050 #elif (defined(__i386) || defined(__i386__) || defined(_M_IX86)   \
0051      || defined(__arm__) || defined(_M_ARM) || defined(__ppc__)   \
0052      || defined(__MINGW32__) || defined(__EMSCRIPTEN__))
0053 #define BOOST_CHARCONV_FASTFLOAT_32BIT 1
0054 #else
0055   // Need to check incrementally, since SIZE_MAX is a size_t, avoid overflow.
0056   // We can never tell the register width, but the SIZE_MAX is a good approximation.
0057   // UINTPTR_MAX and INTPTR_MAX are optional, so avoid them for max portability.
0058   #if SIZE_MAX == 0xffff
0059     #error Unknown platform (16-bit, unsupported)
0060   #elif SIZE_MAX == 0xffffffff
0061     #define BOOST_CHARCONV_FASTFLOAT_32BIT 1
0062   #elif SIZE_MAX == 0xffffffffffffffff
0063     #define BOOST_CHARCONV_FASTFLOAT_64BIT 1
0064   #else
0065     #error Unknown platform (not 32-bit, not 64-bit?)
0066   #endif
0067 #endif
0068 
0069 #if ((defined(_WIN32) || defined(_WIN64)) && !defined(__clang__))
0070 #include <intrin.h>
0071 #endif
0072 
0073 #if defined(_MSC_VER) && !defined(__clang__)
0074 #define BOOST_CHARCONV_FASTFLOAT_VISUAL_STUDIO 1
0075 #endif
0076 
0077 #if defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__
0078 #define BOOST_CHARCONV_FASTFLOAT_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
0079 #elif defined _WIN32
0080 #define BOOST_CHARCONV_FASTFLOAT_IS_BIG_ENDIAN 0
0081 #else
0082 #if defined(__APPLE__) || defined(__FreeBSD__)
0083 #include <machine/endian.h>
0084 #elif defined(sun) || defined(__sun)
0085 #include <sys/byteorder.h>
0086 #else
0087 #ifdef __has_include
0088 #if __has_include(<endian.h>)
0089 #include <endian.h>
0090 #endif //__has_include(<endian.h>)
0091 #endif //__has_include
0092 #endif
0093 #
0094 #ifndef __BYTE_ORDER__
0095 // safe choice
0096 #define BOOST_CHARCONV_FASTFLOAT_IS_BIG_ENDIAN 0
0097 #endif
0098 #
0099 #ifndef __ORDER_LITTLE_ENDIAN__
0100 // safe choice
0101 #define BOOST_CHARCONV_FASTFLOAT_IS_BIG_ENDIAN 0
0102 #endif
0103 #
0104 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
0105 #define BOOST_CHARCONV_FASTFLOAT_IS_BIG_ENDIAN 0
0106 #else
0107 #define BOOST_CHARCONV_FASTFLOAT_IS_BIG_ENDIAN 1
0108 #endif
0109 #endif
0110 
0111 #ifndef BOOST_CHARCONV_FASTFLOAT_ASSERT
0112 #define BOOST_CHARCONV_FASTFLOAT_ASSERT(x)  { ((void)(x)); }
0113 #endif
0114 
0115 #ifndef BOOST_CHARCONV_FASTFLOAT_DEBUG_ASSERT
0116 #define BOOST_CHARCONV_FASTFLOAT_DEBUG_ASSERT(x) { ((void)(x)); }
0117 #endif
0118 
0119 // rust style `try!()` macro, or `?` operator
0120 #define BOOST_CHARCONV_FASTFLOAT_TRY(x) { if (!(x)) return false; }
0121 
0122 namespace boost { namespace charconv { namespace detail { namespace fast_float {
0123 
0124 BOOST_FORCEINLINE constexpr bool cpp20_and_in_constexpr() {
0125 #if BOOST_CHARCONV_FASTFLOAT_HAS_IS_CONSTANT_EVALUATED
0126   return std::is_constant_evaluated();
0127 #else
0128   return false;
0129 #endif
0130 }
0131 
0132 // Compares two ASCII strings in a case insensitive manner.
0133 template <typename UC>
0134 inline BOOST_CHARCONV_FASTFLOAT_CONSTEXPR14 bool
0135 fastfloat_strncasecmp(UC const * input1, UC const * input2, size_t length) {
0136   char running_diff{0};
0137   for (size_t i = 0; i < length; ++i) {
0138     running_diff |= (char(input1[i]) ^ char(input2[i]));
0139   }
0140   return (running_diff == 0) || (running_diff == 32);
0141 }
0142 
0143 #ifndef FLT_EVAL_METHOD
0144 #error "FLT_EVAL_METHOD should be defined, please include cfloat."
0145 #endif
0146 
0147 // a pointer and a length to a contiguous block of memory
0148 template <typename T>
0149 struct span {
0150   const T* ptr;
0151   size_t length;
0152   constexpr span(const T* _ptr, size_t _length) : ptr(_ptr), length(_length) {}
0153   constexpr span() : ptr(nullptr), length(0) {}
0154 
0155   constexpr size_t len() const noexcept {
0156     return length;
0157   }
0158 
0159   BOOST_CHARCONV_FASTFLOAT_CONSTEXPR14 const T& operator[](size_t index) const noexcept {
0160     BOOST_CHARCONV_FASTFLOAT_DEBUG_ASSERT(index < length);
0161     return ptr[index];
0162   }
0163 };
0164 
0165 struct value128 {
0166   uint64_t low;
0167   uint64_t high;
0168   constexpr value128(uint64_t _low, uint64_t _high) : low(_low), high(_high) {}
0169   constexpr value128() : low(0), high(0) {}
0170 };
0171 
0172 /* Helper C++11 constexpr generic implementation of leading_zeroes */
0173 BOOST_FORCEINLINE constexpr
0174 int leading_zeroes_generic(uint64_t input_num, int last_bit = 0) {
0175   return (
0176     ((input_num & uint64_t(0xffffffff00000000)) && (input_num >>= 32, last_bit |= 32)),
0177     ((input_num & uint64_t(        0xffff0000)) && (input_num >>= 16, last_bit |= 16)),
0178     ((input_num & uint64_t(            0xff00)) && (input_num >>=  8, last_bit |=  8)),
0179     ((input_num & uint64_t(              0xf0)) && (input_num >>=  4, last_bit |=  4)),
0180     ((input_num & uint64_t(               0xc)) && (input_num >>=  2, last_bit |=  2)),
0181     ((input_num & uint64_t(               0x2)) && (input_num >>=  1, last_bit |=  1)),
0182     63 - last_bit
0183   );
0184 }
0185 
0186 /* result might be undefined when input_num is zero */
0187 BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR20
0188 int leading_zeroes(uint64_t input_num) {
0189   assert(input_num > 0);
0190   if (cpp20_and_in_constexpr()) {
0191     return leading_zeroes_generic(input_num);
0192   }
0193 #ifdef BOOST_CHARCONV_FASTFLOAT_VISUAL_STUDIO
0194   #if defined(_M_X64) || defined(_M_ARM64)
0195   unsigned long leading_zero = 0;
0196   // Search the mask data from most significant bit (MSB)
0197   // to least significant bit (LSB) for a set bit (1).
0198   _BitScanReverse64(&leading_zero, input_num);
0199   return (int)(63 - leading_zero);
0200   #else
0201   return leading_zeroes_generic(input_num);
0202   #endif
0203 #else
0204   return __builtin_clzll(input_num);
0205 #endif
0206 }
0207 
0208 // slow emulation routine for 32-bit
0209 BOOST_FORCEINLINE constexpr uint64_t emulu(uint32_t x, uint32_t y) {
0210     return x * static_cast<uint64_t>(y);
0211 }
0212 
0213 BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR14
0214 uint64_t umul128_generic(uint64_t ab, uint64_t cd, uint64_t *hi) {
0215   uint64_t ad = emulu(static_cast<uint32_t>(ab >> 32), static_cast<uint32_t>(cd));
0216   uint64_t bd = emulu(static_cast<uint32_t>(ab), static_cast<uint32_t>(cd));
0217   uint64_t adbc = ad + emulu(static_cast<uint32_t>(ab), static_cast<uint32_t>(cd >> 32));
0218   uint64_t adbc_carry = !!(adbc < ad);
0219   uint64_t lo = bd + (adbc << 32);
0220   *hi = emulu(static_cast<uint32_t>(ab >> 32), static_cast<uint32_t>(cd >> 32)) + (adbc >> 32) +
0221         (adbc_carry << 32) + !!(lo < bd);
0222   return lo;
0223 }
0224 
0225 #ifdef BOOST_CHARCONV_FASTFLOAT_32BIT
0226 
0227 // slow emulation routine for 32-bit
0228 #if !defined(__MINGW64__)
0229 BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR14
0230 uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) {
0231   return umul128_generic(ab, cd, hi);
0232 }
0233 #endif // !__MINGW64__
0234 
0235 #endif // BOOST_CHARCONV_FASTFLOAT_32BIT
0236 
0237 
0238 // compute 64-bit a*b
0239 BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR20
0240 value128 full_multiplication(uint64_t a, uint64_t b) {
0241   if (cpp20_and_in_constexpr()) {
0242     value128 answer;
0243     answer.low = umul128_generic(a, b, &answer.high);
0244     return answer;
0245   }
0246   value128 answer;
0247 #if defined(_M_ARM64) && !defined(__MINGW32__)
0248   // ARM64 has native support for 64-bit multiplications, no need to emulate
0249   // But MinGW on ARM64 doesn't have native support for 64-bit multiplications
0250   answer.high = __umulh(a, b);
0251   answer.low = a * b;
0252 #elif defined(BOOST_CHARCONV_FASTFLOAT_32BIT) ||                        \
0253     (defined(_WIN64) && !defined(__clang__) && !defined(_M_ARM64))
0254   unsigned long long high;
0255   answer.low = _umul128(a, b, &high); // _umul128 not available on ARM64
0256   answer.high = static_cast<uint64_t>(high);
0257 #elif defined(BOOST_CHARCONV_FASTFLOAT_64BIT)
0258   __uint128_t r = (static_cast<__uint128_t>(a)) * b;
0259   answer.low = uint64_t(r);
0260   answer.high = uint64_t(r >> 64);
0261 #else
0262   answer.low = umul128_generic(a, b, &answer.high);
0263 #endif
0264   return answer;
0265 }
0266 
0267 struct adjusted_mantissa {
0268   uint64_t mantissa{0};
0269   int32_t power2{0}; // a negative value indicates an invalid result
0270   adjusted_mantissa() = default;
0271   constexpr bool operator==(const adjusted_mantissa &o) const {
0272     return mantissa == o.mantissa && power2 == o.power2;
0273   }
0274   constexpr bool operator!=(const adjusted_mantissa &o) const {
0275     return mantissa != o.mantissa || power2 != o.power2;
0276   }
0277 };
0278 
0279 // Bias so we can get the real exponent with an invalid adjusted_mantissa.
0280 constexpr static int32_t invalid_am_bias = -0x8000;
0281 
0282 // used for binary_format_lookup_tables<T>::max_mantissa
0283 constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5;
0284 
0285 template <typename T, typename U = void>
0286 struct binary_format_lookup_tables;
0287 
0288 template <typename T> struct binary_format : binary_format_lookup_tables<T> {
0289   using equiv_uint = typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type;
0290 
0291   static inline constexpr int mantissa_explicit_bits();
0292   static inline constexpr int minimum_exponent();
0293   static inline constexpr int infinite_power();
0294   static inline constexpr int sign_index();
0295   static inline constexpr int min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST
0296   static inline constexpr int max_exponent_fast_path();
0297   static inline constexpr int max_exponent_round_to_even();
0298   static inline constexpr int min_exponent_round_to_even();
0299   static inline constexpr uint64_t max_mantissa_fast_path(int64_t power);
0300   static inline constexpr uint64_t max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST
0301   static inline constexpr int largest_power_of_ten();
0302   static inline constexpr int smallest_power_of_ten();
0303   static inline constexpr T exact_power_of_ten(int64_t power);
0304   static inline constexpr size_t max_digits();
0305   static inline constexpr equiv_uint exponent_mask();
0306   static inline constexpr equiv_uint mantissa_mask();
0307   static inline constexpr equiv_uint hidden_bit_mask();
0308 };
0309 
0310 template <typename U>
0311 struct binary_format_lookup_tables<double, U> {
0312   static constexpr double powers_of_ten[] = {
0313       1e0,  1e1,  1e2,  1e3,  1e4,  1e5,  1e6,  1e7,  1e8,  1e9,  1e10, 1e11,
0314       1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
0315 
0316   // Largest integer value v so that (5**index * v) <= 1<<53.
0317   // 0x10000000000000 == 1 << 53
0318   static constexpr std::uint64_t max_mantissa[] = {
0319     UINT64_C(0x10000000000000),
0320     UINT64_C(0x10000000000000) / UINT64_C(5),
0321     UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5)),
0322     UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0323     UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0324     UINT64_C(0x10000000000000) / (constant_55555),
0325     UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5)),
0326     UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5)),
0327     UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0328     UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0329     UINT64_C(0x10000000000000) / (constant_55555 * constant_55555),
0330     UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5)),
0331     UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)),
0332     UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0333     UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555),
0334     UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5)),
0335     UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)),
0336     UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0337     UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0338     UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555),
0339     UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5)),
0340     UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)),
0341     UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0342     UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5))};
0343 };
0344 
0345 template <typename U>
0346 constexpr double binary_format_lookup_tables<double, U>::powers_of_ten[];
0347 
0348 template <typename U>
0349 constexpr uint64_t binary_format_lookup_tables<double, U>::max_mantissa[];
0350 
0351 template <typename U>
0352 struct binary_format_lookup_tables<float, U> {
0353   static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f,
0354                                      1e6f, 1e7f, 1e8f, 1e9f, 1e10f};
0355 
0356   // Largest integer value v so that (5**index * v) <= 1<<24.
0357   // 0x1000000 == 1<<24
0358   static constexpr uint64_t max_mantissa[] = {
0359     UINT64_C(0x1000000),
0360     UINT64_C(0x1000000) / UINT64_C(5),
0361     UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5)),
0362     UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0363     UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0364     UINT64_C(0x1000000) / (constant_55555),
0365     UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5)),
0366     UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5)),
0367     UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0368     UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0369     UINT64_C(0x1000000) / (constant_55555 * constant_55555),
0370     UINT64_C(0x1000000) / (constant_55555 * constant_55555 * UINT64_C(5))};
0371 };
0372 
0373 template <typename U>
0374 constexpr float binary_format_lookup_tables<float, U>::powers_of_ten[];
0375 
0376 template <typename U>
0377 constexpr uint64_t binary_format_lookup_tables<float, U>::max_mantissa[];
0378 
0379 template <> inline constexpr int binary_format<double>::min_exponent_fast_path() {
0380 #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
0381   return 0;
0382 #else
0383   return -22;
0384 #endif
0385 }
0386 
0387 template <> inline constexpr int binary_format<float>::min_exponent_fast_path() {
0388 #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
0389   return 0;
0390 #else
0391   return -10;
0392 #endif
0393 }
0394 
0395 template <> inline constexpr int binary_format<double>::mantissa_explicit_bits() {
0396   return 52;
0397 }
0398 template <> inline constexpr int binary_format<float>::mantissa_explicit_bits() {
0399   return 23;
0400 }
0401 
0402 template <> inline constexpr int binary_format<double>::max_exponent_round_to_even() {
0403   return 23;
0404 }
0405 
0406 template <> inline constexpr int binary_format<float>::max_exponent_round_to_even() {
0407   return 10;
0408 }
0409 
0410 template <> inline constexpr int binary_format<double>::min_exponent_round_to_even() {
0411   return -4;
0412 }
0413 
0414 template <> inline constexpr int binary_format<float>::min_exponent_round_to_even() {
0415   return -17;
0416 }
0417 
0418 template <> inline constexpr int binary_format<double>::minimum_exponent() {
0419   return -1023;
0420 }
0421 template <> inline constexpr int binary_format<float>::minimum_exponent() {
0422   return -127;
0423 }
0424 
0425 template <> inline constexpr int binary_format<double>::infinite_power() {
0426   return 0x7FF;
0427 }
0428 template <> inline constexpr int binary_format<float>::infinite_power() {
0429   return 0xFF;
0430 }
0431 
0432 template <> inline constexpr int binary_format<double>::sign_index() { return 63; }
0433 template <> inline constexpr int binary_format<float>::sign_index() { return 31; }
0434 
0435 template <> inline constexpr int binary_format<double>::max_exponent_fast_path() {
0436   return 22;
0437 }
0438 template <> inline constexpr int binary_format<float>::max_exponent_fast_path() {
0439   return 10;
0440 }
0441 
0442 template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() {
0443   return uint64_t(2) << mantissa_explicit_bits();
0444 }
0445 template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path(int64_t power) {
0446   // caller is responsible to ensure that
0447   // power >= 0 && power <= 22
0448   //
0449   // Work around clang bug https://godbolt.org/z/zedh7rrhc
0450   return (void)max_mantissa[0], max_mantissa[power];
0451 }
0452 template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
0453   return uint64_t(2) << mantissa_explicit_bits();
0454 }
0455 template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path(int64_t power) {
0456   // caller is responsible to ensure that
0457   // power >= 0 && power <= 10
0458   //
0459   // Work around clang bug https://godbolt.org/z/zedh7rrhc
0460   return (void)max_mantissa[0], max_mantissa[power];
0461 }
0462 
0463 template <>
0464 inline constexpr double binary_format<double>::exact_power_of_ten(int64_t power) {
0465   // Work around clang bug https://godbolt.org/z/zedh7rrhc
0466   return (void)powers_of_ten[0], powers_of_ten[power];
0467 }
0468 template <>
0469 inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
0470   // Work around clang bug https://godbolt.org/z/zedh7rrhc
0471   return (void)powers_of_ten[0], powers_of_ten[power];
0472 }
0473 
0474 
0475 template <>
0476 inline constexpr int binary_format<double>::largest_power_of_ten() {
0477   return 308;
0478 }
0479 template <>
0480 inline constexpr int binary_format<float>::largest_power_of_ten() {
0481   return 38;
0482 }
0483 
0484 template <>
0485 inline constexpr int binary_format<double>::smallest_power_of_ten() {
0486   return -342;
0487 }
0488 template <>
0489 inline constexpr int binary_format<float>::smallest_power_of_ten() {
0490   return -65;
0491 }
0492 
0493 template <> inline constexpr size_t binary_format<double>::max_digits() {
0494   return 769;
0495 }
0496 template <> inline constexpr size_t binary_format<float>::max_digits() {
0497   return 114;
0498 }
0499 
0500 template <> inline constexpr binary_format<float>::equiv_uint
0501     binary_format<float>::exponent_mask() {
0502   return 0x7F800000;
0503 }
0504 template <> inline constexpr binary_format<double>::equiv_uint
0505     binary_format<double>::exponent_mask() {
0506   return 0x7FF0000000000000;
0507 }
0508 
0509 template <> inline constexpr binary_format<float>::equiv_uint
0510     binary_format<float>::mantissa_mask() {
0511   return 0x007FFFFF;
0512 }
0513 template <> inline constexpr binary_format<double>::equiv_uint
0514     binary_format<double>::mantissa_mask() {
0515   return 0x000FFFFFFFFFFFFF;
0516 }
0517 
0518 template <> inline constexpr binary_format<float>::equiv_uint
0519     binary_format<float>::hidden_bit_mask() {
0520   return 0x00800000;
0521 }
0522 template <> inline constexpr binary_format<double>::equiv_uint
0523     binary_format<double>::hidden_bit_mask() {
0524   return 0x0010000000000000;
0525 }
0526 
0527 template<typename T>
0528 BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR20
0529 void to_float(bool negative, adjusted_mantissa am, T &value) {
0530   using uint = typename binary_format<T>::equiv_uint;
0531   uint word = static_cast<uint>(am.mantissa);
0532   word |= uint(am.power2) << binary_format<T>::mantissa_explicit_bits();
0533   word |= uint(negative) << binary_format<T>::sign_index();
0534 #if BOOST_CHARCONV_FASTFLOAT_HAS_BIT_CAST
0535   value = std::bit_cast<T>(word);
0536 #else
0537   ::memcpy(&value, &word, sizeof(T));
0538 #endif
0539 }
0540 
0541 #ifdef BOOST_CHARCONV_FASTFLOAT_SKIP_WHITE_SPACE // disabled by default
0542 template <typename = void>
0543 struct space_lut {
0544   static constexpr bool value[] = {
0545     0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0546     0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0547     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0548     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0549     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0550     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0551     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0552     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0553     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0554     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0555     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
0556 };
0557 
0558 template <typename T>
0559 constexpr bool space_lut<T>::value[];
0560 
0561 inline constexpr bool is_space(uint8_t c) { return space_lut<>::value[c]; }
0562 #endif
0563 
0564 template<typename UC>
0565 static constexpr uint64_t int_cmp_zeros()
0566 {
0567     static_assert((sizeof(UC) == 1) || (sizeof(UC) == 2) || (sizeof(UC) == 4), "Unsupported character size");
0568     return (sizeof(UC) == 1) ? 0x3030303030303030 : (sizeof(UC) == 2) ? (uint64_t(UC('0')) << 48 | uint64_t(UC('0')) << 32 | uint64_t(UC('0')) << 16 | UC('0')) : (uint64_t(UC('0')) << 32 | UC('0'));
0569 }
0570 template<typename UC>
0571 static constexpr int int_cmp_len()
0572 {
0573     return sizeof(uint64_t) / sizeof(UC);
0574 }
0575 template<typename UC>
0576 static constexpr UC const * str_const_nan()
0577 {
0578     return nullptr;
0579 }
0580 template<>
0581 constexpr char const * str_const_nan<char>()
0582 {
0583     return "nan";
0584 }
0585 template<>
0586 constexpr wchar_t const * str_const_nan<wchar_t>()
0587 {
0588     return L"nan";
0589 }
0590 template<>
0591 constexpr char16_t const * str_const_nan<char16_t>()
0592 {
0593     return u"nan";
0594 }
0595 template<>
0596 constexpr char32_t const * str_const_nan<char32_t>()
0597 {
0598     return U"nan";
0599 }
0600 template<typename UC>
0601 static constexpr UC const * str_const_inf()
0602 {
0603     return nullptr;
0604 }
0605 template<>
0606 constexpr char const * str_const_inf<char>()
0607 {
0608     return "infinity";
0609 }
0610 template<>
0611 constexpr wchar_t const * str_const_inf<wchar_t>()
0612 {
0613     return L"infinity";
0614 }
0615 template<>
0616 constexpr char16_t const * str_const_inf<char16_t>()
0617 {
0618     return u"infinity";
0619 }
0620 template<>
0621 constexpr char32_t const * str_const_inf<char32_t>()
0622 {
0623     return U"infinity";
0624 }
0625 
0626 }}}} // namespaces
0627 
0628 #endif