Merge branch 'fmtlib:master' into patch-1

This commit is contained in:
Juraj 2022-02-20 20:17:06 +01:00 committed by GitHub
commit e8a6f7867f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 26 deletions

View File

@ -314,6 +314,8 @@ template <typename T>
using remove_cvref_t = typename std::remove_cv<remove_reference_t<T>>::type;
template <typename T> struct type_identity { using type = T; };
template <typename T> using type_identity_t = typename type_identity<T>::type;
template <typename T>
using underlying_t = typename std::underlying_type<T>::type;
struct monostate {
constexpr monostate() {}
@ -1416,8 +1418,8 @@ template <typename Context> struct arg_mapper {
!has_fallback_formatter<T, char_type>::value)>
FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
-> decltype(std::declval<arg_mapper>().map(
static_cast<typename std::underlying_type<T>::type>(val))) {
return map(static_cast<typename std::underlying_type<T>::type>(val));
static_cast<underlying_t<T>>(val))) {
return map(static_cast<underlying_t<T>>(val));
}
template <typename T, typename U = decltype(format_as(T())),
@ -2214,13 +2216,12 @@ template <typename Char> constexpr bool is_ascii_letter(Char c) {
// Converts a character to ASCII. Returns a number > 127 on conversion failure.
template <typename Char, FMT_ENABLE_IF(std::is_integral<Char>::value)>
constexpr auto to_ascii(Char value) -> Char {
return value;
constexpr auto to_ascii(Char c) -> Char {
return c;
}
template <typename Char, FMT_ENABLE_IF(std::is_enum<Char>::value)>
constexpr auto to_ascii(Char value) ->
typename std::underlying_type<Char>::type {
return value;
constexpr auto to_ascii(Char c) -> underlying_t<Char> {
return c;
}
template <typename Char>

View File

@ -2208,7 +2208,13 @@ FMT_HEADER_ONLY_CONSTEXPR20 int format_float(Float value, int precision,
if (specs.fallback) return snprintf_float(value, precision, specs, buf);
if (!is_constant_evaluated() && precision < 0) {
int exp = 0;
bool use_dragon = true;
if (!is_fast_float<Float>()) {
// Use floor because 0.9 = 9e-1.
exp = static_cast<int>(std::floor(std::log10(value)));
if (fixed) adjust_precision(precision, exp + 1);
} else if (!is_constant_evaluated() && precision < 0) {
// Use Dragonbox for the shortest format.
if (specs.binary32) {
auto dec = dragonbox::to_decimal(static_cast<float>(value));
@ -2218,11 +2224,7 @@ FMT_HEADER_ONLY_CONSTEXPR20 int format_float(Float value, int precision,
auto dec = dragonbox::to_decimal(static_cast<double>(value));
write<char>(buffer_appender<char>(buf), dec.significand);
return dec.exponent;
}
int exp = 0;
bool use_dragon = true;
if (is_fast_float<Float>()) {
} else {
// Use Grisu + Dragon4 for the given precision:
// https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf.
const int min_exp = -60; // alpha in Grisu.
@ -2241,10 +2243,6 @@ FMT_HEADER_ONLY_CONSTEXPR20 int format_float(Float value, int precision,
exp += handler.size - cached_exp10 - 1;
precision = handler.precision;
}
} else {
// Use floor because 0.9 = 9e-1.
exp = static_cast<int>(std::floor(std::log10(value)));
if (fixed) adjust_precision(precision, exp + 1);
}
if (use_dragon) {
auto f = fp();

View File

@ -775,6 +775,7 @@ class basic_memory_buffer final : public detail::buffer<T> {
// Set pointer to the inline array so that delete is not called
// when deallocating.
other.set(other.store_, 0);
other.clear();
}
this->resize(size);
}
@ -2354,8 +2355,7 @@ template <
type::custom_type,
FMT_ENABLE_IF(check)>
FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
return write<Char>(
out, static_cast<typename std::underlying_type<T>::type>(value));
return write<Char>(out, static_cast<underlying_t<T>>(value));
}
template <typename Char, typename OutputIt, typename T,
@ -2888,11 +2888,17 @@ template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
\endrst
*/
template <typename Enum>
constexpr auto underlying(Enum e) noexcept ->
typename std::underlying_type<Enum>::type {
return static_cast<typename std::underlying_type<Enum>::type>(e);
constexpr auto underlying(Enum e) noexcept -> underlying_t<Enum> {
return static_cast<underlying_t<Enum>>(e);
}
namespace enums {
template <typename Enum, FMT_ENABLE_IF(std::is_enum<Enum>::value)>
constexpr auto format_as(Enum e) noexcept -> underlying_t<Enum> {
return static_cast<underlying_t<Enum>>(e);
}
} // namespace enums
#ifdef __cpp_lib_byte
inline auto format_as(std::byte b) -> unsigned char { return underlying(b); }
FMT_FORMAT_AS(std::byte, unsigned char);

View File

@ -250,8 +250,9 @@ TEST(memory_buffer_test, move_ctor_dynamic_buffer) {
buffer.push_back('a');
basic_memory_buffer<char, 4, std_allocator> buffer2(std::move(buffer));
// Move should rip the guts of the first buffer.
EXPECT_EQ(inline_buffer_ptr, &buffer[0]);
EXPECT_EQ("testa", std::string(&buffer2[0], buffer2.size()));
EXPECT_EQ(&buffer[0], inline_buffer_ptr);
EXPECT_EQ(buffer.size(), 0);
EXPECT_EQ(std::string(&buffer2[0], buffer2.size()), "testa");
EXPECT_GT(buffer2.capacity(), 4u);
}
@ -948,8 +949,10 @@ TEST(format_test, precision) {
EXPECT_THAT(outputs,
testing::Contains(fmt::format("{:.838A}", -2.14001164E+38)));
auto ld = 8.43821965335442234493E-4933L;
EXPECT_EQ(fmt::format("{:.0}", ld), ld != 0 ? "8e-4933" : "0");
if (std::numeric_limits<long double>::digits == 64) {
auto ld = (std::numeric_limits<long double>::min)();
EXPECT_EQ(fmt::format("{:.0}", ld), "3e-4932");
}
EXPECT_EQ("123.", fmt::format("{:#.0f}", 123.0));
EXPECT_EQ("1.23", fmt::format("{:.02f}", 1.234));
@ -1459,8 +1462,14 @@ TEST(format_test, write_uintptr_fallback) {
enum class color { red, green, blue };
namespace test_ns {
enum class color { red, green, blue };
using fmt::enums::format_as;
} // namespace test_ns
TEST(format_test, format_enum_class) {
EXPECT_EQ(fmt::format("{}", fmt::underlying(color::red)), "0");
EXPECT_EQ(fmt::format("{}", test_ns::color::red), "0");
}
TEST(format_test, format_string) {