LCOV - code coverage report
Current view: top level - third_party/fast_float - float_common.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 54 82 65.9 %
Date: 2024-05-14 23:54:21 Functions: 19 26 73.1 %

          Line data    Source code
       1             : #ifndef FASTFLOAT_FLOAT_COMMON_H
       2             : #define FASTFLOAT_FLOAT_COMMON_H
       3             : 
       4             : #include <cfloat>
       5             : #include <cstdint>
       6             : #include <cassert>
       7             : #include <cstring>
       8             : #include <type_traits>
       9             : #include <system_error>
      10             : 
      11             : #include "constexpr_feature_detect.h"
      12             : 
      13             : namespace fast_float {
      14             : 
      15             : #define FASTFLOAT_JSONFMT (1 << 5)
      16             : #define FASTFLOAT_FORTRANFMT (1 << 6)
      17             : 
      18             : enum chars_format {
      19             :   scientific = 1 << 0,
      20             :   fixed = 1 << 2,
      21             :   hex = 1 << 3,
      22             :   no_infnan = 1 << 4,
      23             :   // RFC 8259: https://datatracker.ietf.org/doc/html/rfc8259#section-6
      24             :   json = FASTFLOAT_JSONFMT | fixed | scientific | no_infnan,
      25             :   // Extension of RFC 8259 where, e.g., "inf" and "nan" are allowed.
      26             :   json_or_infnan = FASTFLOAT_JSONFMT | fixed | scientific,
      27             :   fortran = FASTFLOAT_FORTRANFMT | fixed | scientific,
      28             :   general = fixed | scientific
      29             : };
      30             : 
      31             : template <typename UC>
      32             : struct from_chars_result_t {
      33             :   UC const* ptr;
      34             :   std::errc ec;
      35             : };
      36             : using from_chars_result = from_chars_result_t<char>;
      37             : 
      38             : template <typename UC>
      39             : struct parse_options_t {
      40     7463760 :   constexpr explicit parse_options_t(chars_format fmt = chars_format::general,
      41             :     UC dot = UC('.'))
      42     7463760 :     : format(fmt), decimal_point(dot) {}
      43             : 
      44             :   /** Which number formats are accepted */
      45             :   chars_format format;
      46             :   /** The character used as decimal point */
      47             :   UC decimal_point;
      48             : };
      49             : using parse_options = parse_options_t<char>;
      50             : 
      51             : }
      52             : 
      53             : #if FASTFLOAT_HAS_BIT_CAST
      54             : #include <bit>
      55             : #endif
      56             : 
      57             : #if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)   \
      58             :        || defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) \
      59             :        || defined(__MINGW64__)                                          \
      60             :        || defined(__s390x__)                                            \
      61             :        || (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) \
      62             :        || defined(__loongarch64) )
      63             : #define FASTFLOAT_64BIT 1
      64             : #elif (defined(__i386) || defined(__i386__) || defined(_M_IX86)   \
      65             :      || defined(__arm__) || defined(_M_ARM) || defined(__ppc__)   \
      66             :      || defined(__MINGW32__) || defined(__EMSCRIPTEN__))
      67             : #define FASTFLOAT_32BIT 1
      68             : #else
      69             :   // Need to check incrementally, since SIZE_MAX is a size_t, avoid overflow.
      70             :   // We can never tell the register width, but the SIZE_MAX is a good approximation.
      71             :   // UINTPTR_MAX and INTPTR_MAX are optional, so avoid them for max portability.
      72             :   #if SIZE_MAX == 0xffff
      73             :     #error Unknown platform (16-bit, unsupported)
      74             :   #elif SIZE_MAX == 0xffffffff
      75             :     #define FASTFLOAT_32BIT 1
      76             :   #elif SIZE_MAX == 0xffffffffffffffff
      77             :     #define FASTFLOAT_64BIT 1
      78             :   #else
      79             :     #error Unknown platform (not 32-bit, not 64-bit?)
      80             :   #endif
      81             : #endif
      82             : 
      83             : #if ((defined(_WIN32) || defined(_WIN64)) && !defined(__clang__))
      84             : #include <intrin.h>
      85             : #endif
      86             : 
      87             : #if defined(_MSC_VER) && !defined(__clang__)
      88             : #define FASTFLOAT_VISUAL_STUDIO 1
      89             : #endif
      90             : 
      91             : #if defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__
      92             : #define FASTFLOAT_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
      93             : #elif defined _WIN32
      94             : #define FASTFLOAT_IS_BIG_ENDIAN 0
      95             : #else
      96             : #if defined(__APPLE__) || defined(__FreeBSD__)
      97             : #include <machine/endian.h>
      98             : #elif defined(sun) || defined(__sun)
      99             : #include <sys/byteorder.h>
     100             : #elif defined(__MVS__)
     101             : #include <sys/endian.h>
     102             : #else
     103             : #ifdef __has_include
     104             : #if __has_include(<endian.h>)
     105             : #include <endian.h>
     106             : #endif //__has_include(<endian.h>)
     107             : #endif //__has_include
     108             : #endif
     109             : #
     110             : #ifndef __BYTE_ORDER__
     111             : // safe choice
     112             : #define FASTFLOAT_IS_BIG_ENDIAN 0
     113             : #endif
     114             : #
     115             : #ifndef __ORDER_LITTLE_ENDIAN__
     116             : // safe choice
     117             : #define FASTFLOAT_IS_BIG_ENDIAN 0
     118             : #endif
     119             : #
     120             : #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     121             : #define FASTFLOAT_IS_BIG_ENDIAN 0
     122             : #else
     123             : #define FASTFLOAT_IS_BIG_ENDIAN 1
     124             : #endif
     125             : #endif
     126             : 
     127             : #if defined(__SSE2__) || \
     128             :   (defined(FASTFLOAT_VISUAL_STUDIO) && \
     129             :     (defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP == 2)))
     130             : #define FASTFLOAT_SSE2 1
     131             : #endif
     132             : 
     133             : #if defined(__aarch64__) || defined(_M_ARM64)
     134             : #define FASTFLOAT_NEON 1
     135             : #endif
     136             : 
     137             : #if defined(FASTFLOAT_SSE2) || defined(FASTFLOAT_ARM64)
     138             : #define FASTFLOAT_HAS_SIMD 1
     139             : #endif
     140             : 
     141             : #if defined(__GNUC__)
     142             : // disable -Wcast-align=strict (GCC only)
     143             : #define FASTFLOAT_SIMD_DISABLE_WARNINGS \
     144             :   _Pragma("GCC diagnostic push") \
     145             :   _Pragma("GCC diagnostic ignored \"-Wcast-align\"")
     146             : #else
     147             : #define FASTFLOAT_SIMD_DISABLE_WARNINGS
     148             : #endif
     149             : 
     150             : #if defined(__GNUC__)
     151             : #define FASTFLOAT_SIMD_RESTORE_WARNINGS \
     152             :   _Pragma("GCC diagnostic pop")
     153             : #else
     154             : #define FASTFLOAT_SIMD_RESTORE_WARNINGS
     155             : #endif
     156             : 
     157             : 
     158             : 
     159             : #ifdef FASTFLOAT_VISUAL_STUDIO
     160             : #define fastfloat_really_inline __forceinline
     161             : #else
     162             : #define fastfloat_really_inline inline __attribute__((always_inline))
     163             : #endif
     164             : 
     165             : #ifndef FASTFLOAT_ASSERT
     166             : #define FASTFLOAT_ASSERT(x)  { ((void)(x)); }
     167             : #endif
     168             : 
     169             : #ifndef FASTFLOAT_DEBUG_ASSERT
     170             : #define FASTFLOAT_DEBUG_ASSERT(x) { ((void)(x)); }
     171             : #endif
     172             : 
     173             : // rust style `try!()` macro, or `?` operator
     174             : #define FASTFLOAT_TRY(x) { if (!(x)) return false; }
     175             : 
     176             : #define FASTFLOAT_ENABLE_IF(...) typename std::enable_if<(__VA_ARGS__), int>::type = 0
     177             : 
     178             : 
     179             : namespace fast_float {
     180             : 
     181             : fastfloat_really_inline constexpr bool cpp20_and_in_constexpr() {
     182             : #if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED
     183             :   return std::is_constant_evaluated();
     184             : #else
     185     9187190 :   return false;
     186             : #endif
     187             : }
     188             : 
     189             : // Compares two ASCII strings in a case insensitive manner.
     190             : template <typename UC>
     191             : inline FASTFLOAT_CONSTEXPR14 bool
     192          10 : fastfloat_strncasecmp(UC const * input1, UC const * input2, size_t length) {
     193          10 :   char running_diff{0};
     194          40 :   for (size_t i = 0; i < length; ++i) {
     195          30 :     running_diff |= (char(input1[i]) ^ char(input2[i]));
     196             :   }
     197          10 :   return (running_diff == 0) || (running_diff == 32);
     198             : }
     199             : 
     200             : #ifndef FLT_EVAL_METHOD
     201             : #error "FLT_EVAL_METHOD should be defined, please include cfloat."
     202             : #endif
     203             : 
     204             : // a pointer and a length to a contiguous block of memory
     205             : template <typename T>
     206             : struct span {
     207             :   const T* ptr;
     208             :   size_t length;
     209    13738100 :   constexpr span(const T* _ptr, size_t _length) : ptr(_ptr), length(_length) {}
     210             :   constexpr span() : ptr(nullptr), length(0) {}
     211             : 
     212      125032 :   constexpr size_t len() const noexcept {
     213      125032 :     return length;
     214             :   }
     215             : 
     216           0 :   FASTFLOAT_CONSTEXPR14 const T& operator[](size_t index) const noexcept {
     217             :     FASTFLOAT_DEBUG_ASSERT(index < length);
     218           0 :     return ptr[index];
     219             :   }
     220             : };
     221             : 
     222             : struct value128 {
     223             :   uint64_t low;
     224             :   uint64_t high;
     225             :   constexpr value128(uint64_t _low, uint64_t _high) : low(_low), high(_high) {}
     226             :   constexpr value128() : low(0), high(0) {}
     227             : };
     228             : 
     229             : /* Helper C++14 constexpr generic implementation of leading_zeroes */
     230             : fastfloat_really_inline FASTFLOAT_CONSTEXPR14
     231             : int leading_zeroes_generic(uint64_t input_num, int last_bit = 0) {
     232           0 :     if(input_num & uint64_t(0xffffffff00000000)) { input_num >>= 32; last_bit |= 32; }
     233           0 :     if(input_num & uint64_t(        0xffff0000)) { input_num >>= 16; last_bit |= 16; }
     234           0 :     if(input_num & uint64_t(            0xff00)) { input_num >>=  8; last_bit |=  8; }
     235           0 :     if(input_num & uint64_t(              0xf0)) { input_num >>=  4; last_bit |=  4; }
     236           0 :     if(input_num & uint64_t(               0xc)) { input_num >>=  2; last_bit |=  2; }
     237           0 :     if(input_num & uint64_t(               0x2)) { input_num >>=  1; last_bit |=  1; }
     238           0 :     return 63 - last_bit;
     239             : }
     240             : 
     241             : /* result might be undefined when input_num is zero */
     242             : fastfloat_really_inline FASTFLOAT_CONSTEXPR20
     243             : int leading_zeroes(uint64_t input_num) {
     244      329159 :   assert(input_num > 0);
     245      329159 :   if (cpp20_and_in_constexpr()) {
     246           0 :     return leading_zeroes_generic(input_num);
     247             :   }
     248             : #ifdef FASTFLOAT_VISUAL_STUDIO
     249             :   #if defined(_M_X64) || defined(_M_ARM64)
     250             :   unsigned long leading_zero = 0;
     251             :   // Search the mask data from most significant bit (MSB)
     252             :   // to least significant bit (LSB) for a set bit (1).
     253             :   _BitScanReverse64(&leading_zero, input_num);
     254             :   return (int)(63 - leading_zero);
     255             :   #else
     256             :   return leading_zeroes_generic(input_num);
     257             :   #endif
     258             : #else
     259      329159 :   return __builtin_clzll(input_num);
     260             : #endif
     261             : }
     262             : 
     263             : // slow emulation routine for 32-bit
     264             : fastfloat_really_inline constexpr uint64_t emulu(uint32_t x, uint32_t y) {
     265           0 :     return x * (uint64_t)y;
     266             : }
     267             : 
     268             : fastfloat_really_inline FASTFLOAT_CONSTEXPR14
     269             : uint64_t umul128_generic(uint64_t ab, uint64_t cd, uint64_t *hi) {
     270           0 :   uint64_t ad = emulu((uint32_t)(ab >> 32), (uint32_t)cd);
     271           0 :   uint64_t bd = emulu((uint32_t)ab, (uint32_t)cd);
     272           0 :   uint64_t adbc = ad + emulu((uint32_t)ab, (uint32_t)(cd >> 32));
     273           0 :   uint64_t adbc_carry = !!(adbc < ad);
     274           0 :   uint64_t lo = bd + (adbc << 32);
     275           0 :   *hi = emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) +
     276           0 :         (adbc_carry << 32) + !!(lo < bd);
     277           0 :   return lo;
     278             : }
     279             : 
     280             : #ifdef FASTFLOAT_32BIT
     281             : 
     282             : // slow emulation routine for 32-bit
     283             : #if !defined(__MINGW64__)
     284             : fastfloat_really_inline FASTFLOAT_CONSTEXPR14
     285             : uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) {
     286             :   return umul128_generic(ab, cd, hi);
     287             : }
     288             : #endif // !__MINGW64__
     289             : 
     290             : #endif // FASTFLOAT_32BIT
     291             : 
     292             : 
     293             : // compute 64-bit a*b
     294             : fastfloat_really_inline FASTFLOAT_CONSTEXPR20
     295             : value128 full_multiplication(uint64_t a, uint64_t b) {
     296      370803 :   if (cpp20_and_in_constexpr()) {
     297           0 :     value128 answer;
     298           0 :     answer.low = umul128_generic(a, b, &answer.high);
     299           0 :     return answer;
     300             :   }
     301      370803 :   value128 answer;
     302             : #if defined(_M_ARM64) && !defined(__MINGW32__)
     303             :   // ARM64 has native support for 64-bit multiplications, no need to emulate
     304             :   // But MinGW on ARM64 doesn't have native support for 64-bit multiplications
     305             :   answer.high = __umulh(a, b);
     306             :   answer.low = a * b;
     307             : #elif defined(FASTFLOAT_32BIT) || (defined(_WIN64) && !defined(__clang__))
     308             :   answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64
     309             : #elif defined(FASTFLOAT_64BIT)
     310      370803 :   __uint128_t r = ((__uint128_t)a) * b;
     311      370803 :   answer.low = uint64_t(r);
     312      370803 :   answer.high = uint64_t(r >> 64);
     313             : #else
     314             :   answer.low = umul128_generic(a, b, &answer.high);
     315             : #endif
     316      370803 :   return answer;
     317             : }
     318             : 
     319             : struct adjusted_mantissa {
     320             :   uint64_t mantissa{0};
     321             :   int32_t power2{0}; // a negative value indicates an invalid result
     322             :   adjusted_mantissa() = default;
     323             :   constexpr bool operator==(const adjusted_mantissa &o) const {
     324             :     return mantissa == o.mantissa && power2 == o.power2;
     325             :   }
     326       62516 :   constexpr bool operator!=(const adjusted_mantissa &o) const {
     327       62516 :     return mantissa != o.mantissa || power2 != o.power2;
     328             :   }
     329             : };
     330             : 
     331             : // Bias so we can get the real exponent with an invalid adjusted_mantissa.
     332             : constexpr static int32_t invalid_am_bias = -0x8000;
     333             : 
     334             : // used for binary_format_lookup_tables<T>::max_mantissa
     335             : constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5;
     336             : 
     337             : template <typename T, typename U = void>
     338             : struct binary_format_lookup_tables;
     339             : 
     340             : template <typename T> struct binary_format : binary_format_lookup_tables<T> {
     341             :   using equiv_uint = typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type;
     342             : 
     343             :   static inline constexpr int mantissa_explicit_bits();
     344             :   static inline constexpr int minimum_exponent();
     345             :   static inline constexpr int infinite_power();
     346             :   static inline constexpr int sign_index();
     347             :   static inline constexpr int min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST
     348             :   static inline constexpr int max_exponent_fast_path();
     349             :   static inline constexpr int max_exponent_round_to_even();
     350             :   static inline constexpr int min_exponent_round_to_even();
     351             :   static inline constexpr uint64_t max_mantissa_fast_path(int64_t power);
     352             :   static inline constexpr uint64_t max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST
     353             :   static inline constexpr int largest_power_of_ten();
     354             :   static inline constexpr int smallest_power_of_ten();
     355             :   static inline constexpr T exact_power_of_ten(int64_t power);
     356             :   static inline constexpr size_t max_digits();
     357             :   static inline constexpr equiv_uint exponent_mask();
     358             :   static inline constexpr equiv_uint mantissa_mask();
     359             :   static inline constexpr equiv_uint hidden_bit_mask();
     360             : };
     361             : 
     362             : template <typename U>
     363             : struct binary_format_lookup_tables<double, U> {
     364             :   static constexpr double powers_of_ten[] = {
     365             :       1e0,  1e1,  1e2,  1e3,  1e4,  1e5,  1e6,  1e7,  1e8,  1e9,  1e10, 1e11,
     366             :       1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
     367             : 
     368             :   // Largest integer value v so that (5**index * v) <= 1<<53.
     369             :   // 0x10000000000000 == 1 << 53
     370             :   static constexpr uint64_t max_mantissa[] = {
     371             :       0x10000000000000,
     372             :       0x10000000000000 / 5,
     373             :       0x10000000000000 / (5 * 5),
     374             :       0x10000000000000 / (5 * 5 * 5),
     375             :       0x10000000000000 / (5 * 5 * 5 * 5),
     376             :       0x10000000000000 / (constant_55555),
     377             :       0x10000000000000 / (constant_55555 * 5),
     378             :       0x10000000000000 / (constant_55555 * 5 * 5),
     379             :       0x10000000000000 / (constant_55555 * 5 * 5 * 5),
     380             :       0x10000000000000 / (constant_55555 * 5 * 5 * 5 * 5),
     381             :       0x10000000000000 / (constant_55555 * constant_55555),
     382             :       0x10000000000000 / (constant_55555 * constant_55555 * 5),
     383             :       0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5),
     384             :       0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5 * 5),
     385             :       0x10000000000000 / (constant_55555 * constant_55555 * constant_55555),
     386             :       0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5),
     387             :       0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5),
     388             :       0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5),
     389             :       0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5),
     390             :       0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555),
     391             :       0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5),
     392             :       0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5),
     393             :       0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5),
     394             :       0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5)};
     395             : };
     396             : 
     397             : template <typename U>
     398             : constexpr double binary_format_lookup_tables<double, U>::powers_of_ten[];
     399             : 
     400             : template <typename U>
     401             : constexpr uint64_t binary_format_lookup_tables<double, U>::max_mantissa[];
     402             : 
     403             : template <typename U>
     404             : struct binary_format_lookup_tables<float, U> {
     405             :   static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f,
     406             :                                      1e6f, 1e7f, 1e8f, 1e9f, 1e10f};
     407             : 
     408             :   // Largest integer value v so that (5**index * v) <= 1<<24.
     409             :   // 0x1000000 == 1<<24
     410             :   static constexpr uint64_t max_mantissa[] = {
     411             :         0x1000000,
     412             :         0x1000000 / 5,
     413             :         0x1000000 / (5 * 5),
     414             :         0x1000000 / (5 * 5 * 5),
     415             :         0x1000000 / (5 * 5 * 5 * 5),
     416             :         0x1000000 / (constant_55555),
     417             :         0x1000000 / (constant_55555 * 5),
     418             :         0x1000000 / (constant_55555 * 5 * 5),
     419             :         0x1000000 / (constant_55555 * 5 * 5 * 5),
     420             :         0x1000000 / (constant_55555 * 5 * 5 * 5 * 5),
     421             :         0x1000000 / (constant_55555 * constant_55555),
     422             :         0x1000000 / (constant_55555 * constant_55555 * 5)};
     423             : };
     424             : 
     425             : template <typename U>
     426             : constexpr float binary_format_lookup_tables<float, U>::powers_of_ten[];
     427             : 
     428             : template <typename U>
     429             : constexpr uint64_t binary_format_lookup_tables<float, U>::max_mantissa[];
     430             : 
     431     7422650 : template <> inline constexpr int binary_format<double>::min_exponent_fast_path() {
     432             : #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
     433             :   return 0;
     434             : #else
     435     7422650 :   return -22;
     436             : #endif
     437             : }
     438             : 
     439             : template <> inline constexpr int binary_format<float>::min_exponent_fast_path() {
     440             : #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
     441             :   return 0;
     442             : #else
     443             :   return -10;
     444             : #endif
     445             : }
     446             : 
     447     8613050 : template <> inline constexpr int binary_format<double>::mantissa_explicit_bits() {
     448     8613050 :   return 52;
     449             : }
     450             : template <> inline constexpr int binary_format<float>::mantissa_explicit_bits() {
     451             :   return 23;
     452             : }
     453             : 
     454          88 : template <> inline constexpr int binary_format<double>::max_exponent_round_to_even() {
     455          88 :   return 23;
     456             : }
     457             : 
     458             : template <> inline constexpr int binary_format<float>::max_exponent_round_to_even() {
     459             :   return 10;
     460             : }
     461             : 
     462       15118 : template <> inline constexpr int binary_format<double>::min_exponent_round_to_even() {
     463       15118 :   return -4;
     464             : }
     465             : 
     466             : template <> inline constexpr int binary_format<float>::min_exponent_round_to_even() {
     467             :   return -17;
     468             : }
     469             : 
     470      329159 : template <> inline constexpr int binary_format<double>::minimum_exponent() {
     471      329159 :   return -1023;
     472             : }
     473             : template <> inline constexpr int binary_format<float>::minimum_exponent() {
     474             :   return -127;
     475             : }
     476             : 
     477      595797 : template <> inline constexpr int binary_format<double>::infinite_power() {
     478      595797 :   return 0x7FF;
     479             : }
     480             : template <> inline constexpr int binary_format<float>::infinite_power() {
     481             :   return 0xFF;
     482             : }
     483             : 
     484      266645 : template <> inline constexpr int binary_format<double>::sign_index() { return 63; }
     485             : template <> inline constexpr int binary_format<float>::sign_index() { return 31; }
     486             : 
     487     7421600 : template <> inline constexpr int binary_format<double>::max_exponent_fast_path() {
     488     7421600 :   return 22;
     489             : }
     490             : template <> inline constexpr int binary_format<float>::max_exponent_fast_path() {
     491             :   return 10;
     492             : }
     493             : 
     494     7358940 : template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() {
     495     7358940 :   return uint64_t(2) << mantissa_explicit_bits();
     496             : }
     497           0 : template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path(int64_t power) {
     498             :   // caller is responsible to ensure that
     499             :   // power >= 0 && power <= 22
     500             :   //
     501             :   // Work around clang bug https://godbolt.org/z/zedh7rrhc
     502           0 :   return (void)max_mantissa[0], max_mantissa[power];
     503             : }
     504             : template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
     505             :   return uint64_t(2) << mantissa_explicit_bits();
     506             : }
     507             : template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path(int64_t power) {
     508             :   // caller is responsible to ensure that
     509             :   // power >= 0 && power <= 10
     510             :   //
     511             :   // Work around clang bug https://godbolt.org/z/zedh7rrhc
     512             :   return (void)max_mantissa[0], max_mantissa[power];
     513             : }
     514             : 
     515             : template <>
     516     7156000 : inline constexpr double binary_format<double>::exact_power_of_ten(int64_t power) {
     517             :   // Work around clang bug https://godbolt.org/z/zedh7rrhc
     518     7156000 :   return (void)powers_of_ten[0], powers_of_ten[power];
     519             : }
     520             : template <>
     521             : inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
     522             :   // Work around clang bug https://godbolt.org/z/zedh7rrhc
     523             :   return (void)powers_of_ten[0], powers_of_ten[power];
     524             : }
     525             : 
     526             : 
     527             : template <>
     528      329161 : inline constexpr int binary_format<double>::largest_power_of_ten() {
     529      329161 :   return 308;
     530             : }
     531             : template <>
     532             : inline constexpr int binary_format<float>::largest_power_of_ten() {
     533             :   return 38;
     534             : }
     535             : 
     536             : template <>
     537      329161 : inline constexpr int binary_format<double>::smallest_power_of_ten() {
     538      329161 :   return -342;
     539             : }
     540             : template <>
     541             : inline constexpr int binary_format<float>::smallest_power_of_ten() {
     542             :   return -65;
     543             : }
     544             : 
     545             : template <> inline constexpr size_t binary_format<double>::max_digits() {
     546             :   return 769;
     547             : }
     548             : template <> inline constexpr size_t binary_format<float>::max_digits() {
     549             :   return 114;
     550             : }
     551             : 
     552             : template <> inline constexpr binary_format<float>::equiv_uint
     553             :     binary_format<float>::exponent_mask() {
     554             :   return 0x7F800000;
     555             : }
     556             : template <> inline constexpr binary_format<double>::equiv_uint
     557             :     binary_format<double>::exponent_mask() {
     558             :   return 0x7FF0000000000000;
     559             : }
     560             : 
     561             : template <> inline constexpr binary_format<float>::equiv_uint
     562             :     binary_format<float>::mantissa_mask() {
     563             :   return 0x007FFFFF;
     564             : }
     565             : template <> inline constexpr binary_format<double>::equiv_uint
     566             :     binary_format<double>::mantissa_mask() {
     567             :   return 0x000FFFFFFFFFFFFF;
     568             : }
     569             : 
     570             : template <> inline constexpr binary_format<float>::equiv_uint
     571             :     binary_format<float>::hidden_bit_mask() {
     572             :   return 0x00800000;
     573             : }
     574             : template <> inline constexpr binary_format<double>::equiv_uint
     575             :     binary_format<double>::hidden_bit_mask() {
     576             :   return 0x0010000000000000;
     577             : }
     578             : 
     579             : template<typename T>
     580             : fastfloat_really_inline FASTFLOAT_CONSTEXPR20
     581             : void to_float(bool negative, adjusted_mantissa am, T &value) {
     582             :   using fastfloat_uint = typename binary_format<T>::equiv_uint;
     583      266645 :   fastfloat_uint word = (fastfloat_uint)am.mantissa;
     584      266645 :   word |= fastfloat_uint(am.power2) << binary_format<T>::mantissa_explicit_bits();
     585      266645 :   word |= fastfloat_uint(negative) << binary_format<T>::sign_index();
     586             : #if FASTFLOAT_HAS_BIT_CAST
     587             :   value = std::bit_cast<T>(word);
     588             : #else
     589      266645 :   ::memcpy(&value, &word, sizeof(T));
     590             : #endif
     591      266645 : }
     592             : 
     593             : #ifdef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default
     594             : template <typename = void>
     595             : struct space_lut {
     596             :   static constexpr bool value[] = {
     597             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     598             :     0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     599             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     600             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     601             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     602             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     603             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     604             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     605             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     606             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     607             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
     608             : };
     609             : 
     610             : template <typename T>
     611             : constexpr bool space_lut<T>::value[];
     612             : 
     613             : inline constexpr bool is_space(uint8_t c) { return space_lut<>::value[c]; }
     614             : #endif
     615             : 
     616             : template<typename UC>
     617           0 : static constexpr uint64_t int_cmp_zeros()
     618             : {
     619             :     static_assert((sizeof(UC) == 1) || (sizeof(UC) == 2) || (sizeof(UC) == 4), "Unsupported character size");
     620           0 :     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'));
     621             : }
     622             : template<typename UC>
     623           0 : static constexpr int int_cmp_len()
     624             : {
     625           0 :     return sizeof(uint64_t) / sizeof(UC);
     626             : }
     627             : template<typename UC>
     628             : static constexpr UC const * str_const_nan()
     629             : {
     630             :     return nullptr;
     631             : }
     632             : template<>
     633           5 : constexpr char const * str_const_nan<char>()
     634             : {
     635           5 :     return "nan";
     636             : }
     637             : template<>
     638             : constexpr wchar_t const * str_const_nan<wchar_t>()
     639             : {
     640             :     return L"nan";
     641             : }
     642             : template<>
     643             : constexpr char16_t const * str_const_nan<char16_t>()
     644             : {
     645             :     return u"nan";
     646             : }
     647             : template<>
     648             : constexpr char32_t const * str_const_nan<char32_t>()
     649             : {
     650             :     return U"nan";
     651             : }
     652             : template<typename UC>
     653             : static constexpr UC const * str_const_inf()
     654             : {
     655             :     return nullptr;
     656             : }
     657             : template<>
     658           5 : constexpr char const * str_const_inf<char>()
     659             : {
     660           5 :     return "infinity";
     661             : }
     662             : template<>
     663             : constexpr wchar_t const * str_const_inf<wchar_t>()
     664             : {
     665             :     return L"infinity";
     666             : }
     667             : template<>
     668             : constexpr char16_t const * str_const_inf<char16_t>()
     669             : {
     670             :     return u"infinity";
     671             : }
     672             : template<>
     673             : constexpr char32_t const * str_const_inf<char32_t>()
     674             : {
     675             :     return U"infinity";
     676             : }
     677             : } // namespace fast_float
     678             : 
     679             : #endif

Generated by: LCOV version 1.14