diff --git a/include/fmt/base.h b/include/fmt/base.h index e0baae256347..a5721fb90478 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -1971,15 +1971,38 @@ template class counting_buffer : public buffer { template struct is_back_insert_iterator> : std::true_type {}; +template +struct has_container_append : std::false_type {}; +template +struct has_container_append().append( + std::declval(), std::declval()))>> + : std::true_type {}; + // An optimized version of std::copy with the output value type (T). -template ::value)> +template < + typename T, typename InputIt, typename OutputIt, + FMT_ENABLE_IF( + is_back_insert_iterator::value&& has_container_append< + decltype(get_container(std::declval())), InputIt>::value)> FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt { get_container(out).append(begin, end); return out; } +template ::value && + !has_container_append< + decltype(get_container(std::declval())), + InputIt>::value)> +FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out) + -> OutputIt { + auto& c = get_container(out); + c.insert(c.end(), begin, end); + return out; +} + template ::value)> FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt { diff --git a/test/compile-test.cc b/test/compile-test.cc index e3a5dca2bc7c..043588e49050 100644 --- a/test/compile-test.cc +++ b/test/compile-test.cc @@ -8,6 +8,7 @@ #include "fmt/compile.h" #include +#include #include "fmt/chrono.h" #include "fmt/ranges.h" @@ -229,10 +230,14 @@ TEST(compile_test, unknown_format_fallback) { EXPECT_EQ(" 42 ", fmt::format(FMT_COMPILE("{name:^4}"), fmt::arg("name", 42))); - std::vector v; - fmt::format_to(std::back_inserter(v), FMT_COMPILE("{name:^4}"), + std::vector v1; + fmt::format_to(std::back_inserter(v1), FMT_COMPILE("{}"), 42); + EXPECT_EQ("42", fmt::string_view(v1.data(), v1.size())); + + std::vector v2; + fmt::format_to(std::back_inserter(v2), FMT_COMPILE("{name:^4}"), fmt::arg("name", 42)); - EXPECT_EQ(" 42 ", fmt::string_view(v.data(), v.size())); + EXPECT_EQ(" 42 ", fmt::string_view(v2.data(), v2.size())); char buffer[4]; auto result = fmt::format_to_n(buffer, 4, FMT_COMPILE("{name:^5}"),