diff --git a/libcxx/include/__iterator/iterator_traits.h b/libcxx/include/__iterator/iterator_traits.h --- a/libcxx/include/__iterator/iterator_traits.h +++ b/libcxx/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 +struct __is_exactly_cpp17_forward_iterator + : public integral_constant::value && + !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value> {}; + template using __iter_value_type = typename iterator_traits<_InputIterator>::value_type; diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer --- a/libcxx/include/__split_buffer +++ b/libcxx/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 - __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 __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value> diff --git a/libcxx/include/deque b/libcxx/include/deque --- a/libcxx/include/deque +++ b/libcxx/include/deque @@ -1464,12 +1464,10 @@ iterator insert(const_iterator __p, size_type __n, const value_type& __v); template 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 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 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 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 void __append(_ForIter __f, _ForIter __l, typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type* = 0); @@ -2266,8 +2263,7 @@ template 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 __buf(__base::__alloc()); __buf.__construct_at_end(__f, __l); @@ -2279,8 +2275,7 @@ template 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 __buf(__n, 0, __base::__alloc()); @@ -2362,8 +2357,7 @@ template 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/libcxx/include/regex b/libcxx/include/regex --- a/libcxx/include/regex +++ b/libcxx/include/regex @@ -2748,12 +2748,7 @@ template _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/libcxx/include/vector b/libcxx/include/vector --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -393,16 +393,14 @@ template 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 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 - 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 - 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 template 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 template 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 template -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 template -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 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 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 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 - 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 - 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 template vector::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 template vector::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 template -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::assign(_InputIterator __first, _InputIterator __last) @@ -2941,10 +2912,7 @@ template template -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::iterator >::type vector::insert(const_iterator __position, _InputIterator __first, _InputIterator __last) diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp --- a/libcxx/test/std/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp +++ b/libcxx/test/std/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp @@ -106,13 +106,13 @@ #endif } +template void test_emplacable_concept() { #if TEST_STD_VER >= 11 int arr1[] = {42}; int arr2[] = {1, 101, 42}; { using T = EmplaceConstructibleMoveableAndAssignable; - using It = random_access_iterator; { std::deque v; v.assign(It(arr1), It(std::end(arr1))); @@ -126,32 +126,22 @@ assert(v[2].value == 42); } } - { - using T = EmplaceConstructibleMoveableAndAssignable; - using It = cpp17_input_iterator; - { - std::deque v; - v.assign(It(arr1), It(std::end(arr1))); - assert(v[0].copied == 0); - assert(v[0].value == 42); - } - { - std::deque v; - v.assign(It(arr2), It(std::end(arr2))); - //assert(v[0].copied == 0); - assert(v[0].value == 1); - //assert(v[1].copied == 0); - assert(v[1].value == 101); - assert(v[2].copied == 0); - assert(v[2].value == 42); - } - } #endif } +void test_iterators() { + test_emplacable_concept >(); + test_emplacable_concept >(); + test_emplacable_concept >(); + test_emplacable_concept >(); +#if TEST_STD_VER > 17 + test_emplacable_concept >(); +#endif + test_emplacable_concept(); +} + int main(int, char**) { basic_test(); - test_emplacable_concept(); return 0; }