diff --git a/format.h b/format.h index 8260024f..b85ddcb1 100644 --- a/format.h +++ b/format.h @@ -177,6 +177,16 @@ inline uint32_t clzll(uint64_t x) { TypeName& operator=(const TypeName&) #endif +#ifndef FMT_USE_USER_DEFINED_LITERALS +// All compilers which support UDLs also support variadic templates. This +// makes the fmt::literals implementation easier. However, an explicit check +// for variadic templates is added here just in case. +# define FMT_USE_USER_DEFINED_LITERALS \ + FMT_USE_VARIADIC_TEMPLATES && \ + (FMT_HAS_FEATURE(cxx_user_literals) || \ + (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1900) +#endif + #ifndef FMT_ASSERT # define FMT_ASSERT(condition, message) assert((condition) && message) #endif @@ -3005,6 +3015,34 @@ FMT_VARIADIC(int, printf, CStringRef) FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef) } +#if FMT_USE_USER_DEFINED_LITERALS +namespace fmt { +namespace internal { + +template +struct UdlFormat { + const Char *str; + + template + auto operator()(Args && ... args) const + -> decltype(format(str, std::forward(args)...)) { + return format(str, std::forward(args)...); + } +}; + +} // namespace internal + +inline namespace literals { + +inline internal::UdlFormat +operator"" _format(const char *s, std::size_t) { return {s}; } +inline internal::UdlFormat +operator"" _format(const wchar_t *s, std::size_t) { return {s}; } + +} // inline namespace literals +} // namespace fmt +#endif // FMT_USE_USER_DEFINED_LITERALS + // Restore warnings. #if FMT_GCC_VERSION >= 406 # pragma GCC diagnostic pop diff --git a/test/format-test.cc b/test/format-test.cc index 18498524..b95c499a 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1602,3 +1602,12 @@ TEST(FormatTest, MaxArgs) { fmt::format("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e')); } + +#if FMT_USE_USER_DEFINED_LITERALS +using namespace fmt::literals; + +TEST(LiteralsTest, Format) { + EXPECT_EQ(format("{}c{}", "ab", 1), "{}c{}"_format("ab", 1)); + EXPECT_EQ(format(L"{}c{}", L"ab", 1), L"{}c{}"_format(L"ab", 1)); +} +#endif // FMT_USE_USER_DEFINED_LITERALS