From 54eaa8c8f4f7e667adf4c9993096041e3925b839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix-Antoine=20Constantin?= Date: Tue, 28 Nov 2023 09:42:04 -0500 Subject: [PATCH] Added formatter for std::source_location --- include/fmt/std.h | 31 +++++++++++++++++++++++++++++++ test/std-test.cc | 10 ++++++++++ 2 files changed, 41 insertions(+) diff --git a/include/fmt/std.h b/include/fmt/std.h index 4799df1a..91f09f9a 100644 --- a/include/fmt/std.h +++ b/include/fmt/std.h @@ -38,6 +38,10 @@ # endif #endif +#if FMT_CPLUSPLUS > 201703L && FMT_HAS_INCLUDE() +# include +#endif + // GCC 4 does not support FMT_HAS_INCLUDE. #if FMT_HAS_INCLUDE() || defined(__GLIBCXX__) # include @@ -228,6 +232,33 @@ struct formatter, Char, FMT_END_NAMESPACE #endif // __cpp_lib_optional +#ifdef __cpp_lib_source_location +FMT_BEGIN_NAMESPACE +FMT_EXPORT +template +struct formatter::value>> { + template FMT_CONSTEXPR auto parse(ParseContext& ctx) { + return ctx.begin(); + } + + template + auto format(const std::source_location& loc, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto out = ctx.out(); + out = detail::write_bytes(out, loc.file_name(), format_specs()); + out = detail::write(out, Char(':')); + out = detail::write(out, loc.line()); + out = detail::write(out, Char(':')); + out = detail::write(out, loc.column()); + out = detail::write(out, ": "); + out = detail::write(out, loc.function_name()); + return out; + } +}; +FMT_END_NAMESPACE +#endif + #if FMT_CPP_LIB_VARIANT FMT_BEGIN_NAMESPACE namespace detail { diff --git a/test/std-test.cc b/test/std-test.cc index dc1073b5..4505af1c 100644 --- a/test/std-test.cc +++ b/test/std-test.cc @@ -62,6 +62,16 @@ TEST(std_test, thread_id) { EXPECT_FALSE(fmt::format("{}", std::this_thread::get_id()).empty()); } +#ifdef __cpp_lib_source_location +TEST(std_test, source_location) { + std::source_location loc = std::source_location::current(); + EXPECT_EQ(fmt::format("{}", loc), std::string(loc.file_name()) + ":" + + std::to_string(loc.line()) + ":" + + std::to_string(loc.column()) + ": " + + loc.function_name()); +} +#endif + TEST(std_test, optional) { #ifdef __cpp_lib_optional EXPECT_EQ(fmt::format("{}", std::optional{}), "none");