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

Generated by: LCOV version 1.14