[libc++] Use __is_exactly_{input, forward}_iterator

Reviewed By: ldionne, #libc

Spies: libcxx-commits

Differential Revision: https://reviews.llvm.org/D128646

NOKEYCHECK=True
GitOrigin-RevId: 00927334df9a8133a5112c0450349d546373316f
diff --git a/include/__iterator/iterator_traits.h b/include/__iterator/iterator_traits.h
index c3a5b7e..1fbdc95 100644
--- a/include/__iterator/iterator_traits.h
+++ b/include/__iterator/iterator_traits.h
@@ -475,6 +475,12 @@
          __has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value &&
         !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {};
 
+template <class _Tp>
+struct __is_exactly_cpp17_forward_iterator
+    : public integral_constant<bool,
+         __has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value &&
+        !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value> {};
+
 template<class _InputIterator>
 using __iter_value_type = typename iterator_traits<_InputIterator>::value_type;
 
diff --git a/include/__split_buffer b/include/__split_buffer
index c1c03dd..eb78c9c 100644
--- a/include/__split_buffer
+++ b/include/__split_buffer
@@ -118,7 +118,7 @@
     void __construct_at_end(size_type __n);
     void __construct_at_end(size_type __n, const_reference __x);
     template <class _InputIter>
-    __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value && !__is_cpp17_forward_iterator<_InputIter>::value>
+    __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIter>::value>
         __construct_at_end(_InputIter __first, _InputIter __last);
     template <class _ForwardIterator>
     __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value>
diff --git a/include/deque b/include/deque
index d8f48f0..0d7eb9a 100644
--- a/include/deque
+++ b/include/deque
@@ -1464,12 +1464,10 @@
     iterator insert(const_iterator __p, size_type __n, const value_type& __v);
     template <class _InputIter>
         iterator insert(const_iterator __p, _InputIter __f, _InputIter __l,
-                         typename enable_if<__is_cpp17_input_iterator<_InputIter>::value
-                                         &&!__is_cpp17_forward_iterator<_InputIter>::value>::type* = 0);
+                         typename enable_if<__is_exactly_cpp17_input_iterator<_InputIter>::value>::type* = 0);
     template <class _ForwardIterator>
         iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
-                               typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value
-                                         &&!__is_cpp17_bidirectional_iterator<_ForwardIterator>::value>::type* = 0);
+                        typename enable_if<__is_exactly_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0);
     template <class _BiIter>
         iterator insert(const_iterator __p, _BiIter __f, _BiIter __l,
                          typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type* = 0);
@@ -1556,8 +1554,7 @@
 
     template <class _InpIter>
         void __append(_InpIter __f, _InpIter __l,
-                 typename enable_if<__is_cpp17_input_iterator<_InpIter>::value &&
-                                   !__is_cpp17_forward_iterator<_InpIter>::value>::type* = 0);
+                 typename enable_if<__is_exactly_cpp17_input_iterator<_InpIter>::value>::type* = 0);
     template <class _ForIter>
         void __append(_ForIter __f, _ForIter __l,
                       typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type* = 0);
@@ -2266,8 +2263,7 @@
 template <class _InputIter>
 typename deque<_Tp, _Allocator>::iterator
 deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l,
