diff --git a/include/fmt/compile.h b/include/fmt/compile.h index 5b8d2d0d..844793f4 100644 --- a/include/fmt/compile.h +++ b/include/fmt/compile.h @@ -206,15 +206,6 @@ class prepared_format { return {it.base(), it.count()}; } - std::basic_string format(const Args&... args) const { - basic_memory_buffer buffer; - using range = buffer_range; - this->vformat_to(range(buffer), - basic_format_args{ - make_args_checked(format_, args...)}); - return to_string(buffer); - } - template ::value)> inline std::back_insert_iterator format_to( std::back_insert_iterator out, Args&&... args) const { @@ -243,7 +234,6 @@ class prepared_format { make_args_checked(format_, args...)}); } - private: typedef buffer_context context; template @@ -304,6 +294,7 @@ class prepared_format { return ctx.out(); } + private: void advance_parse_context_to_specification( basic_parse_context& parse_ctx, const format_part_t& part) const { @@ -677,9 +668,10 @@ auto do_compile(const Format& format) } #endif -template using prepared_format_t = - typename basic_prepared_format< - std::string, parts_container, Args...>::type; +template +using prepared_format_t = + typename basic_prepared_format, + Args...>::type; } // namespace internal #if FMT_USE_CONSTEXPR @@ -720,6 +712,17 @@ auto compile(basic_string_view format_str) -> return compile(internal::to_runtime_format(format_str)); } +template +std::basic_string format(const CompiledFormat& cf, const Args&... args) { + basic_memory_buffer buffer; + using range = internal::buffer_range; + using context = buffer_context; + cf.template vformat_to(range(buffer), + {make_format_args(args...)}); + return to_string(buffer); +} + FMT_END_NAMESPACE #endif // FMT_COMPILE_H_ diff --git a/test/compile-test.cc b/test/compile-test.cc index 8a8f1b93..5d123f4f 100644 --- a/test/compile-test.cc +++ b/test/compile-test.cc @@ -449,11 +449,11 @@ template struct copied_prepared_format_creator { TEST(PrepareTest, CopyPreparedFormat_InternalStringViewsAreNotInvalidated) { auto prepared = copied_prepared_format_creator::make( "before {} middle {} after"); - EXPECT_EQ("before 42 middle text after", prepared.format(42, "text")); + EXPECT_EQ("before 42 middle text after", fmt::format(prepared, 42, "text")); prepared = copied_prepared_format_creator::make( "before {0} middle {1} after"); - EXPECT_EQ("before 42 middle text after", prepared.format(42, "text")); + EXPECT_EQ("before 42 middle text after", fmt::format(prepared, 42, "text")); { typedef decltype(fmt::arg("first", 42)) argument0; @@ -462,7 +462,7 @@ TEST(PrepareTest, CopyPreparedFormat_InternalStringViewsAreNotInvalidated) { copied_prepared_format_creator::make( "before {first} middle {second} after"); EXPECT_EQ("before 42 middle text after", - named_prepared.format(fmt::arg("first", 42), + fmt::format(named_prepared, fmt::arg("first", 42), fmt::arg("second", "text"))); } { @@ -472,7 +472,7 @@ TEST(PrepareTest, CopyPreparedFormat_InternalStringViewsAreNotInvalidated) { copied_prepared_format_creator::make( ">>>{value:>{width}}<<<"); EXPECT_EQ(">>> 12345<<<", - named_prepared.format(fmt::arg("value", "12345"), + fmt::format(named_prepared, fmt::arg("value", "12345"), fmt::arg("width", 10))); } } @@ -481,9 +481,9 @@ TEST(PrepareTest, ReusedPreparedFormatType) { using prepared_format = fmt::internal::prepared_format_t; prepared_format prepared = fmt::compile("The {} is {}."); - EXPECT_EQ("The answer is 42.", prepared.format("answer", 42)); + EXPECT_EQ("The answer is 42.", fmt::format(prepared, "answer", 42)); prepared = fmt::compile("40 {} 2 = {}"); - EXPECT_EQ("40 + 2 = 42", prepared.format("+", 42)); + EXPECT_EQ("40 + 2 = 42", fmt::format(prepared, "+", 42)); } TEST(PrepareTest, UserProvidedPartsContainerUnderlyingContainer) { @@ -494,9 +494,9 @@ TEST(PrepareTest, UserProvidedPartsContainerUnderlyingContainer) { int>::type prepared_format; prepared_format prepared = fmt::compile("The {} is {}."); - EXPECT_EQ("The answer is 42.", prepared.format("answer", 42)); + EXPECT_EQ("The answer is 42.", fmt::format(prepared, "answer", 42)); prepared = fmt::compile("40 {} 2 = {}"); - EXPECT_EQ("40 + 2 = 42", prepared.format("+", 42)); + EXPECT_EQ("40 + 2 = 42", fmt::format(prepared, "+", 42)); } class custom_parts_container { @@ -538,67 +538,67 @@ TEST(PrepareTest, UserProvidedPartsContainer) { std::string, int>::type prepared_format; prepared_format prepared = fmt::compile("The {} is {}."); - EXPECT_EQ("The answer is 42.", prepared.format("answer", 42)); + EXPECT_EQ("The answer is 42.", fmt::format(prepared, "answer", 42)); prepared = fmt::compile("40 {} 2 = {}"); - EXPECT_EQ("40 + 2 = 42", prepared.format("+", 42)); + EXPECT_EQ("40 + 2 = 42", fmt::format(prepared, "+", 42)); } TEST(PrepareTest, PassConstCharPointerFormat) { const char* c_format = "test {}"; const auto prepared = fmt::compile(c_format); - EXPECT_EQ("test 42", prepared.format(42)); + EXPECT_EQ("test 42", fmt::format(prepared, 42)); const wchar_t* wc_format = L"test {}"; const auto wprepared = fmt::compile(wc_format); - EXPECT_EQ(L"test 42", wprepared.format(42)); + EXPECT_EQ(L"test 42", fmt::format(wprepared, 42)); } TEST(PrepareTest, PassCharArrayFormat) { char c_format[] = "test {}"; const auto prepared = fmt::compile(c_format); - EXPECT_EQ("test 42", prepared.format(42)); + EXPECT_EQ("test 42", fmt::format(prepared, 42)); wchar_t wc_format[] = L"test {}"; const auto wprepared = fmt::compile(wc_format); - EXPECT_EQ(L"test 42", wprepared.format(42)); + EXPECT_EQ(L"test 42", fmt::format(wprepared, 42)); } TEST(PrepareTest, PassConstCharArrayFormat) { const char c_format[] = "test {}"; const auto prepared = fmt::compile(c_format); - EXPECT_EQ("test 42", prepared.format(42)); + EXPECT_EQ("test 42", fmt::format(prepared, 42)); const wchar_t wc_format[] = L"test {}"; const auto wprepared = fmt::compile(wc_format); - EXPECT_EQ(L"test 42", wprepared.format(42)); + EXPECT_EQ(L"test 42", fmt::format(wprepared, 42)); } TEST(PrepareTest, PassStringLiteralFormat) { const auto prepared = fmt::compile("test {}"); - EXPECT_EQ("test 42", prepared.format(42)); + EXPECT_EQ("test 42", fmt::format(prepared, 42)); const auto wprepared = fmt::compile(L"test {}"); - EXPECT_EQ(L"test 42", wprepared.format(42)); + EXPECT_EQ(L"test 42", fmt::format(wprepared, 42)); } TEST(PrepareTest, PassStringViewFormat) { const auto prepared = fmt::compile(fmt::basic_string_view("test {}")); - EXPECT_EQ("test 42", prepared.format(42)); + EXPECT_EQ("test 42", fmt::format(prepared, 42)); const auto wprepared = fmt::compile(fmt::basic_string_view(L"test {}")); - EXPECT_EQ(L"test 42", wprepared.format(42)); + EXPECT_EQ(L"test 42", fmt::format(wprepared, 42)); } TEST(PrepareTest, PassBasicStringFormat) { const auto prepared = fmt::compile(std::string("test {}")); - EXPECT_EQ("test 42", prepared.format(42)); + EXPECT_EQ("test 42", fmt::format(prepared, 42)); const auto wprepared = fmt::compile(std::wstring(L"test {}")); - EXPECT_EQ(L"test 42", wprepared.format(42)); + EXPECT_EQ(L"test 42", fmt::format(wprepared, 42)); } #if FMT_USE_CONSTEXPR TEST(PrepareTest, PassCompileString) { const auto prepared = fmt::compile(FMT_STRING("test {}")); - EXPECT_EQ("test 42", prepared.format(42)); + EXPECT_EQ("test 42", fmt::format(prepared, 42)); const auto wprepared = fmt::compile(FMT_STRING(L"test {}")); - EXPECT_EQ(L"test 42", wprepared.format(42)); + EXPECT_EQ(L"test 42", fmt::format(wprepared, 42)); } #endif @@ -637,7 +637,7 @@ TEST(PrepareTest, PassUserTypeFormat) { typedef std::basic_string, user_allocator> user_format; const auto prepared = fmt::compile(user_format("test {}")); - EXPECT_EQ("test 42", prepared.format(42)); + EXPECT_EQ("test 42", fmt::format(prepared, 42)); } TEST(PrepareTest, FormatToArrayOfChars) {