File indexing completed on 2025-09-15 08:30:31
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) || \
0253 (defined(_WIN64) && !defined(__clang__) && !defined(_M_ARM64))
0254 unsigned long long high;
0255 answer.low = _umul128(a, b, &high);
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};
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
0280 constexpr static int32_t invalid_am_bias = -0x8000;
0281
0282
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();
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();
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
0317
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
0357
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
0447
0448
0449
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
0457
0458
0459
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
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
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
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 }}}}
0627
0628 #endif