aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Sjaardema <gsjaardema@gmail.com>2023-09-20 19:57:55 -0600
committerGitHub <noreply@github.com>2023-09-20 18:57:55 -0700
commit7529af8f991e138669f277c7b8ce2c3d9130aa22 (patch)
treef088ec2561af26f0a782d5d68a86d7827a51978b
parenta3a74fa7f3a6803f34459b36640b0c665a5a60d9 (diff)
downloadfmtlib-7529af8f991e138669f277c7b8ce2c3d9130aa22.tar.gz
Workaround intel bug (#3652)
* Workaround intel bug Potential workaround / restructure for the intel bug that is the cause of #3645. Make the variable in the external struct instead an embedded static constexpr variable in the only function that uses the variable. * Finish the proposed change -- remove struct accessor * Refactor proposed intel fix. Moved variable out of function to avoid specialization on Float. Made it a separate function that is called from format_float. * Fix incorrect function name. * Add missing inline.
-rw-r--r--include/fmt/format.h48
1 files changed, 22 insertions, 26 deletions
diff --git a/include/fmt/format.h b/include/fmt/format.h
index 66a9e226..30addcb7 100644
--- a/include/fmt/format.h
+++ b/include/fmt/format.h
@@ -1740,28 +1740,6 @@ FMT_CONSTEXPR inline fp operator*(fp x, fp y) {
return {multiply(x.f, y.f), x.e + y.e + 64};
}
-template <typename T = void> struct basic_data {
- // For checking rounding thresholds.
- // The kth entry is chosen to be the smallest integer such that the
- // upper 32-bits of 10^(k+1) times it is strictly bigger than 5 * 10^k.
- static constexpr uint32_t fractional_part_rounding_thresholds[8] = {
- 2576980378U, // ceil(2^31 + 2^32/10^1)
- 2190433321U, // ceil(2^31 + 2^32/10^2)
- 2151778616U, // ceil(2^31 + 2^32/10^3)
- 2147913145U, // ceil(2^31 + 2^32/10^4)
- 2147526598U, // ceil(2^31 + 2^32/10^5)
- 2147487943U, // ceil(2^31 + 2^32/10^6)
- 2147484078U, // ceil(2^31 + 2^32/10^7)
- 2147483691U // ceil(2^31 + 2^32/10^8)
- };
-};
-// This is a struct rather than an alias to avoid shadowing warnings in gcc.
-struct data : basic_data<> {};
-
-#if FMT_CPLUSPLUS < 201703L
-template <typename T>
-constexpr uint32_t basic_data<T>::fractional_part_rounding_thresholds[];
-#endif
template <typename T, bool doublish = num_bits<T>() == num_bits<double>()>
using convert_float_result =
@@ -3280,9 +3258,27 @@ FMT_CONSTEXPR20 void format_hexfloat(Float value, int precision,
format_hexfloat(static_cast<double>(value), precision, specs, buf);
}
+FMT_CONSTEXPR inline uint32_t fractional_part_rounding_thresholds(int index) {
+ // For checking rounding thresholds.
+ // The kth entry is chosen to be the smallest integer such that the
+ // upper 32-bits of 10^(k+1) times it is strictly bigger than 5 * 10^k.
+ constexpr uint32_t thresholds[8] = {
+ 2576980378U, // ceil(2^31 + 2^32/10^1)
+ 2190433321U, // ceil(2^31 + 2^32/10^2)
+ 2151778616U, // ceil(2^31 + 2^32/10^3)
+ 2147913145U, // ceil(2^31 + 2^32/10^4)
+ 2147526598U, // ceil(2^31 + 2^32/10^5)
+ 2147487943U, // ceil(2^31 + 2^32/10^6)
+ 2147484078U, // ceil(2^31 + 2^32/10^7)
+ 2147483691U // ceil(2^31 + 2^32/10^8)
+ };
+ return thresholds[index];
+}
+
template <typename Float>
FMT_CONSTEXPR20 auto format_float(Float value, int precision, float_specs specs,
buffer<char>& buf) -> int {
+
// float is passed as double to reduce the number of instantiations.
static_assert(!std::is_same<Float, float>::value, "");
FMT_ASSERT(value >= 0, "value is negative");
@@ -3485,8 +3481,8 @@ FMT_CONSTEXPR20 auto format_float(Float value, int precision, float_specs specs,
if (precision < 9) {
uint32_t fractional_part = static_cast<uint32_t>(prod);
should_round_up = fractional_part >=
- data::fractional_part_rounding_thresholds
- [8 - number_of_digits_to_print] ||
+ fractional_part_rounding_thresholds
+ (8 - number_of_digits_to_print) ||
((fractional_part >> 31) &
((digits & 1) | (second_third_subsegments != 0) |
has_more_segments)) != 0;
@@ -3525,8 +3521,8 @@ FMT_CONSTEXPR20 auto format_float(Float value, int precision, float_specs specs,
// consisting of a genuine digit from the input.
uint32_t fractional_part = static_cast<uint32_t>(prod);
should_round_up = fractional_part >=
- data::fractional_part_rounding_thresholds
- [8 - number_of_digits_to_print] ||
+ fractional_part_rounding_thresholds
+ (8 - number_of_digits_to_print) ||
((fractional_part >> 31) &
((digits & 1) | (third_subsegment != 0) |
has_more_segments)) != 0;