================
@@ -2113,12 +2113,63 @@ void erase(Container &C, ValueType V) {
   C.erase(std::remove(C.begin(), C.end(), V), C.end());
 }
 
+namespace detail {
+template <typename Range>
+using check_has_member_iterator_category_t =
+    typename decltype(std::declval<Range &>().begin())::iterator_category;
+
+template <typename Range>
+static constexpr bool HasMemberIteratorCategory =
+    is_detected<check_has_member_iterator_category_t, Range>::value;
+
+template <typename Container>
+using check_has_member_capacity_t =
+    decltype(std::declval<Container &>().capacity());
+
+template <typename Container>
+static constexpr bool HasMemberCapacity =
+    is_detected<check_has_member_capacity_t, Container>::value;
+
+template <typename Container>
+using check_has_member_reserve_t =
+    decltype(std::declval<Container &>().reserve(1U));
+
+template <typename Container>
+static constexpr bool HasMemberReserve =
+    is_detected<check_has_member_reserve_t, Container>::value;
+} // namespace detail
+
 /// Wrapper function to append range `R` to container `C`.
 ///
 /// C.insert(C.end(), R.begin(), R.end());
 template <typename Container, typename Range>
 void append_range(Container &C, Range &&R) {
+  size_t Before = 0;
+  size_t After = 0;
+
+  if constexpr (detail::HasMemberReserve<Container>) {
+    using IteratorType = decltype(adl_begin(R));
+    if constexpr (std::is_pointer<IteratorType>::value) {
+      C.reserve(C.size() + std::distance(adl_begin(R), adl_end(R)));
----------------
kuhar wrote:

The alternative would be to check that the type either has `.size()` (which we 
assume to be fast) or that `llvm::size` is detected (which already requires 
random access iterators)

https://github.com/llvm/llvm-project/pull/136543
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to