File indexing completed on 2026-09-10 08:41:18
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 ">#
0095 #ifndef __BYTE_ORDER__
0096
0097 #define BOOST_CHARCONV_FASTFLOAT_IS_BIG_ENDIAN 0
0098 #endif
0099 0100 ">#
0101 #ifndef __ORDER_LITTLE_ENDIAN__
0102
0103 #define BOOST_CHARCONV_FASTFLOAT_IS_BIG_ENDIAN 0
0104 #endif
0105 0106 ">#
0107 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
0108 #define BOOST_CHARCONV_FASTFLOAT_IS_BIG_ENDIAN 0
0109 #else
0110 #define BOOST_CHARCONV_FASTFLOAT_IS_BIG_ENDIAN 1
0111 #endif
0112 #endif
0113
0114 #ifndef BOOST_CHARCONV_FASTFLOAT_ASSERT
0115 #define BOOST_CHARCONV_FASTFLOAT_ASSERT(x) { ((void)(x)); }
0116 #endif
0117
0118 #ifndef BOOST_CHARCONV_FASTFLOAT_DEBUG_ASSERT
0119 #define BOOST_CHARCONV_FASTFLOAT_DEBUG_ASSERT(x) { ((void)(x)); }
0120 #endif
0121
0122
0123 #define BOOST_CHARCONV_FASTFLOAT_TRY(x) { if (!(x)) return false; }
0124
0125 namespace boost { namespace charconv { namespace detail { namespace fast_float {
0126
0127 BOOST_FORCEINLINE constexpr bool cpp20_and_in_constexpr() {
0128 #if BOOST_CHARCONV_FASTFLOAT_HAS_IS_CONSTANT_EVALUATED
0129 return std::is_constant_evaluated();
0130 #else
0131 return false;
0132 #endif
0133 }
0134
0135
0136 template <typename UC>
0137 inline BOOST_CHARCONV_FASTFLOAT_CONSTEXPR14 bool
0138 fastfloat_strncasecmp(UC const * input1, UC const * input2, size_t length) {
0139 char running_diff{0};
0140 for (size_t i = 0; i < length; ++i) {
0141 running_diff |= (char(input1[i]) ^ char(input2[i]));
0142 }
0143 return (running_diff == 0) || (running_diff == 32);
0144 }
0145
0146 #ifndef FLT_EVAL_METHOD
0147 #error "FLT_EVAL_METHOD should be defined, please include cfloat."
0148 #endif
0149
0150
0151 template <typename T>
0152 struct span {
0153 const T* ptr;
0154 size_t length;
0155 constexpr span(const T* _ptr, size_t _length) : ptr(_ptr), length(_length) {}
0156 constexpr span() : ptr(nullptr), length(0) {}
0157
0158 constexpr size_t len() const noexcept {
0159 return length;
0160 }
0161
0162 BOOST_CHARCONV_FASTFLOAT_CONSTEXPR14 const T& operator[](size_t index) const noexcept {
0163 BOOST_CHARCONV_FASTFLOAT_DEBUG_ASSERT(index < length);
0164 return ptr[index];
0165 }
0166 };
0167
0168 struct value128 {
0169 uint64_t low;
0170 uint64_t high;
0171 constexpr value128(uint64_t _low, uint64_t _high) : low(_low), high(_high) {}
0172 constexpr value128() : low(0), high(0) {}
0173 };
0174
0175
0176 BOOST_FORCEINLINE constexpr
0177 int leading_zeroes_generic(uint64_t input_num, int last_bit = 0) {
0178 return (
0179 ((input_num & uint64_t(0xffffffff00000000)) && (input_num >>= 32, last_bit |= 32)),
0180 ((input_num & uint64_t( 0xffff0000)) && (input_num >>= 16, last_bit |= 16)),
0181 ((input_num & uint64_t( 0xff00)) && (input_num >>= 8, last_bit |= 8)),
0182 ((input_num & uint64_t( 0xf0)) && (input_num >>= 4, last_bit |= 4)),
0183 ((input_num & uint64_t( 0xc)) && (input_num >>= 2, last_bit |= 2)),
0184 ((input_num & uint64_t( 0x2)) && (input_num >>= 1, last_bit |= 1)),
0185 63 - last_bit
0186 );
0187 }
0188
0189
0190 BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR20
0191 int leading_zeroes(uint64_t input_num) {
0192 assert(input_num > 0);
0193 if (cpp20_and_in_constexpr()) {
0194 return leading_zeroes_generic(input_num);
0195 }
0196 #ifdef BOOST_CHARCONV_FASTFLOAT_VISUAL_STUDIO
0197 #if defined(_M_X64) || defined(_M_ARM64)
0198 unsigned long leading_zero = 0;
0199
0200
0201 _BitScanReverse64(&leading_zero, input_num);
0202 return (int)(63 - leading_zero);
0203 #else
0204 return leading_zeroes_generic(input_num);
0205 #endif
0206 #else
0207 return __builtin_clzll(input_num);
0208 #endif
0209 }
0210
0211
0212 BOOST_FORCEINLINE constexpr uint64_t emulu(uint32_t x, uint32_t y) {
0213 return x * static_cast<uint64_t>(y);
0214 }
0215
0216 BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR14
0217 uint64_t umul128_generic(uint64_t ab, uint64_t cd, uint64_t *hi) {
0218 uint64_t ad = emulu(static_cast<uint32_t>(ab >> 32), static_cast<uint32_t>(cd));
0219 uint64_t bd = emulu(static_cast<uint32_t>(ab), static_cast<uint32_t>(cd));
0220 uint64_t adbc = ad + emulu(static_cast<uint32_t>(ab), static_cast<uint32_t>(cd >> 32));
0221 uint64_t adbc_carry = !!(adbc < ad);
0222 uint64_t lo = bd + (adbc << 32);
0223 *hi = emulu(static_cast<uint32_t>(ab >> 32), static_cast<uint32_t>(cd >> 32)) + (adbc >> 32) +
0224 (adbc_carry << 32) + !!(lo < bd);
0225 return lo;
0226 }
0227
0228 #ifdef BOOST_CHARCONV_FASTFLOAT_32BIT
0229
0230
0231 #if !defined(__MINGW64__)
0232 BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR14
0233 uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) {
0234 return umul128_generic(ab, cd, hi);
0235 }
0236 #endif
0237
0238 #endif
0239
0240
0241
0242 BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR20
0243 value128 full_multiplication(uint64_t a, uint64_t b) {
0244 if (cpp20_and_in_constexpr()) {
0245 value128 answer;
0246 answer.low = umul128_generic(a, b, &answer.high);
0247 return answer;
0248 }
0249 value128 answer;
0250 #if defined(_M_ARM64) && !defined(__MINGW32__)
0251
0252
0253 answer.high = __umulh(a, b);
0254 answer.low = a * b;
0255 #elif defined(BOOST_CHARCONV_FASTFLOAT_32BIT) || \
0256 (defined(_WIN64) && !defined(__clang__) && !defined(_M_ARM64))
0257 unsigned long long high;
0258 answer.low = _umul128(a, b, &high);
0259 answer.high = static_cast<uint64_t>(high);
0260 #elif defined(BOOST_CHARCONV_FASTFLOAT_64BIT)
0261 __uint128_t r = (static_cast<__uint128_t>(a)) * b;
0262 answer.low = uint64_t(r);
0263 answer.high = uint64_t(r >> 64);
0264 #else
0265 answer.low = umul128_generic(a, b, &answer.high);
0266 #endif
0267 return answer;
0268 }
0269
0270 struct adjusted_mantissa {
0271 uint64_t mantissa{0};
0272 int32_t power2{0};
0273 adjusted_mantissa() = default;
0274 constexpr bool operator==(const adjusted_mantissa &o) const {
0275 return mantissa == o.mantissa && power2 == o.power2;
0276 }
0277 constexpr bool operator!=(const adjusted_mantissa &o) const {
0278 return mantissa != o.mantissa || power2 != o.power2;
0279 }
0280 };
0281
0282
0283 constexpr static int32_t invalid_am_bias = -0x8000;
0284
0285
0286 constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5;
0287
0288 template <typename T, typename U = void>
0289 struct binary_format_lookup_tables;
0290
0291 template <typename T> struct binary_format : binary_format_lookup_tables<T> {
0292 using equiv_uint = typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type;
0293
0294 static inline constexpr int mantissa_explicit_bits();
0295 static inline constexpr int minimum_exponent();
0296 static inline constexpr int infinite_power();
0297 static inline constexpr int sign_index();
0298 static inline constexpr int min_exponent_fast_path();
0299 static inline constexpr int max_exponent_fast_path();
0300 static inline constexpr int max_exponent_round_to_even();
0301 static inline constexpr int min_exponent_round_to_even();
0302 static inline constexpr uint64_t max_mantissa_fast_path(int64_t power);
0303 static inline constexpr uint64_t max_mantissa_fast_path();
0304 static inline constexpr int largest_power_of_ten();
0305 static inline constexpr int smallest_power_of_ten();
0306 static inline constexpr T exact_power_of_ten(int64_t power);
0307 static inline constexpr size_t max_digits();
0308 static inline constexpr equiv_uint exponent_mask();
0309 static inline constexpr equiv_uint mantissa_mask();
0310 static inline constexpr equiv_uint hidden_bit_mask();
0311 };
0312
0313 template <typename U>
0314 struct binary_format_lookup_tables<double, U> {
0315 static constexpr double powers_of_ten[] = {
0316 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
0317 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
0318
0319
0320
0321 static constexpr std::uint64_t max_mantissa[] = {
0322 UINT64_C(0x10000000000000),
0323 UINT64_C(0x10000000000000) / UINT64_C(5),
0324 UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5)),
0325 UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0326 UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0327 UINT64_C(0x10000000000000) / (constant_55555),
0328 UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5)),
0329 UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5)),
0330 UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0331 UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0332 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555),
0333 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5)),
0334 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)),
0335 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0336 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555),
0337 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5)),
0338 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)),
0339 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0340 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0341 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555),
0342 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5)),
0343 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)),
0344 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0345 UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5))};
0346 };
0347
0348 template <typename U>
0349 constexpr double binary_format_lookup_tables<double, U>::powers_of_ten[];
0350
0351 template <typename U>
0352 constexpr uint64_t binary_format_lookup_tables<double, U>::max_mantissa[];
0353
0354 template <typename U>
0355 struct binary_format_lookup_tables<float, U> {
0356 static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f,
0357 1e6f, 1e7f, 1e8f, 1e9f, 1e10f};
0358
0359
0360
0361 static constexpr uint64_t max_mantissa[] = {
0362 UINT64_C(0x1000000),
0363 UINT64_C(0x1000000) / UINT64_C(5),
0364 UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5)),
0365 UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0366 UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0367 UINT64_C(0x1000000) / (constant_55555),
0368 UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5)),
0369 UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5)),
0370 UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0371 UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
0372 UINT64_C(0x1000000) / (constant_55555 * constant_55555),
0373 UINT64_C(0x1000000) / (constant_55555 * constant_55555 * UINT64_C(5))};
0374 };
0375
0376 template <typename U>
0377 constexpr float binary_format_lookup_tables<float, U>::powers_of_ten[];
0378
0379 template <typename U>
0380 constexpr uint64_t binary_format_lookup_tables<float, U>::max_mantissa[];
0381
0382 template <> inline constexpr int binary_format<double>::min_exponent_fast_path() {
0383 #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
0384 return 0;
0385 #else
0386 return -22;
0387 #endif
0388 }
0389
0390 template <> inline constexpr int binary_format<float>::min_exponent_fast_path() {
0391 #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
0392 return 0;
0393 #else
0394 return -10;
0395 #endif
0396 }
0397
0398 template <> inline constexpr int binary_format<double>::mantissa_explicit_bits() {
0399 return 52;
0400 }
0401 template <> inline constexpr int binary_format<float>::mantissa_explicit_bits() {
0402 return 23;
0403 }
0404
0405 template <> inline constexpr int binary_format<double>::max_exponent_round_to_even() {
0406 return 23;
0407 }
0408
0409 template <> inline constexpr int binary_format<float>::max_exponent_round_to_even() {
0410 return 10;
0411 }
0412
0413 template <> inline constexpr int binary_format<double>::min_exponent_round_to_even() {
0414 return -4;
0415 }
0416
0417 template <> inline constexpr int binary_format<float>::min_exponent_round_to_even() {
0418 return -17;
0419 }
0420
0421 template <> inline constexpr int binary_format<double>::minimum_exponent() {
0422 return -1023;
0423 }
0424 template <> inline constexpr int binary_format<float>::minimum_exponent() {
0425 return -127;
0426 }
0427
0428 template <> inline constexpr int binary_format<double>::infinite_power() {
0429 return 0x7FF;
0430 }
0431 template <> inline constexpr int binary_format<float>::infinite_power() {
0432 return 0xFF;
0433 }
0434
0435 template <> inline constexpr int binary_format<double>::sign_index() { return 63; }
0436 template <> inline constexpr int binary_format<float>::sign_index() { return 31; }
0437
0438 template <> inline constexpr int binary_format<double>::max_exponent_fast_path() {
0439 return 22;
0440 }
0441 template <> inline constexpr int binary_format<float>::max_exponent_fast_path() {
0442 return 10;
0443 }
0444
0445 template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() {
0446 return uint64_t(2) << mantissa_explicit_bits();
0447 }
0448 template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path(int64_t power) {
0449
0450
0451
0452
0453 return (void)max_mantissa[0], max_mantissa[power];
0454 }
0455 template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
0456 return uint64_t(2) << mantissa_explicit_bits();
0457 }
0458 template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path(int64_t power) {
0459
0460
0461
0462
0463 return (void)max_mantissa[0], max_mantissa[power];
0464 }
0465
0466 template <>
0467 inline constexpr double binary_format<double>::exact_power_of_ten(int64_t power) {
0468
0469 return (void)powers_of_ten[0], powers_of_ten[power];
0470 }
0471 template <>
0472 inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
0473
0474 return (void)powers_of_ten[0], powers_of_ten[power];
0475 }
0476
0477
0478 template <>
0479 inline constexpr int binary_format<double>::largest_power_of_ten() {
0480 return 308;
0481 }
0482 template <>
0483 inline constexpr int binary_format<float>::largest_power_of_ten() {
0484 return 38;
0485 }
0486
0487 template <>
0488 inline constexpr int binary_format<double>::smallest_power_of_ten() {
0489 return -342;
0490 }
0491 template <>
0492 inline constexpr int binary_format<float>::smallest_power_of_ten() {
0493 return -65;
0494 }
0495
0496 template <> inline constexpr size_t binary_format<double>::max_digits() {
0497 return 769;
0498 }
0499 template <> inline constexpr size_t binary_format<float>::max_digits() {
0500 return 114;
0501 }
0502
0503 template <> inline constexpr binary_format<float>::equiv_uint
0504 binary_format<float>::exponent_mask() {
0505 return 0x7F800000;
0506 }
0507 template <> inline constexpr binary_format<double>::equiv_uint
0508 binary_format<double>::exponent_mask() {
0509 return 0x7FF0000000000000;
0510 }
0511
0512 template <> inline constexpr binary_format<float>::equiv_uint
0513 binary_format<float>::mantissa_mask() {
0514 return 0x007FFFFF;
0515 }
0516 template <> inline constexpr binary_format<double>::equiv_uint
0517 binary_format<double>::mantissa_mask() {
0518 return 0x000FFFFFFFFFFFFF;
0519 }
0520
0521 template <> inline constexpr binary_format<float>::equiv_uint
0522 binary_format<float>::hidden_bit_mask() {
0523 return 0x00800000;
0524 }
0525 template <> inline constexpr binary_format<double>::equiv_uint
0526 binary_format<double>::hidden_bit_mask() {
0527 return 0x0010000000000000;
0528 }
0529
0530 template<typename T>
0531 BOOST_FORCEINLINE BOOST_CHARCONV_FASTFLOAT_CONSTEXPR20
0532 void to_float(bool negative, adjusted_mantissa am, T &value) {
0533 using uint = typename binary_format<T>::equiv_uint;
0534 uint word = static_cast<uint>(am.mantissa);
0535 word |= uint(am.power2) << binary_format<T>::mantissa_explicit_bits();
0536 word |= uint(negative) << binary_format<T>::sign_index();
0537 #if BOOST_CHARCONV_FASTFLOAT_HAS_BIT_CAST
0538 value = std::bit_cast<T>(word);
0539 #else
0540 ::memcpy(&value, &word, sizeof(T));
0541 #endif
0542 }
0543
0544 #ifdef BOOST_CHARCONV_FASTFLOAT_SKIP_WHITE_SPACE
0545 template <typename = void>
0546 struct space_lut {
0547 static constexpr bool value[] = {
0548 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0549 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0,
0556 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0557 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0558 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
0559 };
0560
0561 template <typename T>
0562 constexpr bool space_lut<T>::value[];
0563
0564 inline constexpr bool is_space(uint8_t c) { return space_lut<>::value[c]; }
0565 #endif
0566
0567 template<typename UC>
0568 static constexpr uint64_t int_cmp_zeros()
0569 {
0570 static_assert((sizeof(UC) == 1) || (sizeof(UC) == 2) || (sizeof(UC) == 4), "Unsupported character size");
0571 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'));
0572 }
0573 template<typename UC>
0574 static constexpr int int_cmp_len()
0575 {
0576 return sizeof(uint64_t) / sizeof(UC);
0577 }
0578 template<typename UC>
0579 static constexpr UC const * str_const_nan()
0580 {
0581 return nullptr;
0582 }
0583 template<>
0584 constexpr char const * str_const_nan<char>()
0585 {
0586 return "nan";
0587 }
0588 template<>
0589 constexpr wchar_t const * str_const_nan<wchar_t>()
0590 {
0591 return L"nan";
0592 }
0593 template<>
0594 constexpr char16_t const * str_const_nan<char16_t>()
0595 {
0596 return u"nan";
0597 }
0598 template<>
0599 constexpr char32_t const * str_const_nan<char32_t>()
0600 {
0601 return U"nan";
0602 }
0603 template<typename UC>
0604 static constexpr UC const * str_const_inf()
0605 {
0606 return nullptr;
0607 }
0608 template<>
0609 constexpr char const * str_const_inf<char>()
0610 {
0611 return "infinity";
0612 }
0613 template<>
0614 constexpr wchar_t const * str_const_inf<wchar_t>()
0615 {
0616 return L"infinity";
0617 }
0618 template<>
0619 constexpr char16_t const * str_const_inf<char16_t>()
0620 {
0621 return u"infinity";
0622 }
0623 template<>
0624 constexpr char32_t const * str_const_inf<char32_t>()
0625 {
0626 return U"infinity";
0627 }
0628
0629 }}}}
0630
0631 #endif