Merge branch 'fmtlib:master' into patch-1
This commit is contained in:
commit
e8a6f7867f
@ -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>
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user