mirror of
https://github.com/fmtlib/fmt.git
synced 2026-06-15 00:16:15 +08:00
Add formatting support for <stdfloat> types
Provide format_as for std::float16_t and std::bfloat16_t and dedicated std::complex formatters so fmt::print works with C++23 stdfloat types (fixes #4725).
This commit is contained in:
parent
2f18a88e68
commit
1b8b08589e
@ -514,6 +514,9 @@ chrono-format-specifications).
|
||||
https://en.cppreference.com/w/cpp/utility/source_location)
|
||||
- [`std::thread::id`](https://en.cppreference.com/w/cpp/thread/thread/id)
|
||||
- [`std::variant`](https://en.cppreference.com/w/cpp/utility/variant/variant)
|
||||
- C++23 [`std::float16_t`](https://en.cppreference.com/w/cpp/types/float16_t) /
|
||||
[`std::bfloat16_t`](https://en.cppreference.com/w/cpp/types/bfloat16_t) and
|
||||
`std::complex` of those types (via `format_as`, when `<stdfloat>` is available)
|
||||
|
||||
::: ptr(const std::unique_ptr<T, Deleter>&)
|
||||
|
||||
|
||||
@ -804,6 +804,55 @@ struct formatter<std::reference_wrapper<T>, Char,
|
||||
}
|
||||
};
|
||||
|
||||
#if FMT_HAS_INCLUDE(<stdfloat>) && defined(__cpp_lib_stdfloat)
|
||||
# include <stdfloat>
|
||||
|
||||
inline auto format_as(std::float16_t value) -> float {
|
||||
return static_cast<float>(value);
|
||||
}
|
||||
inline auto format_as(std::bfloat16_t value) -> float {
|
||||
return static_cast<float>(value);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
struct formatter<std::complex<std::float16_t>, Char> {
|
||||
private:
|
||||
formatter<std::complex<float>, Char> underlying_;
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
return underlying_.parse(ctx);
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const std::complex<std::float16_t>& value, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
return underlying_.format(
|
||||
std::complex<float>(static_cast<float>(value.real()),
|
||||
static_cast<float>(value.imag())),
|
||||
ctx);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
struct formatter<std::complex<std::bfloat16_t>, Char> {
|
||||
private:
|
||||
formatter<std::complex<float>, Char> underlying_;
|
||||
|
||||
public:
|
||||
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
|
||||
return underlying_.parse(ctx);
|
||||
}
|
||||
template <typename FormatContext>
|
||||
auto format(const std::complex<std::bfloat16_t>& value,
|
||||
FormatContext& ctx) const -> decltype(ctx.out()) {
|
||||
return underlying_.format(
|
||||
std::complex<float>(static_cast<float>(value.real()),
|
||||
static_cast<float>(value.imag())),
|
||||
ctx);
|
||||
}
|
||||
};
|
||||
#endif // stdfloat
|
||||
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
#endif // FMT_STD_H_
|
||||
|
||||
@ -111,6 +111,16 @@ TEST(std_test, complex) {
|
||||
"(1.00-2.20i) ");
|
||||
}
|
||||
|
||||
#if FMT_HAS_INCLUDE(<stdfloat>) && defined(__cpp_lib_stdfloat)
|
||||
# include <stdfloat>
|
||||
TEST(std_test, stdfloat) {
|
||||
std::float16_t f16 = std::float16_t(1.5f);
|
||||
EXPECT_EQ(fmt::format("{}", f16), fmt::format("{}", 1.5f));
|
||||
EXPECT_EQ(fmt::format("{}", std::complex<std::float16_t>(f16, std::float16_t(2.f))),
|
||||
fmt::format("{}", std::complex<float>(1.5f, 2.f)));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cpp_lib_source_location
|
||||
TEST(std_test, source_location) {
|
||||
std::source_location loc = std::source_location::current();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user