about summary refs log tree commit diff
path: root/absl/container/inlined_vector.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/container/inlined_vector.h')
-rw-r--r--absl/container/inlined_vector.h73
1 files changed, 44 insertions, 29 deletions
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h
index c2f9d44b8c67..7c574aec43bd 100644
--- a/absl/container/inlined_vector.h
+++ b/absl/container/inlined_vector.h
@@ -72,17 +72,30 @@ class InlinedVector {
   }
 
   template <typename Iterator>
+  using IsAtLeastInputIterator = std::is_convertible<
+      typename std::iterator_traits<Iterator>::iterator_category,
+      std::input_iterator_tag>;
+
+  template <typename Iterator>
+  using IsAtLeastForwardIterator = std::is_convertible<
+      typename std::iterator_traits<Iterator>::iterator_category,
+      std::forward_iterator_tag>;
+
+  template <typename Iterator>
   using DisableIfIntegral =
       absl::enable_if_t<!std::is_integral<Iterator>::value>;
 
   template <typename Iterator>
-  using EnableIfInputIterator = absl::enable_if_t<std::is_convertible<
-      typename std::iterator_traits<Iterator>::iterator_category,
-      std::input_iterator_tag>::value>;
+  using EnableIfAtLeastInputIterator =
+      absl::enable_if_t<IsAtLeastInputIterator<Iterator>::value>;
+
+  template <typename Iterator>
+  using EnableIfAtLeastForwardIterator =
+      absl::enable_if_t<IsAtLeastForwardIterator<Iterator>::value>;
 
   template <typename Iterator>
-  using IteratorCategory =
-      typename std::iterator_traits<Iterator>::iterator_category;
+  using DisableIfAtLeastForwardIterator =
+      absl::enable_if_t<!IsAtLeastForwardIterator<Iterator>::value>;
 
   using rvalue_reference = typename A::value_type&&;
 
