diff --git a/doc/api.md b/doc/api.md index ff190383..a77b9d6b 100644 --- a/doc/api.md +++ b/doc/api.md @@ -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 `` is available) ::: ptr(const std::unique_ptr&) diff --git a/include/fmt/std.h b/include/fmt/std.h index b6b98bb7..60e83329 100644 --- a/include/fmt/std.h +++ b/include/fmt/std.h @@ -804,6 +804,55 @@ struct formatter, Char, } }; +#if FMT_HAS_INCLUDE() && defined(__cpp_lib_stdfloat) +# include + +inline auto format_as(std::float16_t value) -> float { + return static_cast(value); +} +inline auto format_as(std::bfloat16_t value) -> float { + return static_cast(value); +} + +template +struct formatter, Char> { + private: + formatter, Char> underlying_; + + public: + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + return underlying_.parse(ctx); + } + template + auto format(const std::complex& value, FormatContext& ctx) const + -> decltype(ctx.out()) { + return underlying_.format( + std::complex(static_cast(value.real()), + static_cast(value.imag())), + ctx); + } +}; + +template +struct formatter, Char> { + private: + formatter, Char> underlying_; + + public: + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + return underlying_.parse(ctx); + } + template + auto format(const std::complex& value, + FormatContext& ctx) const -> decltype(ctx.out()) { + return underlying_.format( + std::complex(static_cast(value.real()), + static_cast(value.imag())), + ctx); + } +}; +#endif // stdfloat + FMT_END_NAMESPACE #endif // FMT_STD_H_ diff --git a/test/std-test.cc b/test/std-test.cc index 1684a5ed..8c28f36a 100644 --- a/test/std-test.cc +++ b/test/std-test.cc @@ -111,6 +111,16 @@ TEST(std_test, complex) { "(1.00-2.20i) "); } +#if FMT_HAS_INCLUDE() && defined(__cpp_lib_stdfloat) +# include +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(f16, std::float16_t(2.f))), + fmt::format("{}", std::complex(1.5f, 2.f))); +} +#endif + #ifdef __cpp_lib_source_location TEST(std_test, source_location) { std::source_location loc = std::source_location::current();