From 4e7ae339d6d2e311c510186c598aa2b2b0582f53 Mon Sep 17 00:00:00 2001 From: Maya Warrier Date: Sun, 7 May 2023 00:34:58 -0400 Subject: [PATCH 1/4] Implement intellisense fix --- .gitignore | 18 ++++++++++++++++ include/fast_float/fast_float.h | 32 ++--------------------------- include/fast_float/float_common.h | 34 +++++++++++++++++++++++++++++++ include/fast_float/parse_number.h | 1 + 4 files changed, 55 insertions(+), 30 deletions(-) diff --git a/.gitignore b/.gitignore index 1566557..c9e8138 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,21 @@ build/* Testing/* .cache/ compile_commands.json + +# Visual Studio +.vs/ +Debug/ +Release/ +*.sln +*.vcxproj +*.vcxproj.filters +*.vcxproj.user +*.psess +*.vspx +*.vsp +*.diagsession +*.hint + +# VS CMake +/out/ +/CMakeSettings.json diff --git a/include/fast_float/fast_float.h b/include/fast_float/fast_float.h index 1cc25f4..04efa87 100644 --- a/include/fast_float/fast_float.h +++ b/include/fast_float/fast_float.h @@ -1,38 +1,10 @@ + #ifndef FASTFLOAT_FAST_FLOAT_H #define FASTFLOAT_FAST_FLOAT_H -#include - -#include "constexpr_feature_detect.h" +#include "float_common.h" namespace fast_float { -enum chars_format { - scientific = 1<<0, - fixed = 1<<2, - hex = 1<<3, - general = fixed | scientific -}; - -template -struct from_chars_result_t { - UC const * ptr; - std::errc ec; -}; -using from_chars_result = from_chars_result_t; - -template -struct parse_options_t { - constexpr explicit parse_options_t(chars_format fmt = chars_format::general, - UC dot = UC('.')) - : format(fmt), decimal_point(dot) {} - - /** Which number formats are accepted */ - chars_format format; - /** The character used as decimal point */ - UC decimal_point; -}; -using parse_options = parse_options_t; - /** * This function parses the character sequence [first,last) for a number. It parses floating-point numbers expecting * a locale-indepent format equivalent to what is used by std::strtod in the default ("C") locale. diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index 6901d7c..3439600 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -6,6 +6,40 @@ #include #include #include +#include + +#include "constexpr_feature_detect.h" + +namespace fast_float { + +enum chars_format { + scientific = 1 << 0, + fixed = 1 << 2, + hex = 1 << 3, + general = fixed | scientific +}; + +template +struct from_chars_result_t { + UC const* ptr; + std::errc ec; +}; +using from_chars_result = from_chars_result_t; + +template +struct parse_options_t { + constexpr explicit parse_options_t(chars_format fmt = chars_format::general, + UC dot = UC('.')) + : format(fmt), decimal_point(dot) {} + + /** Which number formats are accepted */ + chars_format format; + /** The character used as decimal point */ + UC decimal_point; +}; +using parse_options = parse_options_t; + +} #if FASTFLOAT_HAS_BIT_CAST #include diff --git a/include/fast_float/parse_number.h b/include/fast_float/parse_number.h index 726d761..4541d70 100644 --- a/include/fast_float/parse_number.h +++ b/include/fast_float/parse_number.h @@ -4,6 +4,7 @@ #include "ascii_number.h" #include "decimal_to_binary.h" #include "digit_comparison.h" +#include "float_common.h" #include #include From db7991a612de88d3eced98e1ee6752b600523ff1 Mon Sep 17 00:00:00 2001 From: Maya Warrier Date: Sun, 7 May 2023 17:04:02 -0400 Subject: [PATCH 2/4] amalmagate.py header inclusion order --- script/amalgamate.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/script/amalgamate.py b/script/amalgamate.py index c0f078d..6a25459 100644 --- a/script/amalgamate.py +++ b/script/amalgamate.py @@ -31,9 +31,8 @@ for filename in ['LICENSE-MIT', 'LICENSE-APACHE']: processed_files[filename] = text # code -for filename in [ 'constexpr_feature_detect.h', 'fast_float.h', 'float_common.h', 'ascii_number.h', - 'fast_table.h', 'decimal_to_binary.h', 'bigint.h', - 'ascii_number.h', 'digit_comparison.h', 'parse_number.h']: +for filename in [ 'constexpr_feature_detect.h', 'float_common.h', 'fast_float.h', 'ascii_number.h', + 'fast_table.h', 'decimal_to_binary.h', 'bigint.h', 'digit_comparison.h', 'parse_number.h']: with open('include/fast_float/' + filename, encoding='utf8') as f: text = '' for line in f: @@ -76,11 +75,10 @@ text = ''.join([ processed_files['AUTHORS'], processed_files['CONTRIBUTORS'], *license_content(args.license), processed_files['constexpr_feature_detect.h'], - processed_files['fast_float.h'], processed_files['float_common.h'], + processed_files['float_common.h'], processed_files['fast_float.h'], processed_files['ascii_number.h'], processed_files['fast_table.h'], processed_files['decimal_to_binary.h'], processed_files['bigint.h'], - processed_files['ascii_number.h'], processed_files['digit_comparison.h'], - processed_files['parse_number.h']]) + processed_files['digit_comparison.h'], processed_files['parse_number.h']]) if args.output: with open(args.output, 'wt', encoding='utf8') as f: From cc042ae40958cd6646585d950d3cb10ad6e39a0b Mon Sep 17 00:00:00 2001 From: Lenard Szolnoki Date: Sun, 7 May 2023 23:07:34 +0100 Subject: [PATCH 3/4] Make lookup tables external linkage --- include/fast_float/float_common.h | 116 ++++++++++++++++-------------- 1 file changed, 63 insertions(+), 53 deletions(-) diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index 6901d7c..007dab3 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -252,55 +252,8 @@ struct adjusted_mantissa { // Bias so we can get the real exponent with an invalid adjusted_mantissa. constexpr static int32_t invalid_am_bias = -0x8000; -constexpr static double powers_of_ten_double[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, - 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}; -constexpr static float powers_of_ten_float[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, - 1e6f, 1e7f, 1e8f, 1e9f, 1e10f}; -// used for max_mantissa_double and max_mantissa_float +// used for binary_format::max_mantissa constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5; -// Largest integer value v so that (5**index * v) <= 1<<53. -// 0x10000000000000 == 1 << 53 -constexpr static uint64_t max_mantissa_double[] = { - 0x10000000000000, - 0x10000000000000 / 5, - 0x10000000000000 / (5 * 5), - 0x10000000000000 / (5 * 5 * 5), - 0x10000000000000 / (5 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555), - 0x10000000000000 / (constant_55555 * 5), - 0x10000000000000 / (constant_55555 * 5 * 5), - 0x10000000000000 / (constant_55555 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * 5 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555), - 0x10000000000000 / (constant_55555 * constant_55555 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5)}; - // Largest integer value v so that (5**index * v) <= 1<<24. - // 0x1000000 == 1<<24 - constexpr static uint64_t max_mantissa_float[] = { - 0x1000000, - 0x1000000 / 5, - 0x1000000 / (5 * 5), - 0x1000000 / (5 * 5 * 5), - 0x1000000 / (5 * 5 * 5 * 5), - 0x1000000 / (constant_55555), - 0x1000000 / (constant_55555 * 5), - 0x1000000 / (constant_55555 * 5 * 5), - 0x1000000 / (constant_55555 * 5 * 5 * 5), - 0x1000000 / (constant_55555 * 5 * 5 * 5 * 5), - 0x1000000 / (constant_55555 * constant_55555), - 0x1000000 / (constant_55555 * constant_55555 * 5)}; template struct binary_format { using equiv_uint = typename std::conditional::type; @@ -322,6 +275,9 @@ template struct binary_format { static inline constexpr equiv_uint exponent_mask(); static inline constexpr equiv_uint mantissa_mask(); static inline constexpr equiv_uint hidden_bit_mask(); + + static const T powers_of_ten[]; + static const uint64_t max_mantissa[]; }; template <> inline constexpr int binary_format::min_exponent_fast_path() { @@ -386,6 +342,52 @@ template <> inline constexpr int binary_format::max_exponent_fast_path() template <> inline constexpr int binary_format::max_exponent_fast_path() { return 10; } + +// Largest integer value v so that (5**index * v) <= 1<<53. +// 0x10000000000000 == 1 << 53 +template <> +constexpr uint64_t binary_format::max_mantissa[] = { + 0x10000000000000, + 0x10000000000000 / 5, + 0x10000000000000 / (5 * 5), + 0x10000000000000 / (5 * 5 * 5), + 0x10000000000000 / (5 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555), + 0x10000000000000 / (constant_55555 * 5), + 0x10000000000000 / (constant_55555 * 5 * 5), + 0x10000000000000 / (constant_55555 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * 5 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555), + 0x10000000000000 / (constant_55555 * constant_55555 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5)}; +// Largest integer value v so that (5**index * v) <= 1<<24. +// 0x1000000 == 1<<24 +template <> +constexpr uint64_t binary_format::max_mantissa[] = { + 0x1000000, + 0x1000000 / 5, + 0x1000000 / (5 * 5), + 0x1000000 / (5 * 5 * 5), + 0x1000000 / (5 * 5 * 5 * 5), + 0x1000000 / (constant_55555), + 0x1000000 / (constant_55555 * 5), + 0x1000000 / (constant_55555 * 5 * 5), + 0x1000000 / (constant_55555 * 5 * 5 * 5), + 0x1000000 / (constant_55555 * 5 * 5 * 5 * 5), + 0x1000000 / (constant_55555 * constant_55555), + 0x1000000 / (constant_55555 * constant_55555 * 5)}; + template <> inline constexpr uint64_t binary_format::max_mantissa_fast_path() { return uint64_t(2) << mantissa_explicit_bits(); } @@ -393,7 +395,7 @@ template <> inline constexpr uint64_t binary_format::max_mantissa_fast_p // caller is responsible to ensure that // power >= 0 && power <= 22 // - return max_mantissa_double[power]; + return max_mantissa[power]; } template <> inline constexpr uint64_t binary_format::max_mantissa_fast_path() { return uint64_t(2) << mantissa_explicit_bits(); @@ -402,17 +404,25 @@ template <> inline constexpr uint64_t binary_format::max_mantissa_fast_pa // caller is responsible to ensure that // power >= 0 && power <= 10 // - return max_mantissa_float[power]; + return max_mantissa[power]; } +template <> +constexpr double binary_format::powers_of_ten[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, + 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}; + +template <> +constexpr float binary_format::powers_of_ten[] = { + 1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, 1e6f, 1e7f, 1e8f, 1e9f, 1e10f}; + template <> inline constexpr double binary_format::exact_power_of_ten(int64_t power) { - return powers_of_ten_double[power]; + return powers_of_ten[power]; } template <> inline constexpr float binary_format::exact_power_of_ten(int64_t power) { - - return powers_of_ten_float[power]; + return powers_of_ten[power]; } From ddaefc0bbfe57bb3fd65d5391b61dfd61344e69c Mon Sep 17 00:00:00 2001 From: Lenard Szolnoki Date: Mon, 8 May 2023 15:24:11 +0100 Subject: [PATCH 4/4] Fix multiple definition linker errors for tables --- include/fast_float/float_common.h | 145 +++++++++++++++++------------- 1 file changed, 82 insertions(+), 63 deletions(-) diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index 007dab3..3451c3b 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -252,10 +252,13 @@ struct adjusted_mantissa { // Bias so we can get the real exponent with an invalid adjusted_mantissa. constexpr static int32_t invalid_am_bias = -0x8000; -// used for binary_format::max_mantissa +// used for binary_format_lookup_tables::max_mantissa constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5; -template struct binary_format { +template +struct binary_format_lookup_tables; + +template struct binary_format : binary_format_lookup_tables { using equiv_uint = typename std::conditional::type; static inline constexpr int mantissa_explicit_bits(); @@ -275,11 +278,77 @@ template struct binary_format { static inline constexpr equiv_uint exponent_mask(); static inline constexpr equiv_uint mantissa_mask(); static inline constexpr equiv_uint hidden_bit_mask(); - - static const T powers_of_ten[]; - static const uint64_t max_mantissa[]; }; +template +struct binary_format_lookup_tables { + static constexpr double powers_of_ten[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, + 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}; + + // Largest integer value v so that (5**index * v) <= 1<<53. + // 0x10000000000000 == 1 << 53 + static constexpr uint64_t max_mantissa[] = { + 0x10000000000000, + 0x10000000000000 / 5, + 0x10000000000000 / (5 * 5), + 0x10000000000000 / (5 * 5 * 5), + 0x10000000000000 / (5 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555), + 0x10000000000000 / (constant_55555 * 5), + 0x10000000000000 / (constant_55555 * 5 * 5), + 0x10000000000000 / (constant_55555 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * 5 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555), + 0x10000000000000 / (constant_55555 * constant_55555 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5)}; +}; + +template +constexpr double binary_format_lookup_tables::powers_of_ten[]; + +template +constexpr uint64_t binary_format_lookup_tables::max_mantissa[]; + +template +struct binary_format_lookup_tables { + static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, + 1e6f, 1e7f, 1e8f, 1e9f, 1e10f}; + + // Largest integer value v so that (5**index * v) <= 1<<24. + // 0x1000000 == 1<<24 + static constexpr uint64_t max_mantissa[] = { + 0x1000000, + 0x1000000 / 5, + 0x1000000 / (5 * 5), + 0x1000000 / (5 * 5 * 5), + 0x1000000 / (5 * 5 * 5 * 5), + 0x1000000 / (constant_55555), + 0x1000000 / (constant_55555 * 5), + 0x1000000 / (constant_55555 * 5 * 5), + 0x1000000 / (constant_55555 * 5 * 5 * 5), + 0x1000000 / (constant_55555 * 5 * 5 * 5 * 5), + 0x1000000 / (constant_55555 * constant_55555), + 0x1000000 / (constant_55555 * constant_55555 * 5)}; +}; + +template +constexpr float binary_format_lookup_tables::powers_of_ten[]; + +template +constexpr uint64_t binary_format_lookup_tables::max_mantissa[]; + template <> inline constexpr int binary_format::min_exponent_fast_path() { #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) return 0; @@ -343,51 +412,6 @@ template <> inline constexpr int binary_format::max_exponent_fast_path() return 10; } -// Largest integer value v so that (5**index * v) <= 1<<53. -// 0x10000000000000 == 1 << 53 -template <> -constexpr uint64_t binary_format::max_mantissa[] = { - 0x10000000000000, - 0x10000000000000 / 5, - 0x10000000000000 / (5 * 5), - 0x10000000000000 / (5 * 5 * 5), - 0x10000000000000 / (5 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555), - 0x10000000000000 / (constant_55555 * 5), - 0x10000000000000 / (constant_55555 * 5 * 5), - 0x10000000000000 / (constant_55555 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * 5 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555), - 0x10000000000000 / (constant_55555 * constant_55555 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5)}; -// Largest integer value v so that (5**index * v) <= 1<<24. -// 0x1000000 == 1<<24 -template <> -constexpr uint64_t binary_format::max_mantissa[] = { - 0x1000000, - 0x1000000 / 5, - 0x1000000 / (5 * 5), - 0x1000000 / (5 * 5 * 5), - 0x1000000 / (5 * 5 * 5 * 5), - 0x1000000 / (constant_55555), - 0x1000000 / (constant_55555 * 5), - 0x1000000 / (constant_55555 * 5 * 5), - 0x1000000 / (constant_55555 * 5 * 5 * 5), - 0x1000000 / (constant_55555 * 5 * 5 * 5 * 5), - 0x1000000 / (constant_55555 * constant_55555), - 0x1000000 / (constant_55555 * constant_55555 * 5)}; - template <> inline constexpr uint64_t binary_format::max_mantissa_fast_path() { return uint64_t(2) << mantissa_explicit_bits(); } @@ -395,7 +419,8 @@ template <> inline constexpr uint64_t binary_format::max_mantissa_fast_p // caller is responsible to ensure that // power >= 0 && power <= 22 // - return max_mantissa[power]; + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)max_mantissa[0], max_mantissa[power]; } template <> inline constexpr uint64_t binary_format::max_mantissa_fast_path() { return uint64_t(2) << mantissa_explicit_bits(); @@ -404,25 +429,19 @@ template <> inline constexpr uint64_t binary_format::max_mantissa_fast_pa // caller is responsible to ensure that // power >= 0 && power <= 10 // - return max_mantissa[power]; + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)max_mantissa[0], max_mantissa[power]; } -template <> -constexpr double binary_format::powers_of_ten[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, - 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}; - -template <> -constexpr float binary_format::powers_of_ten[] = { - 1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, 1e6f, 1e7f, 1e8f, 1e9f, 1e10f}; - template <> inline constexpr double binary_format::exact_power_of_ten(int64_t power) { - return powers_of_ten[power]; + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)powers_of_ten[0], powers_of_ten[power]; } template <> inline constexpr float binary_format::exact_power_of_ten(int64_t power) { - return powers_of_ten[power]; + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)powers_of_ten[0], powers_of_ten[power]; }