62.65% Lines (52/83) 82.61% Functions (19/23)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // Copyright 2020-2023 Daniel Lemire 1   // Copyright 2020-2023 Daniel Lemire
2   // Copyright 2023 Matt Borland 2   // Copyright 2023 Matt Borland
3   // Distributed under the Boost Software License, Version 1.0. 3   // Distributed under the Boost Software License, Version 1.0.
4   // https://www.boost.org/LICENSE_1_0.txt 4   // https://www.boost.org/LICENSE_1_0.txt
5   // 5   //
6   // Derivative of: https://github.com/fastfloat/fast_float 6   // Derivative of: https://github.com/fastfloat/fast_float
7   7  
8   #ifndef BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_FLOAT_COMMON_HPP 8   #ifndef BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_FLOAT_COMMON_HPP
9   #define BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_FLOAT_COMMON_HPP 9   #define BOOST_JSON_DETAIL_CHARCONV_DETAIL_FASTFLOAT_FLOAT_COMMON_HPP
10   10  
11   #include <boost/json/detail/charconv/detail/fast_float/constexpr_feature_detect.hpp> 11   #include <boost/json/detail/charconv/detail/fast_float/constexpr_feature_detect.hpp>
12   #include <boost/json/detail/charconv/detail/from_chars_result.hpp> 12   #include <boost/json/detail/charconv/detail/from_chars_result.hpp>
13   #include <boost/json/detail/charconv/detail/config.hpp> 13   #include <boost/json/detail/charconv/detail/config.hpp>
14   #include <boost/json/detail/charconv/chars_format.hpp> 14   #include <boost/json/detail/charconv/chars_format.hpp>
15   #include <cfloat> 15   #include <cfloat>
16   #include <cstdint> 16   #include <cstdint>
17   #include <cassert> 17   #include <cassert>
18   #include <cstring> 18   #include <cstring>
19   #include <type_traits> 19   #include <type_traits>
20   #include <system_error> 20   #include <system_error>
21   21  
22   namespace boost { namespace json { namespace detail { namespace charconv { namespace detail { namespace fast_float { 22   namespace boost { namespace json { namespace detail { namespace charconv { namespace detail { namespace fast_float {
23   23  
24   24  
25   template <typename UC> 25   template <typename UC>
26   struct parse_options_t { 26   struct parse_options_t {
HITCBC 27   1009310 constexpr explicit parse_options_t(chars_format fmt = chars_format::general, 27   1009310 constexpr explicit parse_options_t(chars_format fmt = chars_format::general,
28   UC dot = UC('.')) 28   UC dot = UC('.'))
HITCBC 29   1009310 : format(fmt), decimal_point(dot) {} 29   1009310 : format(fmt), decimal_point(dot) {}
30   30  
31   /** Which number formats are accepted */ 31   /** Which number formats are accepted */
32   chars_format format; 32   chars_format format;
33   /** The character used as decimal point */ 33   /** The character used as decimal point */
34   UC decimal_point; 34   UC decimal_point;
35   }; 35   };
36   using parse_options = parse_options_t<char>; 36   using parse_options = parse_options_t<char>;
37   37  
38   }}}}}} 38   }}}}}}
39   39  
40   #ifdef BOOST_JSON_HAS_BIT_CAST 40   #ifdef BOOST_JSON_HAS_BIT_CAST
41   #include <bit> 41   #include <bit>
42   #endif 42   #endif
43   43  
44   #if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \ 44   #if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \
45   || defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) \ 45   || defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) \
46   || defined(__MINGW64__) \ 46   || defined(__MINGW64__) \
47   || defined(__s390x__) \ 47   || defined(__s390x__) \
48   || (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) ) 48   || (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) )
49   #define BOOST_JSON_FASTFLOAT_64BIT 1 49   #define BOOST_JSON_FASTFLOAT_64BIT 1
50   #elif (defined(__i386) || defined(__i386__) || defined(_M_IX86) \ 50   #elif (defined(__i386) || defined(__i386__) || defined(_M_IX86) \
51   || defined(__arm__) || defined(_M_ARM) || defined(__ppc__) \ 51   || defined(__arm__) || defined(_M_ARM) || defined(__ppc__) \
52   || defined(__MINGW32__) || defined(__EMSCRIPTEN__)) 52   || defined(__MINGW32__) || defined(__EMSCRIPTEN__))
53   #define BOOST_JSON_FASTFLOAT_32BIT 1 53   #define BOOST_JSON_FASTFLOAT_32BIT 1
54   #else 54   #else
55   // Need to check incrementally, since SIZE_MAX is a size_t, avoid overflow. 55   // Need to check incrementally, since SIZE_MAX is a size_t, avoid overflow.
56   // We can never tell the register width, but the SIZE_MAX is a good approximation. 56   // We can never tell the register width, but the SIZE_MAX is a good approximation.
57   // UINTPTR_MAX and INTPTR_MAX are optional, so avoid them for max portability. 57   // UINTPTR_MAX and INTPTR_MAX are optional, so avoid them for max portability.
58   #if SIZE_MAX == 0xffff 58   #if SIZE_MAX == 0xffff
59   #error Unknown platform (16-bit, unsupported) 59   #error Unknown platform (16-bit, unsupported)
60   #elif SIZE_MAX == 0xffffffff 60   #elif SIZE_MAX == 0xffffffff
61   #define BOOST_JSON_FASTFLOAT_32BIT 1 61   #define BOOST_JSON_FASTFLOAT_32BIT 1
62   #elif SIZE_MAX == 0xffffffffffffffff 62   #elif SIZE_MAX == 0xffffffffffffffff
63   #define BOOST_JSON_FASTFLOAT_64BIT 1 63   #define BOOST_JSON_FASTFLOAT_64BIT 1
64   #else 64   #else
65   #error Unknown platform (not 32-bit, not 64-bit?) 65   #error Unknown platform (not 32-bit, not 64-bit?)
66   #endif 66   #endif
67   #endif 67   #endif
68   68  
69   #if ((defined(_WIN32) || defined(_WIN64)) && !defined(__clang__)) 69   #if ((defined(_WIN32) || defined(_WIN64)) && !defined(__clang__))
70   #include <intrin.h> 70   #include <intrin.h>
71   #endif 71   #endif
72   72  
73   #if defined(_MSC_VER) && !defined(__clang__) 73   #if defined(_MSC_VER) && !defined(__clang__)
74   #define BOOST_JSON_FASTFLOAT_VISUAL_STUDIO 1 74   #define BOOST_JSON_FASTFLOAT_VISUAL_STUDIO 1
75   #endif 75   #endif
76   76  
77   // rust style `try!()` macro, or `?` operator 77   // rust style `try!()` macro, or `?` operator
78   #define BOOST_JSON_FASTFLOAT_TRY(x) { if (!(x)) return false; } 78   #define BOOST_JSON_FASTFLOAT_TRY(x) { if (!(x)) return false; }
79   79  
80   namespace boost { namespace json { namespace detail { namespace charconv { namespace detail { namespace fast_float { 80   namespace boost { namespace json { namespace detail { namespace charconv { namespace detail { namespace fast_float {
81   81  
82   BOOST_FORCEINLINE constexpr bool cpp20_and_in_constexpr() { 82   BOOST_FORCEINLINE constexpr bool cpp20_and_in_constexpr() {
83   #ifdef BOOST_JSON_HAS_IS_CONSTANT_EVALUATED 83   #ifdef BOOST_JSON_HAS_IS_CONSTANT_EVALUATED
84   return std::is_constant_evaluated(); 84   return std::is_constant_evaluated();
85   #else 85   #else
HITCBC 86   8902634 return false; 86   8902634 return false;
87   #endif 87   #endif
88   } 88   }
89   89  
90   // Compares two ASCII strings in a case insensitive manner. 90   // Compares two ASCII strings in a case insensitive manner.
91   template <typename UC> 91   template <typename UC>
92   inline BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE bool 92   inline BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE bool
MISUBC 93   fastfloat_strncasecmp(UC const * input1, UC const * input2, size_t length) { 93   fastfloat_strncasecmp(UC const * input1, UC const * input2, size_t length) {
MISUBC 94   char running_diff{0}; 94   char running_diff{0};
MISUBC 95   for (size_t i = 0; i < length; ++i) { 95   for (size_t i = 0; i < length; ++i) {
MISUBC 96   running_diff |= (char(input1[i]) ^ char(input2[i])); 96   running_diff |= (char(input1[i]) ^ char(input2[i]));
97   } 97   }
MISUBC 98   return (running_diff == 0) || (running_diff == 32); 98   return (running_diff == 0) || (running_diff == 32);
99   } 99   }
100   100  
101   #ifndef FLT_EVAL_METHOD 101   #ifndef FLT_EVAL_METHOD
102   #error "FLT_EVAL_METHOD should be defined, please include cfloat." 102   #error "FLT_EVAL_METHOD should be defined, please include cfloat."
103   #endif 103   #endif
104   104  
105   // a pointer and a length to a contiguous block of memory 105   // a pointer and a length to a contiguous block of memory
106   template <typename T> 106   template <typename T>
107   struct span { 107   struct span {
108   const T* ptr; 108   const T* ptr;
109   size_t length; 109   size_t length;
HITCBC 110   2028274 constexpr span(const T* _ptr, size_t _length) : ptr(_ptr), length(_length) {} 110   2028274 constexpr span(const T* _ptr, size_t _length) : ptr(_ptr), length(_length) {}
111   constexpr span() : ptr(nullptr), length(0) {} 111   constexpr span() : ptr(nullptr), length(0) {}
112   112  
HITCBC 113   1155768 constexpr size_t len() const noexcept { 113   1155768 constexpr size_t len() const noexcept {
HITCBC 114   1155768 return length; 114   1155768 return length;
115   } 115   }
116   116  
HITCBC 117   36365 BOOST_JSON_CXX14_CONSTEXPR const T& operator[](size_t index) const noexcept { 117   36365 BOOST_JSON_CXX14_CONSTEXPR const T& operator[](size_t index) const noexcept {
HITCBC 118   36365 BOOST_ASSERT(index < length); 118   36365 BOOST_ASSERT(index < length);
HITCBC 119   36365 return ptr[index]; 119   36365 return ptr[index];
120   } 120   }
121   }; 121   };
122   122  
123   struct value128 { 123   struct value128 {
124   uint64_t low; 124   uint64_t low;
125   uint64_t high; 125   uint64_t high;
126   constexpr value128(uint64_t _low, uint64_t _high) : low(_low), high(_high) {} 126   constexpr value128(uint64_t _low, uint64_t _high) : low(_low), high(_high) {}
127   constexpr value128() : low(0), high(0) {} 127   constexpr value128() : low(0), high(0) {}
128   }; 128   };
129   129  
130   /* Helper C++11 constexpr generic implementation of leading_zeroes */ 130   /* Helper C++11 constexpr generic implementation of leading_zeroes */
131   BOOST_FORCEINLINE constexpr 131   BOOST_FORCEINLINE constexpr
132   int leading_zeroes_generic(uint64_t input_num, int last_bit = 0) { 132   int leading_zeroes_generic(uint64_t input_num, int last_bit = 0) {
133   return ( 133   return (
MISUBC 134   ((input_num & uint64_t(0xffffffff00000000)) && (input_num >>= 32, last_bit |= 32)), 134   ((input_num & uint64_t(0xffffffff00000000)) && (input_num >>= 32, last_bit |= 32)),
MISUBC 135   ((input_num & uint64_t( 0xffff0000)) && (input_num >>= 16, last_bit |= 16)), 135   ((input_num & uint64_t( 0xffff0000)) && (input_num >>= 16, last_bit |= 16)),
MISUBC 136   ((input_num & uint64_t( 0xff00)) && (input_num >>= 8, last_bit |= 8)), 136   ((input_num & uint64_t( 0xff00)) && (input_num >>= 8, last_bit |= 8)),
MISUBC 137   ((input_num & uint64_t( 0xf0)) && (input_num >>= 4, last_bit |= 4)), 137   ((input_num & uint64_t( 0xf0)) && (input_num >>= 4, last_bit |= 4)),
MISUBC 138   ((input_num & uint64_t( 0xc)) && (input_num >>= 2, last_bit |= 2)), 138   ((input_num & uint64_t( 0xc)) && (input_num >>= 2, last_bit |= 2)),
MISUBC 139   ((input_num & uint64_t( 0x2)) && (input_num >>= 1, last_bit |= 1)), 139   ((input_num & uint64_t( 0x2)) && (input_num >>= 1, last_bit |= 1)),
140   63 - last_bit 140   63 - last_bit
MISUBC 141   ); 141   );
142   } 142   }
143   143  
144   /* result might be undefined when input_num is zero */ 144   /* result might be undefined when input_num is zero */
145   BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20 145   BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
146   int leading_zeroes(uint64_t input_num) { 146   int leading_zeroes(uint64_t input_num) {
HITCBC 147   2008629 assert(input_num > 0); 147   2008629 assert(input_num > 0);
HITCBC 148   2008629 if (cpp20_and_in_constexpr()) { 148   2008629 if (cpp20_and_in_constexpr()) {
MISUBC 149   return leading_zeroes_generic(input_num); 149   return leading_zeroes_generic(input_num);
150   } 150   }
151   #ifdef BOOST_JSON_FASTFLOAT_VISUAL_STUDIO 151   #ifdef BOOST_JSON_FASTFLOAT_VISUAL_STUDIO
152   #if defined(_M_X64) || defined(_M_ARM64) 152   #if defined(_M_X64) || defined(_M_ARM64)
153   unsigned long leading_zero = 0; 153   unsigned long leading_zero = 0;
154   // Search the mask data from most significant bit (MSB) 154   // Search the mask data from most significant bit (MSB)
155   // to least significant bit (LSB) for a set bit (1). 155   // to least significant bit (LSB) for a set bit (1).
156   _BitScanReverse64(&leading_zero, input_num); 156   _BitScanReverse64(&leading_zero, input_num);
157   return (int)(63 - leading_zero); 157   return (int)(63 - leading_zero);
158   #else 158   #else
159   return leading_zeroes_generic(input_num); 159   return leading_zeroes_generic(input_num);
160   #endif 160   #endif
161   #else 161   #else
HITCBC 162   2008629 return __builtin_clzll(input_num); 162   2008629 return __builtin_clzll(input_num);
163   #endif 163   #endif
164   } 164   }
165   165  
166   // slow emulation routine for 32-bit 166   // slow emulation routine for 32-bit
167   BOOST_FORCEINLINE constexpr uint64_t emulu(uint32_t x, uint32_t y) { 167   BOOST_FORCEINLINE constexpr uint64_t emulu(uint32_t x, uint32_t y) {
MISUBC 168   return x * (uint64_t)y; 168   return x * (uint64_t)y;
169   } 169   }
170   170  
171   BOOST_FORCEINLINE BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE 171   BOOST_FORCEINLINE BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE
172   uint64_t umul128_generic(uint64_t ab, uint64_t cd, uint64_t *hi) { 172   uint64_t umul128_generic(uint64_t ab, uint64_t cd, uint64_t *hi) {
MISUBC 173   uint64_t ad = emulu((uint32_t)(ab >> 32), (uint32_t)cd); 173   uint64_t ad = emulu((uint32_t)(ab >> 32), (uint32_t)cd);
MISUBC 174   uint64_t bd = emulu((uint32_t)ab, (uint32_t)cd); 174   uint64_t bd = emulu((uint32_t)ab, (uint32_t)cd);
MISUBC 175   uint64_t adbc = ad + emulu((uint32_t)ab, (uint32_t)(cd >> 32)); 175   uint64_t adbc = ad + emulu((uint32_t)ab, (uint32_t)(cd >> 32));
MISUBC 176   uint64_t adbc_carry = !!(adbc < ad); 176   uint64_t adbc_carry = !!(adbc < ad);
MISUBC 177   uint64_t lo = bd + (adbc << 32); 177   uint64_t lo = bd + (adbc << 32);
MISUBC 178   *hi = emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + 178   *hi = emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) +
MISUBC 179   (adbc_carry << 32) + !!(lo < bd); 179   (adbc_carry << 32) + !!(lo < bd);
MISUBC 180   return lo; 180   return lo;
181   } 181   }
182   182  
183   #ifdef BOOST_JSON_FASTFLOAT_32BIT 183   #ifdef BOOST_JSON_FASTFLOAT_32BIT
184   184  
185   // slow emulation routine for 32-bit 185   // slow emulation routine for 32-bit
186   #if !defined(__MINGW64__) 186   #if !defined(__MINGW64__)
187   BOOST_FORCEINLINE BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE 187   BOOST_FORCEINLINE BOOST_JSON_CXX14_CONSTEXPR_NO_INLINE
188   uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) { 188   uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) {
189   return umul128_generic(ab, cd, hi); 189   return umul128_generic(ab, cd, hi);
190   } 190   }
191   #endif // !__MINGW64__ 191   #endif // !__MINGW64__
192   192  
193   #endif // BOOST_JSON_FASTFLOAT_32BIT 193   #endif // BOOST_JSON_FASTFLOAT_32BIT
194   194  
195   195  
196   // compute 64-bit a*b 196   // compute 64-bit a*b
197   BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20 197   BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
198   value128 full_multiplication(uint64_t a, uint64_t b) { 198   value128 full_multiplication(uint64_t a, uint64_t b) {
HITCBC 199   2010874 if (cpp20_and_in_constexpr()) { 199   2010874 if (cpp20_and_in_constexpr()) {
MISUBC 200   value128 answer; 200   value128 answer;
MISUBC 201   answer.low = umul128_generic(a, b, &answer.high); 201   answer.low = umul128_generic(a, b, &answer.high);
MISUBC 202   return answer; 202   return answer;
203   } 203   }
HITCBC 204   2010874 value128 answer; 204   2010874 value128 answer;
205   #if defined(_M_ARM64) && !defined(__MINGW32__) 205   #if defined(_M_ARM64) && !defined(__MINGW32__)
206   // ARM64 has native support for 64-bit multiplications, no need to emulate 206   // ARM64 has native support for 64-bit multiplications, no need to emulate
207   // But MinGW on ARM64 doesn't have native support for 64-bit multiplications 207   // But MinGW on ARM64 doesn't have native support for 64-bit multiplications
208   answer.high = __umulh(a, b); 208   answer.high = __umulh(a, b);
209   answer.low = a * b; 209   answer.low = a * b;
210   #elif defined(BOOST_JSON_FASTFLOAT_32BIT) || \ 210   #elif defined(BOOST_JSON_FASTFLOAT_32BIT) || \
211   (defined(_WIN64) && !defined(__clang__) && !defined(_M_ARM64)) 211   (defined(_WIN64) && !defined(__clang__) && !defined(_M_ARM64))
212   unsigned long long high; 212   unsigned long long high;
213   answer.low = _umul128(a, b, &high); // _umul128 not available on ARM64 213   answer.low = _umul128(a, b, &high); // _umul128 not available on ARM64
214   answer.high = static_cast<uint64_t>(high); 214   answer.high = static_cast<uint64_t>(high);
215   #elif defined(BOOST_JSON_FASTFLOAT_64BIT) 215   #elif defined(BOOST_JSON_FASTFLOAT_64BIT)
HITCBC 216   2010874 __uint128_t r = ((__uint128_t)a) * b; 216   2010874 __uint128_t r = ((__uint128_t)a) * b;
HITCBC 217   2010874 answer.low = uint64_t(r); 217   2010874 answer.low = uint64_t(r);
HITCBC 218   2010874 answer.high = uint64_t(r >> 64); 218   2010874 answer.high = uint64_t(r >> 64);
219   #else 219   #else
220   answer.low = umul128_generic(a, b, &answer.high); 220   answer.low = umul128_generic(a, b, &answer.high);
221   #endif 221   #endif
HITCBC 222   2010874 return answer; 222   2010874 return answer;
223   } 223   }
224   224  
225   struct adjusted_mantissa { 225   struct adjusted_mantissa {
226   uint64_t mantissa{0}; 226   uint64_t mantissa{0};
227   int32_t power2{0}; // a negative value indicates an invalid result 227   int32_t power2{0}; // a negative value indicates an invalid result
228   adjusted_mantissa() = default; 228   adjusted_mantissa() = default;
229   constexpr bool operator==(const adjusted_mantissa &o) const { 229   constexpr bool operator==(const adjusted_mantissa &o) const {
230   return mantissa == o.mantissa && power2 == o.power2; 230   return mantissa == o.mantissa && power2 == o.power2;
231   } 231   }
HITCBC 232   1000712 constexpr bool operator!=(const adjusted_mantissa &o) const { 232   1000712 constexpr bool operator!=(const adjusted_mantissa &o) const {
HITCBC 233   1000712 return mantissa != o.mantissa || power2 != o.power2; 233   1000712 return mantissa != o.mantissa || power2 != o.power2;
234   } 234   }
235   }; 235   };
236   236  
237   // Bias so we can get the real exponent with an invalid adjusted_mantissa. 237   // Bias so we can get the real exponent with an invalid adjusted_mantissa.
238   constexpr static int32_t invalid_am_bias = -0x8000; 238   constexpr static int32_t invalid_am_bias = -0x8000;
239   239  
240   // used for binary_format_lookup_tables<T>::max_mantissa 240   // used for binary_format_lookup_tables<T>::max_mantissa
241   constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5; 241   constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5;
242   242  
243   template <typename T, typename U = void> 243   template <typename T, typename U = void>
244   struct binary_format_lookup_tables; 244   struct binary_format_lookup_tables;
245   245  
246   template <typename T> struct binary_format : binary_format_lookup_tables<T> { 246   template <typename T> struct binary_format : binary_format_lookup_tables<T> {
247   using equiv_uint = typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type; 247   using equiv_uint = typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type;
248   248  
249   static inline constexpr int mantissa_explicit_bits(); 249   static inline constexpr int mantissa_explicit_bits();
250   static inline constexpr int minimum_exponent(); 250   static inline constexpr int minimum_exponent();
251   static inline constexpr int infinite_power(); 251   static inline constexpr int infinite_power();
252   static inline constexpr int sign_index(); 252   static inline constexpr int sign_index();
253   static inline constexpr int min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST 253   static inline constexpr int min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST
254   static inline constexpr int max_exponent_fast_path(); 254   static inline constexpr int max_exponent_fast_path();
255   static inline constexpr int max_exponent_round_to_even(); 255   static inline constexpr int max_exponent_round_to_even();
256   static inline constexpr int min_exponent_round_to_even(); 256   static inline constexpr int min_exponent_round_to_even();
257   static inline constexpr uint64_t max_mantissa_fast_path(int64_t power); 257   static inline constexpr uint64_t max_mantissa_fast_path(int64_t power);
258   static inline constexpr uint64_t max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST 258   static inline constexpr uint64_t max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST
259   static inline constexpr int largest_power_of_ten(); 259   static inline constexpr int largest_power_of_ten();
260   static inline constexpr int smallest_power_of_ten(); 260   static inline constexpr int smallest_power_of_ten();
261   static inline constexpr T exact_power_of_ten(int64_t power); 261   static inline constexpr T exact_power_of_ten(int64_t power);
262   static inline constexpr size_t max_digits(); 262   static inline constexpr size_t max_digits();
263   static inline constexpr equiv_uint exponent_mask(); 263   static inline constexpr equiv_uint exponent_mask();
264   static inline constexpr equiv_uint mantissa_mask(); 264   static inline constexpr equiv_uint mantissa_mask();
265   static inline constexpr equiv_uint hidden_bit_mask(); 265   static inline constexpr equiv_uint hidden_bit_mask();
266   }; 266   };
267   267  
268   template <typename U> 268   template <typename U>
269   struct binary_format_lookup_tables<double, U> { 269   struct binary_format_lookup_tables<double, U> {
270   static constexpr double powers_of_ten[] = { 270   static constexpr double powers_of_ten[] = {
271   1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 271   1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
272   1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}; 272   1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
273   273  
274   // Largest integer value v so that (5**index * v) <= 1<<53. 274   // Largest integer value v so that (5**index * v) <= 1<<53.
275   // 0x10000000000000 == 1 << 53 275   // 0x10000000000000 == 1 << 53
276   static constexpr std::uint64_t max_mantissa[] = { 276   static constexpr std::uint64_t max_mantissa[] = {
277   UINT64_C(0x10000000000000), 277   UINT64_C(0x10000000000000),
278   UINT64_C(0x10000000000000) / UINT64_C(5), 278   UINT64_C(0x10000000000000) / UINT64_C(5),
279   UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5)), 279   UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5)),
280   UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5)), 280   UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
281   UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)), 281   UINT64_C(0x10000000000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
282   UINT64_C(0x10000000000000) / (constant_55555), 282   UINT64_C(0x10000000000000) / (constant_55555),
283   UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5)), 283   UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5)),
284   UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5)), 284   UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5)),
285   UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)), 285   UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
286   UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)), 286   UINT64_C(0x10000000000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
287   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555), 287   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555),
288   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5)), 288   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5)),
289   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)), 289   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)),
290   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)), 290   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
291   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555), 291   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555),
292   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5)), 292   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5)),
293   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)), 293   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)),
294   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)), 294   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
295   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)), 295   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
296   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555), 296   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555),
297   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5)), 297   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5)),
298   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)), 298   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5)),
299   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)), 299   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
300   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5))}; 300   UINT64_C(0x10000000000000) / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5))};
301   }; 301   };
302   302  
303   template <typename U> 303   template <typename U>
304   constexpr double binary_format_lookup_tables<double, U>::powers_of_ten[]; 304   constexpr double binary_format_lookup_tables<double, U>::powers_of_ten[];
305   305  
306   template <typename U> 306   template <typename U>
307   constexpr uint64_t binary_format_lookup_tables<double, U>::max_mantissa[]; 307   constexpr uint64_t binary_format_lookup_tables<double, U>::max_mantissa[];
308   308  
309   template <typename U> 309   template <typename U>
310   struct binary_format_lookup_tables<float, U> { 310   struct binary_format_lookup_tables<float, U> {
311   static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, 311   static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f,
312   1e6f, 1e7f, 1e8f, 1e9f, 1e10f}; 312   1e6f, 1e7f, 1e8f, 1e9f, 1e10f};
313   313  
314   // Largest integer value v so that (5**index * v) <= 1<<24. 314   // Largest integer value v so that (5**index * v) <= 1<<24.
315   // 0x1000000 == 1<<24 315   // 0x1000000 == 1<<24
316   static constexpr uint64_t max_mantissa[] = { 316   static constexpr uint64_t max_mantissa[] = {
317   UINT64_C(0x1000000), 317   UINT64_C(0x1000000),
318   UINT64_C(0x1000000) / UINT64_C(5), 318   UINT64_C(0x1000000) / UINT64_C(5),
319   UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5)), 319   UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5)),
320   UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5)), 320   UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
321   UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)), 321   UINT64_C(0x1000000) / (UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
322   UINT64_C(0x1000000) / (constant_55555), 322   UINT64_C(0x1000000) / (constant_55555),
323   UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5)), 323   UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5)),
324   UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5)), 324   UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5)),
325   UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)), 325   UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
326   UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)), 326   UINT64_C(0x1000000) / (constant_55555 * UINT64_C(5) * UINT64_C(5) * UINT64_C(5) * UINT64_C(5)),
327   UINT64_C(0x1000000) / (constant_55555 * constant_55555), 327   UINT64_C(0x1000000) / (constant_55555 * constant_55555),
328   UINT64_C(0x1000000) / (constant_55555 * constant_55555 * UINT64_C(5))}; 328   UINT64_C(0x1000000) / (constant_55555 * constant_55555 * UINT64_C(5))};
329   }; 329   };
330   330  
331   template <typename U> 331   template <typename U>
332   constexpr float binary_format_lookup_tables<float, U>::powers_of_ten[]; 332   constexpr float binary_format_lookup_tables<float, U>::powers_of_ten[];
333   333  
334   template <typename U> 334   template <typename U>
335   constexpr uint64_t binary_format_lookup_tables<float, U>::max_mantissa[]; 335   constexpr uint64_t binary_format_lookup_tables<float, U>::max_mantissa[];
336   336  
HITCBC 337   1009310 template <> inline constexpr int binary_format<double>::min_exponent_fast_path() { 337   1009310 template <> inline constexpr int binary_format<double>::min_exponent_fast_path() {
338   #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) 338   #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
339   return 0; 339   return 0;
340   #else 340   #else
HITCBC 341   1009310 return -22; 341   1009310 return -22;
342   #endif 342   #endif
343   } 343   }
344   344  
345   template <> inline constexpr int binary_format<float>::min_exponent_fast_path() { 345   template <> inline constexpr int binary_format<float>::min_exponent_fast_path() {
346   #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) 346   #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
347   return 0; 347   return 0;
348   #else 348   #else
349   return -10; 349   return -10;
350   #endif 350   #endif
351   } 351   }
352   352  
HITCBC 353   7032865 template <> inline constexpr int binary_format<double>::mantissa_explicit_bits() { 353   7032865 template <> inline constexpr int binary_format<double>::mantissa_explicit_bits() {
HITCBC 354   7032865 return 52; 354   7032865 return 52;
355   } 355   }
356   template <> inline constexpr int binary_format<float>::mantissa_explicit_bits() { 356   template <> inline constexpr int binary_format<float>::mantissa_explicit_bits() {
357   return 23; 357   return 23;
358   } 358   }
359   359  
HITCBC 360   8893 template <> inline constexpr int binary_format<double>::max_exponent_round_to_even() { 360   8893 template <> inline constexpr int binary_format<double>::max_exponent_round_to_even() {
HITCBC 361   8893 return 23; 361   8893 return 23;
362   } 362   }
363   363  
364   template <> inline constexpr int binary_format<float>::max_exponent_round_to_even() { 364   template <> inline constexpr int binary_format<float>::max_exponent_round_to_even() {
365   return 10; 365   return 10;
366   } 366   }
367   367  
HITCBC 368   9255 template <> inline constexpr int binary_format<double>::min_exponent_round_to_even() { 368   9255 template <> inline constexpr int binary_format<double>::min_exponent_round_to_even() {
HITCBC 369   9255 return -4; 369   9255 return -4;
370   } 370   }
371   371  
372   template <> inline constexpr int binary_format<float>::min_exponent_round_to_even() { 372   template <> inline constexpr int binary_format<float>::min_exponent_round_to_even() {
373   return -17; 373   return -17;
374   } 374   }
375   375  
HITCBC 376   2002893 template <> inline constexpr int binary_format<double>::minimum_exponent() { 376   2002893 template <> inline constexpr int binary_format<double>::minimum_exponent() {
HITCBC 377   2002893 return -1023; 377   2002893 return -1023;
378   } 378   }
379   template <> inline constexpr int binary_format<float>::minimum_exponent() { 379   template <> inline constexpr int binary_format<float>::minimum_exponent() {
380   return -127; 380   return -127;
381   } 381   }
382   382  
HITCBC 383   3072364 template <> inline constexpr int binary_format<double>::infinite_power() { 383   3072364 template <> inline constexpr int binary_format<double>::infinite_power() {
HITCBC 384   3072364 return 0x7FF; 384   3072364 return 0x7FF;
385   } 385   }
386   template <> inline constexpr int binary_format<float>::infinite_power() { 386   template <> inline constexpr int binary_format<float>::infinite_power() {
387   return 0xFF; 387   return 0xFF;
388   } 388   }
389   389  
HITCBC 390   1005351 template <> inline constexpr int binary_format<double>::sign_index() { return 63; } 390   1005351 template <> inline constexpr int binary_format<double>::sign_index() { return 63; }
391   template <> inline constexpr int binary_format<float>::sign_index() { return 31; } 391   template <> inline constexpr int binary_format<float>::sign_index() { return 31; }
392   392  
HITCBC 393   546058 template <> inline constexpr int binary_format<double>::max_exponent_fast_path() { 393   546058 template <> inline constexpr int binary_format<double>::max_exponent_fast_path() {
HITCBC 394   546058 return 22; 394   546058 return 22;
395   } 395   }
396   template <> inline constexpr int binary_format<float>::max_exponent_fast_path() { 396   template <> inline constexpr int binary_format<float>::max_exponent_fast_path() {
397   return 10; 397   return 10;
398   } 398   }
399   399  
HITCBC 400   5895 template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() { 400   5895 template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() {
HITCBC 401   5895 return uint64_t(2) << mantissa_explicit_bits(); 401   5895 return uint64_t(2) << mantissa_explicit_bits();
402   } 402   }
MISUBC 403   template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path(int64_t power) { 403   template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path(int64_t power) {
404   // caller is responsible to ensure that 404   // caller is responsible to ensure that
405   // power >= 0 && power <= 22 405   // power >= 0 && power <= 22
406   // 406   //
407   // Work around clang bug https://godbolt.org/z/zedh7rrhc 407   // Work around clang bug https://godbolt.org/z/zedh7rrhc
MISUBC 408   return (void)max_mantissa[0], max_mantissa[power]; 408   return (void)max_mantissa[0], max_mantissa[power];
409   } 409   }
410   template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() { 410   template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
411   return uint64_t(2) << mantissa_explicit_bits(); 411   return uint64_t(2) << mantissa_explicit_bits();
412   } 412   }
413   template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path(int64_t power) { 413   template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path(int64_t power) {
414   // caller is responsible to ensure that 414   // caller is responsible to ensure that
415   // power >= 0 && power <= 10 415   // power >= 0 && power <= 10
416   // 416   //
417   // Work around clang bug https://godbolt.org/z/zedh7rrhc 417   // Work around clang bug https://godbolt.org/z/zedh7rrhc
418   return (void)max_mantissa[0], max_mantissa[power]; 418   return (void)max_mantissa[0], max_mantissa[power];
419   } 419   }
420   420  
421   template <> 421   template <>
HITCBC 422   5570 inline constexpr double binary_format<double>::exact_power_of_ten(int64_t power) { 422   5570 inline constexpr double binary_format<double>::exact_power_of_ten(int64_t power) {
423   // Work around clang bug https://godbolt.org/z/zedh7rrhc 423   // Work around clang bug https://godbolt.org/z/zedh7rrhc
HITCBC 424   5570 return (void)powers_of_ten[0], powers_of_ten[power]; 424   5570 return (void)powers_of_ten[0], powers_of_ten[power];
425   } 425   }
426   template <> 426   template <>
427   inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) { 427   inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
428   // Work around clang bug https://godbolt.org/z/zedh7rrhc 428   // Work around clang bug https://godbolt.org/z/zedh7rrhc
429   return (void)powers_of_ten[0], powers_of_ten[power]; 429   return (void)powers_of_ten[0], powers_of_ten[power];
430   } 430   }
431   431  
432   432  
433   template <> 433   template <>
HITCBC 434   2004451 inline constexpr int binary_format<double>::largest_power_of_ten() { 434   2004451 inline constexpr int binary_format<double>::largest_power_of_ten() {
HITCBC 435   2004451 return 308; 435   2004451 return 308;
436   } 436   }
437   template <> 437   template <>
438   inline constexpr int binary_format<float>::largest_power_of_ten() { 438   inline constexpr int binary_format<float>::largest_power_of_ten() {
439   return 38; 439   return 38;
440   } 440   }
441   441  
442   template <> 442   template <>
HITCBC 443   2004451 inline constexpr int binary_format<double>::smallest_power_of_ten() { 443   2004451 inline constexpr int binary_format<double>::smallest_power_of_ten() {
HITCBC 444   2004451 return -342; 444   2004451 return -342;
445   } 445   }
446   template <> 446   template <>
447   inline constexpr int binary_format<float>::smallest_power_of_ten() { 447   inline constexpr int binary_format<float>::smallest_power_of_ten() {
448   return -65; 448   return -65;
449   } 449   }
450   450  
451   template <> inline constexpr size_t binary_format<double>::max_digits() { 451   template <> inline constexpr size_t binary_format<double>::max_digits() {
452   return 769; 452   return 769;
453   } 453   }
454   template <> inline constexpr size_t binary_format<float>::max_digits() { 454   template <> inline constexpr size_t binary_format<float>::max_digits() {
455   return 114; 455   return 114;
456   } 456   }
457   457  
458   template <> inline constexpr binary_format<float>::equiv_uint 458   template <> inline constexpr binary_format<float>::equiv_uint
459   binary_format<float>::exponent_mask() { 459   binary_format<float>::exponent_mask() {
460   return 0x7F800000; 460   return 0x7F800000;
461   } 461   }
462   template <> inline constexpr binary_format<double>::equiv_uint 462   template <> inline constexpr binary_format<double>::equiv_uint
463   binary_format<double>::exponent_mask() { 463   binary_format<double>::exponent_mask() {
464   return 0x7FF0000000000000; 464   return 0x7FF0000000000000;
465   } 465   }
466   466  
467   template <> inline constexpr binary_format<float>::equiv_uint 467   template <> inline constexpr binary_format<float>::equiv_uint
468   binary_format<float>::mantissa_mask() { 468   binary_format<float>::mantissa_mask() {
469   return 0x007FFFFF; 469   return 0x007FFFFF;
470   } 470   }
471   template <> inline constexpr binary_format<double>::equiv_uint 471   template <> inline constexpr binary_format<double>::equiv_uint
472   binary_format<double>::mantissa_mask() { 472   binary_format<double>::mantissa_mask() {
473   return 0x000FFFFFFFFFFFFF; 473   return 0x000FFFFFFFFFFFFF;
474   } 474   }
475   475  
476   template <> inline constexpr binary_format<float>::equiv_uint 476   template <> inline constexpr binary_format<float>::equiv_uint
477   binary_format<float>::hidden_bit_mask() { 477   binary_format<float>::hidden_bit_mask() {
478   return 0x00800000; 478   return 0x00800000;
479   } 479   }
480   template <> inline constexpr binary_format<double>::equiv_uint 480   template <> inline constexpr binary_format<double>::equiv_uint
481   binary_format<double>::hidden_bit_mask() { 481   binary_format<double>::hidden_bit_mask() {
482   return 0x0010000000000000; 482   return 0x0010000000000000;
483   } 483   }
484   484  
485   template<typename T> 485   template<typename T>
486   BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20 486   BOOST_FORCEINLINE BOOST_JSON_FASTFLOAT_CONSTEXPR20
487   void to_float(bool negative, adjusted_mantissa am, T &value) { 487   void to_float(bool negative, adjusted_mantissa am, T &value) {
488   using uint = typename binary_format<T>::equiv_uint; 488   using uint = typename binary_format<T>::equiv_uint;
HITCBC 489   1005351 uint word = (uint)am.mantissa; 489   1005351 uint word = (uint)am.mantissa;
HITCBC 490   1005351 word |= uint(am.power2) << binary_format<T>::mantissa_explicit_bits(); 490   1005351 word |= uint(am.power2) << binary_format<T>::mantissa_explicit_bits();
HITCBC 491   1005351 word |= uint(negative) << binary_format<T>::sign_index(); 491   1005351 word |= uint(negative) << binary_format<T>::sign_index();
492   #ifdef BOOST_JSON_HAS_BIT_CAST 492   #ifdef BOOST_JSON_HAS_BIT_CAST
493   value = std::bit_cast<T>(word); 493   value = std::bit_cast<T>(word);
494   #else 494   #else
HITCBC 495   1005351 ::memcpy(&value, &word, sizeof(T)); 495   1005351 ::memcpy(&value, &word, sizeof(T));
496   #endif 496   #endif
HITCBC 497   1005351 } 497   1005351 }
498   498  
499   template<typename UC> 499   template<typename UC>
HITCBC 500   2986 static constexpr uint64_t int_cmp_zeros() 500   2986 static constexpr uint64_t int_cmp_zeros()
501   { 501   {
502   static_assert((sizeof(UC) == 1) || (sizeof(UC) == 2) || (sizeof(UC) == 4), "Unsupported character size"); 502   static_assert((sizeof(UC) == 1) || (sizeof(UC) == 2) || (sizeof(UC) == 4), "Unsupported character size");
HITCBC 503   2986 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')); 503   2986 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'));
504   } 504   }
505   template<typename UC> 505   template<typename UC>
HITCBC 506   2986 static constexpr int int_cmp_len() 506   2986 static constexpr int int_cmp_len()
507   { 507   {
HITCBC 508   2986 return sizeof(uint64_t) / sizeof(UC); 508   2986 return sizeof(uint64_t) / sizeof(UC);
509   } 509   }
510   template<typename UC> 510   template<typename UC>
511   static constexpr UC const * str_const_nan() 511   static constexpr UC const * str_const_nan()
512   { 512   {
513   return nullptr; 513   return nullptr;
514   } 514   }
515   template<> 515   template<>
MISUBC 516   constexpr char const * str_const_nan<char>() 516   constexpr char const * str_const_nan<char>()
517   { 517   {
MISUBC 518   return "nan"; 518   return "nan";
519   } 519   }
520   template<> 520   template<>
521   constexpr wchar_t const * str_const_nan<wchar_t>() 521   constexpr wchar_t const * str_const_nan<wchar_t>()
522   { 522   {
523   return L"nan"; 523   return L"nan";
524   } 524   }
525   template<> 525   template<>
526   constexpr char16_t const * str_const_nan<char16_t>() 526   constexpr char16_t const * str_const_nan<char16_t>()
527   { 527   {
528   return u"nan"; 528   return u"nan";
529   } 529   }
530   template<> 530   template<>
531   constexpr char32_t const * str_const_nan<char32_t>() 531   constexpr char32_t const * str_const_nan<char32_t>()
532   { 532   {
533   return U"nan"; 533   return U"nan";
534   } 534   }
535   template<typename UC> 535   template<typename UC>
536   static constexpr UC const * str_const_inf() 536   static constexpr UC const * str_const_inf()
537   { 537   {
538   return nullptr; 538   return nullptr;
539   } 539   }
540   template<> 540   template<>
MISUBC 541   constexpr char const * str_const_inf<char>() 541   constexpr char const * str_const_inf<char>()
542   { 542   {
MISUBC 543   return "infinity"; 543   return "infinity";
544   } 544   }
545   template<> 545   template<>
546   constexpr wchar_t const * str_const_inf<wchar_t>() 546   constexpr wchar_t const * str_const_inf<wchar_t>()
547   { 547   {
548   return L"infinity"; 548   return L"infinity";
549   } 549   }
550   template<> 550   template<>
551   constexpr char16_t const * str_const_inf<char16_t>() 551   constexpr char16_t const * str_const_inf<char16_t>()
552   { 552   {
553   return u"infinity"; 553   return u"infinity";
554   } 554   }
555   template<> 555   template<>
556   constexpr char32_t const * str_const_inf<char32_t>() 556   constexpr char32_t const * str_const_inf<char32_t>()
557   { 557   {
558   return U"infinity"; 558   return U"infinity";
559   } 559   }
560   560  
561   }}}}}} // namespaces 561   }}}}}} // namespaces
562   562  
563   #endif 563   #endif