From 99b9fbf8eff2fc63e639260bd96e22f058f4f818 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix-Antoine=20Constantin?= <60141446+felix642@users.noreply.github.com> Date: Thu, 30 Nov 2023 13:05:56 -0500 Subject: [PATCH] Add formatter for std::source_location (#3730) --- include/fmt/std.h | 30 ++++++++++++++++++++++++++++++ test/std-test.cc | 10 ++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/fmt/std.h b/include/fmt/std.h index 86c8756f..6f6b23ff 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 @@ -239,6 +243,32 @@ struct formatter, Char, FMT_END_NAMESPACE #endif // __cpp_lib_optional +#ifdef __cpp_lib_source_location +FMT_BEGIN_NAMESPACE +FMT_EXPORT +template<> +struct formatter { + 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(out, loc.file_name()); + out = detail::write(out, ':'); + out = detail::write(out, loc.line()); + out = detail::write(out, ':'); + 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 55a48810..2e8ff177 100644 --- a/test/std-test.cc +++ b/test/std-test.cc @@ -66,6 +66,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");