diff --git a/include/fmt/std.h b/include/fmt/std.h index 4799df1a317d..2427e8c8cfa2 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,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 dc1073b58fc8..4505af1c180e 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");