@@ -130,8 +143,7 @@ class InlinedVector {
   InlinedVector(std::initializer_list<value_type> init_list,
                 const allocator_type& alloc = allocator_type())
       : allocator_and_tag_(alloc) {
-    AppendRange(init_list.begin(), init_list.end(),
-                IteratorCategory<decltype(init_list.begin())>{});
+    AppendRange(init_list.begin(), init_list.end());
   }
 
   // Creates an inlined vector with elements constructed from the provided
@@ -144,7 +156,7 @@ class InlinedVector {
   InlinedVector(InputIterator first, InputIterator last,
                 const allocator_type& alloc = allocator_type())
       : allocator_and_tag_(alloc) {
-    AppendRange(first, last, IteratorCategory<InputIterator>{});
+    AppendRange(first, last);
   }
 
   // Creates a copy of `other` using `other`'s allocator.
@@ -422,8 +434,7 @@ class InlinedVector {
   // Replaces the contents of the inlined vector with copies of the elements in
   // the provided `std::initializer_list`.
   InlinedVector& operator=(std::initializer_list<value_type> init_list) {
-    AssignRange(init_list.begin(), init_list.end(),
-                IteratorCategory<decltype(init_list.begin())>{});
+    AssignRange(init_list.begin(), init_list.end());
     return *this;
   }
 
@@ -500,15 +511,14 @@ class InlinedVector {
   // inlined vector with copies of the values in the provided
   // `std::initializer_list`.
   void assign(std::initializer_list<value_type> init_list) {
-    AssignRange(init_list.begin(), init_list.end(),
-                IteratorCategory<decltype(init_list.begin())>{});
+    AssignRange(init_list.begin(), init_list.end());
   }
 
   // Overload of `InlinedVector::assign()` to replace the contents of the
   // inlined vector with values constructed from the range [`first`, `last`).
   template <typename InputIterator, DisableIfIntegral<InputIterator>* = nullptr>
   void assign(InputIterator first, InputIterator last) {
-    AssignRange(first, last, IteratorCategory<InputIterator>{});
+    AssignRange(first, last);
   }
 
   // `InlinedVector::resize()`
@@ -593,11 +603,10 @@ class InlinedVector {
   // NOTE: The `enable_if` is intended to disambiguate the two three-argument
   // overloads of `insert()`.
   template <typename InputIterator,
-            typename = EnableIfInputIterator<InputIterator>>
+            EnableIfAtLeastInputIterator<InputIterator>* = nullptr>
   iterator insert(const_iterator position, InputIterator first,
                   InputIterator last) {
-    return InsertWithRange(position, first, last,
-                           IteratorCategory<InputIterator>());
+    return InsertWithRange(position, first, last);
   }
 
   // `InlinedVector::emplace()`
@@ -1077,8 +1086,9 @@ class InlinedVector {
     }
   }
 
-  template <typename Iterator>
-  void AssignRange(Iterator first, Iterator last, std::forward_iterator_tag) {
+  template <typename ForwardIterator,
+            EnableIfAtLeastForwardIterator<ForwardIterator>* = nullptr>
+  void AssignRange(ForwardIterator first, ForwardIterator last) {
     auto length = std::distance(first, last);
     // Prefer reassignment to copy construction for elements.
     if (static_cast<size_type>(length) <= size()) {
@@ -1097,8 +1107,9 @@ class InlinedVector {
     }
   }
 
-  template <typename Iterator>
-  void AssignRange(Iterator first, Iterator last, std::input_iterator_tag) {
+  template <typename InputIterator,
+            DisableIfAtLeastForwardIterator<InputIterator>* = nullptr>
+  void AssignRange(InputIterator first, InputIterator last) {
     // Optimized to avoid reallocation.
     // Prefer reassignment to copy construction for elements.
     iterator out = begin();
@@ -1109,8 +1120,9 @@ class InlinedVector {
     std::copy(first, last, std::back_inserter(*this));
   }
 
-  template <typename Iterator>
-  void AppendRange(Iterator first, Iterator last, std::forward_iterator_tag) {
+  template <typename ForwardIterator,
+            EnableIfAtLeastForwardIterator<ForwardIterator>* = nullptr>
+  void AppendRange(ForwardIterator first, ForwardIterator last) {
     auto length = std::distance(first, last);
     reserve(size() + length);
     if (allocated()) {
@@ -1122,8 +1134,9 @@ class InlinedVector {
     }
   }
 
-  template <typename Iterator>
-  void AppendRange(Iterator first, Iterator last, std::input_iterator_tag) {
+  template <typename InputIterator,
+            DisableIfAtLeastForwardIterator<InputIterator>* = nullptr>
+  void AppendRange(InputIterator first, InputIterator last) {
     std::copy(first, last, std::back_inserter(*this));
   }
 
@@ -1140,9 +1153,10 @@ class InlinedVector {
     return it_pair.first;
   }
 
-  template <typename ForwardIterator>
+  template <typename ForwardIterator,
+            EnableIfAtLeastForwardIterator<ForwardIterator>* = nullptr>
   iterator InsertWithRange(const_iterator position, ForwardIterator first,
-                           ForwardIterator last, std::forward_iterator_tag) {
+                           ForwardIterator last) {
     assert(position >= begin() && position <= end());
     if (ABSL_PREDICT_FALSE(first == last))
       return const_cast<iterator>(position);
@@ -1150,15 +1164,16 @@ class InlinedVector {
     auto n = std::distance(first, last);
     std::pair<iterator, iterator> it_pair = ShiftRight(position, n);
     size_type used_spots = it_pair.second - it_pair.first;
-    ForwardIterator open_spot = std::next(first, used_spots);
+    auto open_spot = std::next(first, used_spots);
     std::copy(first, open_spot, it_pair.first);
     UninitializedCopy(open_spot, last, it_pair.second);
     return it_pair.first;
   }
 
-  template <typename InputIterator>
+  template <typename InputIterator,
+            DisableIfAtLeastForwardIterator<InputIterator>* = nullptr>
   iterator InsertWithRange(const_iterator position, InputIterator first,
-                           InputIterator last, std::input_iterator_tag) {
+                           InputIterator last) {
     assert(position >= begin() && position <= end());
     size_type index = position - cbegin();
     size_type i = index;