diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index ddd85182..92639ed6 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -152,7 +152,6 @@ template <> FMT_FUNC int count_digits<4>(detail::fallback_uintptr n) { #if __cplusplus < 201703L template constexpr const char basic_data::digits[][2]; template constexpr const char basic_data::hex_digits[]; -template constexpr const char basic_data::signs[]; template constexpr const unsigned basic_data::prefixes[]; #endif diff --git a/include/fmt/format.h b/include/fmt/format.h index b515d872..02726ee0 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -909,7 +909,6 @@ template struct basic_data { {'9', '6'}, {'9', '7'}, {'9', '8'}, {'9', '9'}}; FMT_API static constexpr const char hex_digits[] = "0123456789abcdef"; - FMT_API static constexpr const char signs[4] = {0, '-', '+', ' '}; FMT_API static constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+', 0x1000000u | ' '}; }; @@ -922,6 +921,14 @@ extern template struct basic_data; // This is a struct rather than an alias to avoid shadowing warnings in gcc. struct data : basic_data<> {}; +// Sign is a template parameter to workaround a bug in gcc 4.8. +template constexpr Char sign(Sign s) { +#if !FMT_GCC_VERSION || FMT_GCC_VERSION > 408 + static_assert(std::is_same::value, ""); +#endif + return static_cast("\0-+ "[s]); +} + template FMT_CONSTEXPR auto count_digits_fallback(T n) -> int { int count = 1; for (;;) { @@ -1676,7 +1683,7 @@ auto write_nonfinite(OutputIt out, bool isinf, basic_format_specs specs, specs.fill.size() == 1 && *specs.fill.data() == static_cast('0'); if (is_zero_fill) specs.fill[0] = static_cast(' '); return write_padded(out, specs, size, [=](reserve_iterator it) { - if (sign) *it++ = static_cast(data::signs[sign]); + if (sign) *it++ = detail::sign(sign); return copy_str(str, str + str_size, it); }); } @@ -1820,7 +1827,7 @@ auto write_float(OutputIt out, const DecimalFP& fp, size += to_unsigned((decimal_point ? 1 : 0) + 2 + exp_digits); char exp_char = fspecs.upper ? 'E' : 'e'; auto write = [=](iterator it) { - if (sign) *it++ = static_cast(data::signs[sign]); + if (sign) *it++ = detail::sign(sign); // Insert a decimal point after the first digit and add an exponent. it = write_significand(it, significand, significand_size, 1, decimal_point); @@ -1848,7 +1855,7 @@ auto write_float(OutputIt out, const DecimalFP& fp, auto grouping = digit_grouping(loc, fspecs.locale); size += to_unsigned(grouping.count_separators(significand_size)); return write_padded(out, specs, size, [&](iterator it) { - if (sign) *it++ = static_cast(data::signs[sign]); + if (sign) *it++ = detail::sign(sign); it = write_significand(it, significand, significand_size, fp.exponent, grouping); if (!fspecs.showpoint) return it; @@ -1862,7 +1869,7 @@ auto write_float(OutputIt out, const DecimalFP& fp, auto grouping = digit_grouping(loc, fspecs.locale); size += to_unsigned(grouping.count_separators(significand_size)); return write_padded(out, specs, size, [&](iterator it) { - if (sign) *it++ = static_cast(data::signs[sign]); + if (sign) *it++ = detail::sign(sign); it = write_significand(it, significand, significand_size, exp, decimal_point, grouping); return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it; @@ -1877,7 +1884,7 @@ auto write_float(OutputIt out, const DecimalFP& fp, bool pointy = num_zeros != 0 || significand_size != 0 || fspecs.showpoint; size += 1 + (pointy ? 1 : 0) + to_unsigned(num_zeros); return write_padded(out, specs, size, [&](iterator it) { - if (sign) *it++ = static_cast(data::signs[sign]); + if (sign) *it++ = detail::sign(sign); *it++ = zero; if (!pointy) return it; *it++ = decimal_point; @@ -1905,7 +1912,7 @@ auto write(OutputIt out, T value, basic_format_specs specs, if (specs.align == align::numeric && fspecs.sign) { auto it = reserve(out, 1); - *it++ = static_cast(data::signs[fspecs.sign]); + *it++ = detail::sign(fspecs.sign); out = base_iterator(out, it); fspecs.sign = sign::none; if (specs.width != 0) --specs.width; @@ -1913,7 +1920,7 @@ auto write(OutputIt out, T value, basic_format_specs specs, memory_buffer buffer; if (fspecs.format == float_format::hex) { - if (fspecs.sign) buffer.push_back(data::signs[fspecs.sign]); + if (fspecs.sign) buffer.push_back(detail::sign(fspecs.sign)); snprintf_float(promote_float(value), specs.precision, fspecs, buffer); return write_bytes(out, {buffer.data(), buffer.size()}, specs);