diff --git a/include/fmt/compile.h b/include/fmt/compile.h index 003be9e78414..662dbc2067ef 100644 --- a/include/fmt/compile.h +++ b/include/fmt/compile.h @@ -11,7 +11,15 @@ #include "format.h" FMT_BEGIN_NAMESPACE -namespace detail { +FMT_MODULE_EXPORT_BEGIN + +// compile-time support +namespace ct { +// A compile-time string which is compiled into fast formatting code. +class compiled_string {}; +} // namespace ct + +FMT_BEGIN_DETAIL_NAMESPACE // An output iterator that counts the number of objects written to it and // discards them. @@ -137,11 +145,8 @@ class truncating_iterator truncating_iterator& operator*() { return *this; } }; -// A compile-time string which is compiled into fast formatting code. -class compiled_string {}; - template -struct is_compiled_string : std::is_base_of {}; +struct is_compiled_string : std::is_base_of {}; /** \rst @@ -157,15 +162,14 @@ struct is_compiled_string : std::is_base_of {}; \endrst */ #ifdef __cpp_if_constexpr -# define FMT_COMPILE(s) \ - FMT_STRING_IMPL(s, fmt::detail::compiled_string, explicit) +# define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::ct::compiled_string, explicit) #else # define FMT_COMPILE(s) FMT_STRING(s) #endif #if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS template Str> -struct udl_compiled_string : compiled_string { +struct udl_compiled_string : fmt::ct::compiled_string { using char_type = Char; constexpr operator basic_string_view() const { return {Str.data, N - 1}; @@ -527,9 +531,8 @@ constexpr auto compile(S format_str) { } } #endif // __cpp_if_constexpr -} // namespace detail -FMT_MODULE_EXPORT_BEGIN +FMT_END_DETAIL_NAMESPACE #ifdef __cpp_if_constexpr diff --git a/include/fmt/fmt.h b/include/fmt/fmt.h index 72341d4c0bb5..5050df6c9f5b 100644 --- a/include/fmt/fmt.h +++ b/include/fmt/fmt.h @@ -23,6 +23,7 @@ }() #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::compile_string, ) +#define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::ct::compiled_string, explicit) import fmt; diff --git a/test/module-test.cc b/test/module-test.cc index 28550491a65c..1abec18842e9 100644 --- a/test/module-test.cc +++ b/test/module-test.cc @@ -277,6 +277,8 @@ TEST(module_test, literals) { EXPECT_EQ("42", "{}"_format(42)); EXPECT_EQ(L"42", fmt::format(L"{answer}", L"answer"_a = 42)); EXPECT_EQ(L"42", L"{}"_format(42)); + EXPECT_EQ("", fmt::format(""_cf)); + EXPECT_EQ("42", fmt::format("{}"_cf, 42)); } TEST(module_test, locale) { @@ -565,3 +567,11 @@ TEST(module_test, compile_time_string) { fmt::vformat_to(wbuffer, FMT_STRING(L"{:}"), fmt::make_wformat_args(42)); EXPECT_EQ(L"42", std::wstring_view(wbuffer)); } + +TEST(module_test, compile_format_string) { + EXPECT_EQ("42", fmt::format(FMT_COMPILE("{0:x}"), 0x42)); + EXPECT_EQ(L"42", fmt::format(FMT_COMPILE(L"{:}"), 42)); + using namespace fmt::literals; + EXPECT_EQ("4.2", fmt::format(FMT_COMPILE("{arg:3.1f}"), "arg"_a = 4.2)); + EXPECT_EQ(L" 42", fmt::format(FMT_COMPILE(L"{arg:>3}"), L"arg"_a = L"42")); +}