-                               typename enable_if<__is_cpp17_input_iterator<_InputIter>::value
-                                               &&!__is_cpp17_forward_iterator<_InputIter>::value>::type*)
+                               typename enable_if<__is_exactly_cpp17_input_iterator<_InputIter>::value>::type*)
 {
     __split_buffer<value_type, allocator_type&> __buf(__base::__alloc());
     __buf.__construct_at_end(__f, __l);
@@ -2279,8 +2275,7 @@
 template <class _ForwardIterator>
 typename deque<_Tp, _Allocator>::iterator
 deque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l,
-                               typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value
-                                               &&!__is_cpp17_bidirectional_iterator<_ForwardIterator>::value>::type*)
+                               typename enable_if<__is_exactly_cpp17_forward_iterator<_ForwardIterator>::value>::type*)
 {
     size_type __n = _VSTD::distance(__f, __l);
     __split_buffer<value_type, allocator_type&> __buf(__n, 0, __base::__alloc());
@@ -2362,8 +2357,7 @@
 template <class _InpIter>
 void
 deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,
-                                 typename enable_if<__is_cpp17_input_iterator<_InpIter>::value &&
-                                                   !__is_cpp17_forward_iterator<_InpIter>::value>::type*)
+                                 typename enable_if<__is_exactly_cpp17_input_iterator<_InpIter>::value>::type*)
 {
     for (; __f != __l; ++__f)
 #ifdef _LIBCPP_CXX03_LANG
diff --git a/include/regex b/include/regex
index a117c50..bd04017 100644
--- a/include/regex
+++ b/include/regex
@@ -2748,12 +2748,7 @@
 
     template <class _InputIterator>
         _LIBCPP_INLINE_VISIBILITY
-        typename enable_if
-        <
-             __is_cpp17_input_iterator  <_InputIterator>::value &&
-            !__is_cpp17_forward_iterator<_InputIterator>::value,
-            basic_regex&
-        >::type
+        typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value, basic_regex&>::type
         assign(_InputIterator __first, _InputIterator __last,
                             flag_type __f = regex_constants::ECMAScript)
         {
diff --git a/include/vector b/include/vector
index f5c0901..b3901fb 100644
--- a/include/vector
+++ b/include/vector
@@ -393,16 +393,14 @@
 
     template <class _InputIterator>
         vector(_InputIterator __first,
-               typename enable_if<__is_cpp17_input_iterator  <_InputIterator>::value &&
-                                 !__is_cpp17_forward_iterator<_InputIterator>::value &&
+               typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
                                  is_constructible<
                                     value_type,
                                     typename iterator_traits<_InputIterator>::reference>::value,
                                  _InputIterator>::type __last);
     template <class _InputIterator>
         vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
-               typename enable_if<__is_cpp17_input_iterator  <_InputIterator>::value &&
-                                 !__is_cpp17_forward_iterator<_InputIterator>::value &&
+               typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
                                  is_constructible<
                                     value_type,
                                     typename iterator_traits<_InputIterator>::reference>::value>::type* = 0);
@@ -465,10 +463,7 @@
         _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
 
     template <class _InputIterator>
-        typename enable_if
-        <
-             __is_cpp17_input_iterator  <_InputIterator>::value &&
-            !__is_cpp17_forward_iterator<_InputIterator>::value &&
+        typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
             is_constructible<
                  value_type,
                  typename iterator_traits<_InputIterator>::reference>::value,
@@ -598,10 +593,7 @@
 
     iterator insert(const_iterator __position, size_type __n, const_reference __x);
     template <class _InputIterator>
-        typename enable_if
-        <
-             __is_cpp17_input_iterator  <_InputIterator>::value &&
-            !__is_cpp17_forward_iterator<_InputIterator>::value &&
+        typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
             is_constructible<
                  value_type,
                  typename iterator_traits<_InputIterator>::reference>::value,
@@ -1090,8 +1082,7 @@
 template <class _Tp, class _Allocator>
 template <class _InputIterator>
 vector<_Tp, _Allocator>::vector(_InputIterator __first,
-       typename enable_if<__is_cpp17_input_iterator  <_InputIterator>::value &&
-                         !__is_cpp17_forward_iterator<_InputIterator>::value &&
+       typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
                          is_constructible<
                             value_type,
                             typename iterator_traits<_InputIterator>::reference>::value,
@@ -1105,8 +1096,7 @@
 template <class _Tp, class _Allocator>
 template <class _InputIterator>
 vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
-       typename enable_if<__is_cpp17_input_iterator  <_InputIterator>::value &&
-                         !__is_cpp17_forward_iterator<_InputIterator>::value &&
+       typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
                          is_constructible<
                             value_type,
                             typename iterator_traits<_InputIterator>::reference>::value>::type*)
@@ -1301,10 +1291,7 @@
 
 template <class _Tp, class _Allocator>
 template <class _InputIterator>
-typename enable_if
-<
-     __is_cpp17_input_iterator  <_InputIterator>::value &&
-    !__is_cpp17_forward_iterator<_InputIterator>::value &&
+typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
     is_constructible<
        _Tp,
        typename iterator_traits<_InputIterator>::reference>::value,
@@ -1751,10 +1738,7 @@
 
 template <class _Tp, class _Allocator>
 template <class _InputIterator>
-typename enable_if
-<
-     __is_cpp17_input_iterator  <_InputIterator>::value &&
-    !__is_cpp17_forward_iterator<_InputIterator>::value &&
+typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value &&
     is_constructible<
        _Tp,
        typename iterator_traits<_InputIterator>::reference>::value,
@@ -2057,12 +2041,10 @@
     vector(size_type __n, const value_type& __v, const allocator_type& __a);
     template <class _InputIterator>
         vector(_InputIterator __first, _InputIterator __last,
-               typename enable_if<__is_cpp17_input_iterator  <_InputIterator>::value &&
-                                 !__is_cpp17_forward_iterator<_InputIterator>::value>::type* = 0);
+               typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type* = 0);
     template <class _InputIterator>
         vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
