Skip to content

Commit 73b240b

Browse files
committed
Speed up iterator_buffer
1 parent dc97113 commit 73b240b

File tree

2 files changed

+63
-60
lines changed

2 files changed

+63
-60
lines changed

include/fmt/base.h

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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.
18601919
template <typename OutputIt, typename T, typename Traits = buffer_traits>
18611920
class 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:

include/fmt/format.h

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -548,65 +548,6 @@ FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* {
548548
return out + count;
549549
}
550550

551-
template <typename OutputIt, typename InputIt, typename = void>
552-
struct has_back_insert_iterator_container_append : std::false_type {};
553-
554-
template <typename OutputIt, typename InputIt>
555-
struct has_back_insert_iterator_container_append<
556-
OutputIt, InputIt,
557-
void_t<decltype(get_container(std::declval<OutputIt>())
558-
.append(std::declval<InputIt>(),
559-
std::declval<InputIt>()))>> : std::true_type {};
560-
561-
template <typename OutputIt, typename InputIt, typename = void>
562-
struct has_back_insert_iterator_container_insert_at_end : std::false_type {};
563-
564-
template <typename OutputIt, typename InputIt>
565-
struct has_back_insert_iterator_container_insert_at_end<
566-
OutputIt, InputIt,
567-
void_t<decltype(get_container(std::declval<OutputIt>())
568-
.insert(get_container(std::declval<OutputIt>()).end(),
569-
std::declval<InputIt>(),
570-
std::declval<InputIt>()))>> : std::true_type {};
571-
572-
// An optimized version of std::copy with the output value type (T).
573-
template <typename T, typename InputIt, typename OutputIt,
574-
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value&&
575-
has_back_insert_iterator_container_append<
576-
OutputIt, InputIt>::value)>
577-
FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt {
578-
get_container(out).append(begin, end);
579-
return out;
580-
}
581-
582-
template <typename T, typename InputIt, typename OutputIt,
583-
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value &&
584-
!has_back_insert_iterator_container_append<
585-
OutputIt, InputIt>::value &&
586-
has_back_insert_iterator_container_insert_at_end<
587-
OutputIt, InputIt>::value)>
588-
FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt {
589-
auto& c = get_container(out);
590-
c.insert(c.end(), begin, end);
591-
return out;
592-
}
593-
594-
template <typename T, typename InputIt, typename OutputIt,
595-
FMT_ENABLE_IF(!(is_back_insert_iterator<OutputIt>::value &&
596-
(has_back_insert_iterator_container_append<
597-
OutputIt, InputIt>::value ||
598-
has_back_insert_iterator_container_insert_at_end<
599-
OutputIt, InputIt>::value)))>
600-
FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt {
601-
while (begin != end) *out++ = static_cast<T>(*begin++);
602-
return out;
603-
}
604-
605-
template <typename T, typename V, typename OutputIt>
606-
FMT_CONSTEXPR auto copy(basic_string_view<V> s, OutputIt out) -> OutputIt {
607-
return copy<T>(s.begin(), s.end(), out);
608-
}
609-
610551
template <typename OutChar, typename InputIt, typename OutputIt>
611552
FMT_CONSTEXPR FMT_NOINLINE auto copy_noinline(InputIt begin, InputIt end,
612553
OutputIt out) -> OutputIt {

0 commit comments

Comments
 (0)