From 26c6b1c23dd5274b0e2d6d0d7c9a773924641eed Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 29 Jan 2026 21:30:20 -0800 Subject: [PATCH] Move copy to format.h --- include/fmt/base.h | 58 ------------------------------------------- include/fmt/format.h | 59 ++++++++++++++++++++++++++++++++++++++++++++ test/base-test.cc | 11 --------- test/format-test.cc | 11 +++++++++ 4 files changed, 70 insertions(+), 69 deletions(-) diff --git a/include/fmt/base.h b/include/fmt/base.h index 5151232c..d6d32e97 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -2031,64 +2031,6 @@ template class counting_buffer : public buffer { template struct is_back_insert_iterator> : std::true_type {}; -template -struct has_back_insert_iterator_container_append : std::false_type {}; -template -struct has_back_insert_iterator_container_append< - OutputIt, InputIt, - void_t()) - .append(std::declval(), - std::declval()))>> : std::true_type {}; - -template -struct has_back_insert_iterator_container_insert_at_end : std::false_type {}; - -template -struct has_back_insert_iterator_container_insert_at_end< - OutputIt, InputIt, - void_t()) - .insert(get_container(std::declval()).end(), - std::declval(), - std::declval()))>> : std::true_type {}; - -// An optimized version of std::copy with the output value type (T). -template ::value&& - has_back_insert_iterator_container_append< - OutputIt, InputIt>::value)> -FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt { - get_container(out).append(begin, end); - return out; -} - -template ::value && - !has_back_insert_iterator_container_append< - OutputIt, InputIt>::value && - has_back_insert_iterator_container_insert_at_end< - OutputIt, InputIt>::value)> -FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt { - auto& c = get_container(out); - c.insert(c.end(), begin, end); - return out; -} - -template ::value && - (has_back_insert_iterator_container_append< - OutputIt, InputIt>::value || - has_back_insert_iterator_container_insert_at_end< - OutputIt, InputIt>::value)))> -FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt { - while (begin != end) *out++ = static_cast(*begin++); - return out; -} - -template -FMT_CONSTEXPR auto copy(basic_string_view s, OutputIt out) -> OutputIt { - return copy(s.begin(), s.end(), out); -} - template struct is_buffer_appender : std::false_type {}; template diff --git a/include/fmt/format.h b/include/fmt/format.h index 94e964b4..1fd4a59e 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -567,6 +567,65 @@ FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* { return out + count; } +template +struct has_back_insert_iterator_container_append : std::false_type {}; + +template +struct has_back_insert_iterator_container_append< + OutputIt, InputIt, + void_t()) + .append(std::declval(), + std::declval()))>> : std::true_type {}; + +template +struct has_back_insert_iterator_container_insert_at_end : std::false_type {}; + +template +struct has_back_insert_iterator_container_insert_at_end< + OutputIt, InputIt, + void_t()) + .insert(get_container(std::declval()).end(), + std::declval(), + std::declval()))>> : std::true_type {}; + +// An optimized version of std::copy with the output value type (T). +template ::value&& + has_back_insert_iterator_container_append< + OutputIt, InputIt>::value)> +FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt { + get_container(out).append(begin, end); + return out; +} + +template ::value && + !has_back_insert_iterator_container_append< + OutputIt, InputIt>::value && + has_back_insert_iterator_container_insert_at_end< + OutputIt, InputIt>::value)> +FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt { + auto& c = get_container(out); + c.insert(c.end(), begin, end); + return out; +} + +template ::value && + (has_back_insert_iterator_container_append< + OutputIt, InputIt>::value || + has_back_insert_iterator_container_insert_at_end< + OutputIt, InputIt>::value)))> +FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt { + while (begin != end) *out++ = static_cast(*begin++); + return out; +} + +template +FMT_CONSTEXPR auto copy(basic_string_view s, OutputIt out) -> OutputIt { + return copy(s.begin(), s.end(), out); +} + template FMT_CONSTEXPR FMT_NOINLINE auto copy_noinline(InputIt begin, InputIt end, OutputIt out) -> OutputIt { diff --git a/test/base-test.cc b/test/base-test.cc index 7f5c5c7b..bf268875 100644 --- a/test/base-test.cc +++ b/test/base-test.cc @@ -282,17 +282,6 @@ TEST(base_test, is_back_insert_iterator) { std::front_insert_iterator>::value); } -struct minimal_container { - using value_type = char; - void push_back(char) {} -}; - -TEST(base_test, copy) { - minimal_container c; - static constexpr char str[] = "a"; - fmt::detail::copy(str, str + 1, std::back_inserter(c)); -} - TEST(base_test, get_buffer) { mock_buffer buffer; void* buffer_ptr = &buffer; diff --git a/test/format-test.cc b/test/format-test.cc index 4db939a1..9efde149 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -196,6 +196,17 @@ TEST(util_test, increment) { EXPECT_STREQ("200", s); } +struct minimal_container { + using value_type = char; + void push_back(char) {} +}; + +TEST(util_test, copy) { + minimal_container c; + static constexpr char str[] = "a"; + fmt::detail::copy(str, str + 1, std::back_inserter(c)); +} + TEST(util_test, parse_nonnegative_int) { auto s = fmt::string_view("10000000000"); auto begin = s.begin(), end = s.end();