-               typename enable_if<__is_cpp17_input_iterator  <_InputIterator>::value &&
-                                 !__is_cpp17_forward_iterator<_InputIterator>::value>::type* = 0);
+               typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type* = 0);
     template <class _ForwardIterator>
         vector(_ForwardIterator __first, _ForwardIterator __last,
                typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0);
@@ -2097,10 +2079,7 @@
         _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value));
 
     template <class _InputIterator>
-        typename enable_if
-        <
-            __is_cpp17_input_iterator<_InputIterator>::value &&
-           !__is_cpp17_forward_iterator<_InputIterator>::value,
+        typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
            void
         >::type
         assign(_InputIterator __first, _InputIterator __last);
@@ -2212,10 +2191,7 @@
     iterator insert(const_iterator __position, const value_type& __x);
     iterator insert(const_iterator __position, size_type __n, const value_type& __x);
     template <class _InputIterator>
-        typename enable_if
-        <
-             __is_cpp17_input_iterator  <_InputIterator>::value &&
-            !__is_cpp17_forward_iterator<_InputIterator>::value,
+        typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
             iterator
         >::type
         insert(const_iterator __position, _InputIterator __first, _InputIterator __last);
@@ -2522,8 +2498,7 @@
 template <class _Allocator>
 template <class _InputIterator>
 vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
-       typename enable_if<__is_cpp17_input_iterator  <_InputIterator>::value &&
-                         !__is_cpp17_forward_iterator<_InputIterator>::value>::type*)
+       typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type*)
     : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, __default_init_tag())
@@ -2549,8 +2524,7 @@
 template <class _Allocator>
 template <class _InputIterator>
 vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
-       typename enable_if<__is_cpp17_input_iterator  <_InputIterator>::value &&
-                         !__is_cpp17_forward_iterator<_InputIterator>::value>::type*)
+       typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type*)
     : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, static_cast<__storage_allocator>(__a))
@@ -2787,10 +2761,7 @@
 
 template <class _Allocator>
 template <class _InputIterator>
-typename enable_if
-<
-    __is_cpp17_input_iterator<_InputIterator>::value &&
-   !__is_cpp17_forward_iterator<_InputIterator>::value,
+typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
    void
 >::type
 vector<bool, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
@@ -2941,10 +2912,7 @@
 
 template <class _Allocator>
 template <class _InputIterator>
-typename enable_if
-<
-     __is_cpp17_input_iterator  <_InputIterator>::value &&
-    !__is_cpp17_forward_iterator<_InputIterator>::value,
+typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value,
     typename vector<bool, _Allocator>::iterator
 >::type
 vector<bool, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last)