File indexing completed on 2025-04-19 08:19:38
0001
0002
0003
0004
0005
0006
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
0032 chars_format format;
0033
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
0056
0057
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
0091 #endif
0092 #endif
0093 #
0094 #ifndef __BYTE_ORDER__
0095
0096 #define BOOST_CHARCONV_FASTFLOAT_IS_BIG_ENDIAN 0
0097 #endif
0098 #
0099 #ifndef __ORDER_LITTLE_ENDIAN__
0100
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
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
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
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
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
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
0197
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
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
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
0234
0235 #endif
0236
0237
0238
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
0249
0250 answer.high = __umulh(a, b);
0251 answer.low = a * b;
0252 #elif defined(BOOST_CHARCONV_FASTFLOAT_32BIT) || (defined(_WIN64) && !defined(__clang__))
0253 unsigned long long high;
0254 answer.low = _umul128(a, b, &high);
0255 answer.high = static_cast<uint64_t>(high);
0256 #elif defined(BOOST_CHARCONV_FASTFLOAT_64BIT)
0257 __uint128_t r = (static_cast<__uint128_t>(a)) * b;
0258 answer.low = uint64_t(r);
0259 answer.high = uint64_t(r >> 64);
0260 #else
0261 answer.low = umul128_generic(a, b, &answer.high);
0262 #endif
0263 return answer;
0264 }
0265
0266 struct adjusted_mantissa {
0267 uint64_t mantissa{0};
0268 int32_t power2{0};
0269 adjusted_mantissa() = default;
0270 constexpr bool operator==(const adjusted_mantissa &o) const {
0271 return mantissa == o.mantissa && power2 == o.power2;
0272 }
0273 constexpr bool operator!=(const adjusted_mantissa &o) const {
0274 return mantissa != o.mantissa || power2 != o.power2;
0275 }
0276 };
0277
0278
0279 constexpr static int32_t invalid_am_bias = -0x8000;
0280
0281
0282 constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5;
0283
0284 template <typename T, typename U = void>
0285 struct binary_format_lookup_tables;
0286
0287 template <typename T> struct binary_format : binary_format_lookup_tables<T> {
0288 using equiv_uint = typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type;
0289
0290 static inline constexpr int mantissa_explicit_bits();
0291 static inline constexpr int minimum_exponent();
0292 static inline constexpr int infinite_power();
0293 static inline constexpr int sign_index();
0294 static inline constexpr int min_exponent_fast_path();
0295 static inline constexpr int max_exponent_fast_path();
0296 static inline constexpr int max_exponent_round_to_even();
0297 static inline constexpr int min_exponent_round_to_even();
0298 static inline constexpr uint64_t max_mantissa_fast_path(int64_t power);
0299 static inline constexpr uint64_t max_mantissa_fast_path();
0300 static inline constexpr int largest_power_of_ten();
0301 static inline constexpr int smallest_power_of_ten();
0302 static inline constexpr T exact_power_of_ten(int64_t power);
0303 static inline constexpr size_t max_digits();
0304 static inline constexpr equiv_uint exponent_mask();
0305 static inline constexpr equiv_uint mantissa_mask();
0306 static inline constexpr equiv_uint hidden_bit_mask();
0307 };
0308
0309 template <typename U>
0310 struct binary_format_lookup_tables<double, U> {
0311 static constexpr double powers_of_ten[] = {
0312 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
0313 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
0314
0315
0316
0317 static constexpr std::uint64_t max_mantissa[] = {
0318 UINT64_C(0x10000000000000),
0319 UINT64_C(0x10000000000000) / UINT64_C(5),
0320 UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5)),
0321 UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0322 UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0323 UINT64_C(0x10000000000000) / (constant_55555),
0324 UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5)),
0325 UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5)),
0326 UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0327 UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0328 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555),
0329 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5)),
0330 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)),
0331 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0332 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555),
0333 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5)),
0334 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)),
0335 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * 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) * UINT64_C(5)),
0337 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555),
0338 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5)),
0339 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)),
0340 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * 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) * UINT64_C(5))};
0342 };
0343
0344 template <typename U>
0345 constexpr double binary_format_lookup_tables<double, U>::powers_of_ten[];
0346
0347 template <typename U>
0348 constexpr uint64_t binary_format_lookup_tables<double, U>::max_mantissa[];
0349
0350 template <typename U>
0351 struct binary_format_lookup_tables<float, U> {
0352 static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f,
0353 1e6f, 1e7f, 1e8f, 1e9f, 1e10f};
0354
0355
0356
0357 static constexpr uint64_t max_mantissa[] = {
0358 UINT64_C(0x1000000),
0359 UINT64_C(0x1000000) / UINT64_C(5),
0360 UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5)),
0361 UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0362 UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0363 UINT64_C(0x1000000) / (constant_55555),
0364 UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5)),
0365 UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5)),
0366 UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0367 UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0368 UINT64_C(0x1000000) / (constant_55555 * constant_55555),
0369 UINT64_C(0x1000000) / (constant_55555 * constant_55555 * UINT64_C(5))};
0370 };
0371
0372 template <typename U>
0373 constexpr float binary_format_lookup_tables<float, U>::powers_of_ten[];
0374
0375 template <typename U>
0376 constexpr uint64_t binary_format_lookup_tables<float, U>::max_mantissa[];
0377
0378 template <> inline constexpr int binary_format<double>::min_exponent_fast_path() {
0379 #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
0380 return 0;
0381 #else
0382 return -22;
0383 #endif
0384 }
0385
0386 template <> inline constexpr int binary_format<float>::min_exponent_fast_path() {
0387 #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
0388 return 0;
0389 #else
0390 return -10;
0391 #endif
0392 }
0393
0394 template <> inline constexpr int binary_format<double>::mantissa_explicit_bits() {
0395 return 52;
0396 }
0397 template <> inline constexpr int binary_format<float>::mantissa_explicit_bits() {
0398 return 23;
0399 }
0400
0401 template <> inline constexpr int binary_format<double>::max_exponent_round_to_even() {
0402 return 23;
0403 }
0404
0405 template <> inline constexpr int binary_format<float>::max_exponent_round_to_even() {
0406 return 10;
0407 }
0408
0409 template <> inline constexpr int binary_format<double>::min_exponent_round_to_even() {
0410 return -4;
0411 }
0412
0413 template <> inline constexpr int binary_format<float>::min_exponent_round_to_even() {
0414 return -17;
0415 }
0416
0417 template <> inline constexpr int binary_format<double>::minimum_exponent() {
0418 return -1023;
0419 }
0420 template <> inline constexpr int binary_format<float>::minimum_exponent() {
0421 return -127;
0422 }
0423
0424 template <> inline constexpr int binary_format<double>::infinite_power() {
0425 return 0x7FF;
0426 }
0427 template <> inline constexpr int binary_format<float>::infinite_power() {
0428 return 0xFF;
0429 }
0430
0431 template <> inline constexpr int binary_format<double>::sign_index() { return 63; }
0432 template <> inline constexpr int binary_format<float>::sign_index() { return 31; }
0433
0434 template <> inline constexpr int binary_format<double>::max_exponent_fast_path() {
0435 return 22;
0436 }
0437 template <> inline constexpr int binary_format<float>::max_exponent_fast_path() {
0438 return 10;
0439 }
0440
0441 template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() {
0442 return uint64_t(2) << mantissa_explicit_bits();
0443 }
0444 template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path(int64_t power) {
0445
0446
0447
0448
0449 return (void)max_mantissa[0], max_mantissa[power];
0450 }
0451 template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
0452 return uint64_t(2) << mantissa_explicit_bits();
0453 }
0454 template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path(int64_t power) {
0455
0456
0457
0458
0459 return (void)max_mantissa[0], max_mantissa[power];
0460 }
0461
0462 template <>
0463 inline constexpr double binary_format<double>::exact_power_of_ten(int64_t power) {
0464
0465 return (void)powers_of_ten[0], powers_of_ten[power];
0466 }
0467 template <>
0468 inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
0469
0470 return (void)powers_of_ten[0], powers_of_ten[power];
0471 }
0472
0473
0474 template <>
0475 inline constexpr int binary_format<double>::largest_power_of_ten() {
0476 return 308;
0477 }
0478 template <>
0479 inline constexpr int binary_format<float>::largest_power_of_ten() {
0480 return 38;
0481 }
0482
0483 template <>
0484 inline constexpr int binary_format<double>::smallest_power_of_ten() {
0485 return -342;
0486 }
0487 template <>
0488 inline constexpr int binary_format<float>::smallest_power_of_ten() {
0489 return -65;
0490 }
0491
0492 template <> inline constexpr size_t binary_format<double>::max_digits() {
0493 return 769;
0494 }
0495 template <> inline constexpr size_t binary_format<float>::max_digits() {
0496 return 114;
0497 }
0498
0499 template <> inline constexpr binary_format<float>::equiv_uint
0500 binary_format<float>::exponent_mask() {
0501 return 0x7F800000;
0502 }
0503 template <> inline constexpr binary_format<double>::equiv_uint
0504 binary_format<double>::exponent_mask() {
0505 return 0x7FF0000000000000;
0506 }
0507
0508 template <> inline constexpr binary_format<float>::equiv_uint
0509 binary_format<float>::mantissa_mask() {
0510 return 0x007FFFFF;
0511 }
0512 template <> inline constexpr binary_format<double>::equiv_uint
0513 binary_format<double>::mantissa_mask() {
0514 return 0x000FFFFFFFFFFFFF;
0515 }
0516
0517 template <> inline constexpr binary_format<float>::equiv_uint
0518 binary_format<float>::hidden_bit_mask() {
0519 return 0x00800000;
0520 }
0521 template <> inline constexpr binary_format<double>::equiv_uint
0522 binary_format<double>::hidden_bit_mask() {
0523 return 0x0010000000000000;
0524 }
0525
0526 template<typename T>
0527 BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR20
0528 void to_float(bool negative, adjusted_mantissa am, T &value) {
0529 using uint = typename binary_format<T>::equiv_uint;
0530 uint word = static_cast<uint>(am.mantissa);
0531 word |= uint(am.power2) << binary_format<T>::mantissa_explicit_bits();
0532 word |= uint(negative) << binary_format<T>::sign_index();
0533 #if BOOST_CHARCONV_FASTFLOAT_HAS_BIT_CAST
0534 value = std::bit_cast<T>(word);
0535 #else
0536 ::memcpy(&value, &word, sizeof(T));
0537 #endif
0538 }
0539
0540 #ifdef BOOST_CHARCONV_FASTFLOAT_SKIP_WHITE_SPACE
0541 template <typename = void>
0542 struct space_lut {
0543 static constexpr bool value[] = {
0544 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0545 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0546 0, 0, 0, 0, 0, 0, 0, 0, 0, 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};
0555 };
0556
0557 template <typename T>
0558 constexpr bool space_lut<T>::value[];
0559
0560 inline constexpr bool is_space(uint8_t c) { return space_lut<>::value[c]; }
0561 #endif
0562
0563 template<typename UC>
0564 static constexpr uint64_t int_cmp_zeros()
0565 {
0566 static_assert((sizeof(UC) == 1) || (sizeof(UC) == 2) || (sizeof(UC) == 4), "Unsupported character size");
0567 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'));
0568 }
0569 template<typename UC>
0570 static constexpr int int_cmp_len()
0571 {
0572 return sizeof(uint64_t) / sizeof(UC);
0573 }
0574 template<typename UC>
0575 static constexpr UC const * str_const_nan()
0576 {
0577 return nullptr;
0578 }
0579 template<>
0580 constexpr char const * str_const_nan<char>()
0581 {
0582 return "nan";
0583 }
0584 template<>
0585 constexpr wchar_t const * str_const_nan<wchar_t>()
0586 {
0587 return L"nan";
0588 }
0589 template<>
0590 constexpr char16_t const * str_const_nan<char16_t>()
0591 {
0592 return u"nan";
0593 }
0594 template<>
0595 constexpr char32_t const * str_const_nan<char32_t>()
0596 {
0597 return U"nan";
0598 }
0599 template<typename UC>
0600 static constexpr UC const * str_const_inf()
0601 {
0602 return nullptr;
0603 }
0604 template<>
0605 constexpr char const * str_const_inf<char>()
0606 {
0607 return "infinity";
0608 }
0609 template<>
0610 constexpr wchar_t const * str_const_inf<wchar_t>()
0611 {
0612 return L"infinity";
0613 }
0614 template<>
0615 constexpr char16_t const * str_const_inf<char16_t>()
0616 {
0617 return u"infinity";
0618 }
0619 template<>
0620 constexpr char32_t const * str_const_inf<char32_t>()
0621 {
0622 return U"infinity";
0623 }
0624
0625 }}}}
0626
0627 #endif