Speed up iterator_buffer (#4679)
This commit is contained in:
@@ -1858,6 +1858,65 @@ class fixed_buffer_traits {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename OutputIt, typename InputIt, typename = void>
|
||||||
|
struct has_back_insert_iterator_container_append : std::false_type {};
|
||||||
|
|
||||||
|
template <typename OutputIt, typename InputIt>
|
||||||
|
struct has_back_insert_iterator_container_append<
|
||||||
|
OutputIt, InputIt,
|
||||||
|
void_t<decltype(get_container(std::declval<OutputIt>())
|
||||||
|
.append(std::declval<InputIt>(),
|
||||||
|
std::declval<InputIt>()))>> : std::true_type {};
|
||||||
|
|
||||||
|
template <typename OutputIt, typename InputIt, typename = void>
|
||||||
|
struct has_back_insert_iterator_container_insert_at_end : std::false_type {};
|
||||||
|
|
||||||
|
template <typename OutputIt, typename InputIt>
|
||||||
|
struct has_back_insert_iterator_container_insert_at_end<
|
||||||
|
OutputIt, InputIt,
|
||||||
|
void_t<decltype(get_container(std::declval<OutputIt>())
|
||||||
|
.insert(get_container(std::declval<OutputIt>()).end(),
|
||||||
|
std::declval<InputIt>(),
|
||||||
|
std::declval<InputIt>()))>> : std::true_type {};
|
||||||
|
|
||||||
|
// An optimized version of std::copy with the output value type (T).
|
||||||
|
template <typename T, typename InputIt, typename OutputIt,
|
||||||
|
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::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 <typename T, typename InputIt, typename OutputIt,
|
||||||
|
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::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 <typename T, typename InputIt, typename OutputIt,
|
||||||
|
FMT_ENABLE_IF(!(is_back_insert_iterator<OutputIt>::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<T>(*begin++);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename V, typename OutputIt>
|
||||||
|
FMT_CONSTEXPR auto copy(basic_string_view<V> s, OutputIt out) -> OutputIt {
|
||||||
|
return copy<T>(s.begin(), s.end(), out);
|
||||||
|
}
|
||||||
|
|
||||||
// A buffer that writes to an output iterator when flushed.
|
// A buffer that writes to an output iterator when flushed.
|
||||||
template <typename OutputIt, typename T, typename Traits = buffer_traits>
|
template <typename OutputIt, typename T, typename Traits = buffer_traits>
|
||||||
class iterator_buffer : public Traits, public buffer<T> {
|
class iterator_buffer : public Traits, public buffer<T> {
|
||||||
@@ -1875,7 +1934,12 @@ class iterator_buffer : public Traits, public buffer<T> {
|
|||||||
this->clear();
|
this->clear();
|
||||||
const T* begin = data_;
|
const T* begin = data_;
|
||||||
const T* end = begin + this->limit(size);
|
const T* end = begin + this->limit(size);
|
||||||
while (begin != end) *out_++ = *begin++;
|
#if defined(__cpp_if_constexpr)
|
||||||
|
if constexpr (std::is_move_assignable<OutputIt>::value)
|
||||||
|
out_ = copy<T>(begin, end, out_);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
while (begin != end) *out_++ = *begin++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -548,65 +548,6 @@ FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* {
|
|||||||
return out + count;
|
return out + count;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutputIt, typename InputIt, typename = void>
|
|
||||||
struct has_back_insert_iterator_container_append : std::false_type {};
|
|
||||||
|
|
||||||
template <typename OutputIt, typename InputIt>
|
|
||||||
struct has_back_insert_iterator_container_append<
|
|
||||||
OutputIt, InputIt,
|
|
||||||
void_t<decltype(get_container(std::declval<OutputIt>())
|
|
||||||
.append(std::declval<InputIt>(),
|
|
||||||
std::declval<InputIt>()))>> : std::true_type {};
|
|
||||||
|
|
||||||
template <typename OutputIt, typename InputIt, typename = void>
|
|
||||||
struct has_back_insert_iterator_container_insert_at_end : std::false_type {};
|
|
||||||
|
|
||||||
template <typename OutputIt, typename InputIt>
|
|
||||||
struct has_back_insert_iterator_container_insert_at_end<
|
|
||||||
OutputIt, InputIt,
|
|
||||||
void_t<decltype(get_container(std::declval<OutputIt>())
|
|
||||||
.insert(get_container(std::declval<OutputIt>()).end(),
|
|
||||||
std::declval<InputIt>(),
|
|
||||||
std::declval<InputIt>()))>> : std::true_type {};
|
|
||||||
|
|
||||||
// An optimized version of std::copy with the output value type (T).
|
|
||||||
template <typename T, typename InputIt, typename OutputIt,
|
|
||||||
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::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 <typename T, typename InputIt, typename OutputIt,
|
|
||||||
FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::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 <typename T, typename InputIt, typename OutputIt,
|
|
||||||
FMT_ENABLE_IF(!(is_back_insert_iterator<OutputIt>::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<T>(*begin++);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename V, typename OutputIt>
|
|
||||||
FMT_CONSTEXPR auto copy(basic_string_view<V> s, OutputIt out) -> OutputIt {
|
|
||||||
return copy<T>(s.begin(), s.end(), out);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutChar, typename InputIt, typename OutputIt>
|
template <typename OutChar, typename InputIt, typename OutputIt>
|
||||||
FMT_CONSTEXPR FMT_NOINLINE auto copy_noinline(InputIt begin, InputIt end,
|
FMT_CONSTEXPR FMT_NOINLINE auto copy_noinline(InputIt begin, InputIt end,
|
||||||
OutputIt out) -> OutputIt {
|
OutputIt out) -> OutputIt {
|
||||||
|
|||||||
Reference in New Issue
Block a user