@@ -1856,6 +1856,65 @@ class fixed_buffer_traits {
18561856 }
18571857};
18581858
1859+ template <typename OutputIt, typename InputIt, typename = void >
1860+ struct has_back_insert_iterator_container_append : std::false_type {};
1861+
1862+ template <typename OutputIt, typename InputIt>
1863+ struct has_back_insert_iterator_container_append <
1864+ OutputIt, InputIt,
1865+ void_t <decltype (get_container(std::declval<OutputIt>())
1866+ .append(std::declval<InputIt>(),
1867+ std::declval<InputIt>()))>> : std::true_type {};
1868+
1869+ template <typename OutputIt, typename InputIt, typename = void >
1870+ struct has_back_insert_iterator_container_insert_at_end : std::false_type {};
1871+
1872+ template <typename OutputIt, typename InputIt>
1873+ struct has_back_insert_iterator_container_insert_at_end <
1874+ OutputIt, InputIt,
1875+ void_t <decltype (get_container(std::declval<OutputIt>())
1876+ .insert(get_container(std::declval<OutputIt>()).end(),
1877+ std::declval<InputIt>(),
1878+ std::declval<InputIt>()))>> : std::true_type {};
1879+
1880+ // An optimized version of std::copy with the output value type (T).
1881+ template <typename T, typename InputIt, typename OutputIt,
1882+ FMT_ENABLE_IF (is_back_insert_iterator<OutputIt>::value&&
1883+ has_back_insert_iterator_container_append<
1884+ OutputIt, InputIt>::value)>
1885+ FMT_CONSTEXPR auto copy (InputIt begin, InputIt end, OutputIt out) -> OutputIt {
1886+ get_container (out).append (begin, end);
1887+ return out;
1888+ }
1889+
1890+ template <typename T, typename InputIt, typename OutputIt,
1891+ FMT_ENABLE_IF (is_back_insert_iterator<OutputIt>::value &&
1892+ !has_back_insert_iterator_container_append<
1893+ OutputIt, InputIt>::value &&
1894+ has_back_insert_iterator_container_insert_at_end<
1895+ OutputIt, InputIt>::value)>
1896+ FMT_CONSTEXPR auto copy (InputIt begin, InputIt end, OutputIt out) -> OutputIt {
1897+ auto & c = get_container (out);
1898+ c.insert (c.end (), begin, end);
1899+ return out;
1900+ }
1901+
1902+ template <typename T, typename InputIt, typename OutputIt,
1903+ FMT_ENABLE_IF (!(is_back_insert_iterator<OutputIt>::value &&
1904+ (has_back_insert_iterator_container_append<
1905+ OutputIt, InputIt>::value ||
1906+ has_back_insert_iterator_container_insert_at_end<
1907+ OutputIt, InputIt>::value)))>
1908+ FMT_CONSTEXPR auto copy (InputIt begin, InputIt end, OutputIt out) -> OutputIt {
1909+ while (begin != end) *out++ = static_cast <T>(*begin++);
1910+ return out;
1911+ }
1912+
1913+ template <typename T, typename V, typename OutputIt>
1914+ FMT_CONSTEXPR auto copy (basic_string_view<V> s, OutputIt out) -> OutputIt {
1915+ return copy<T>(s.begin (), s.end (), out);
1916+ }
1917+
18591918// A buffer that writes to an output iterator when flushed.
18601919template <typename OutputIt, typename T, typename Traits = buffer_traits>
18611920class iterator_buffer : public Traits , public buffer <T> {
@@ -1873,7 +1932,10 @@ class iterator_buffer : public Traits, public buffer<T> {
18731932 this ->clear ();
18741933 const T* begin = data_;
18751934 const T* end = begin + this ->limit (size);
1876- while (begin != end) *out_++ = *begin++;
1935+ if constexpr (std::is_move_assignable<OutputIt>::value)
1936+ out_ = copy<T>(begin, end, out_);
1937+ else
1938+ while (begin != end) *out_++ = *begin++;
18771939 }
18781940
18791941 public:
0 commit comments