diff --git a/libcxx/include/__algorithm/adjacent_find.h b/libcxx/include/__algorithm/adjacent_find.h --- a/libcxx/include/__algorithm/adjacent_find.h +++ b/libcxx/include/__algorithm/adjacent_find.h @@ -13,6 +13,7 @@ #include <__algorithm/comp.h> #include <__algorithm/iterator_operations.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__utility/move.h> @@ -39,6 +40,7 @@ template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); return std::__adjacent_find(std::move(__first), std::move(__last), __pred); } diff --git a/libcxx/include/__algorithm/all_of.h b/libcxx/include/__algorithm/all_of.h --- a/libcxx/include/__algorithm/all_of.h +++ b/libcxx/include/__algorithm/all_of.h @@ -11,6 +11,7 @@ #define _LIBCPP___ALGORITHM_ALL_OF_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,6 +22,7 @@ template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); for (; __first != __last; ++__first) if (!__pred(*__first)) return false; diff --git a/libcxx/include/__algorithm/any_of.h b/libcxx/include/__algorithm/any_of.h --- a/libcxx/include/__algorithm/any_of.h +++ b/libcxx/include/__algorithm/any_of.h @@ -11,6 +11,7 @@ #define _LIBCPP___ALGORITHM_ANY_OF_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,6 +22,7 @@ template _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); for (; __first != __last; ++__first) if (__pred(*__first)) return true; diff --git a/libcxx/include/__algorithm/binary_search.h b/libcxx/include/__algorithm/binary_search.h --- a/libcxx/include/__algorithm/binary_search.h +++ b/libcxx/include/__algorithm/binary_search.h @@ -13,6 +13,7 @@ #include <__algorithm/comp_ref_type.h> #include <__algorithm/lower_bound.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -27,6 +28,7 @@ bool binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); __first = std::lower_bound<_ForwardIterator, _Tp, __comp_ref_type<_Compare> >(__first, __last, __value, __comp); return __first != __last && !__comp(__value, *__first); } diff --git a/libcxx/include/__algorithm/copy.h b/libcxx/include/__algorithm/copy.h --- a/libcxx/include/__algorithm/copy.h +++ b/libcxx/include/__algorithm/copy.h @@ -14,6 +14,7 @@ #include <__algorithm/iterator_operations.h> #include <__algorithm/min.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/segmented_iterator.h> #include <__type_traits/common_type.h> #include <__utility/move.h> @@ -114,6 +115,8 @@ template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(*__first)); return std::__copy<_ClassicAlgPolicy>(__first, __last, __result).second; } diff --git a/libcxx/include/__algorithm/copy_backward.h b/libcxx/include/__algorithm/copy_backward.h --- a/libcxx/include/__algorithm/copy_backward.h +++ b/libcxx/include/__algorithm/copy_backward.h @@ -13,6 +13,7 @@ #include <__algorithm/iterator_operations.h> #include <__algorithm/min.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/segmented_iterator.h> #include <__type_traits/common_type.h> #include <__type_traits/is_copy_constructible.h> @@ -129,8 +130,8 @@ copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) { - static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value && - std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible."); + _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(_BidirectionalIterator1); + _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(_BidirectionalIterator2); return std::__copy_backward<_ClassicAlgPolicy>( std::move(__first), std::move(__last), std::move(__result)).second; diff --git a/libcxx/include/__algorithm/copy_if.h b/libcxx/include/__algorithm/copy_if.h --- a/libcxx/include/__algorithm/copy_if.h +++ b/libcxx/include/__algorithm/copy_if.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_COPY_IF_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -23,6 +24,8 @@ copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(*__first)); for (; __first != __last; ++__first) { if (__pred(*__first)) diff --git a/libcxx/include/__algorithm/copy_n.h b/libcxx/include/__algorithm/copy_n.h --- a/libcxx/include/__algorithm/copy_n.h +++ b/libcxx/include/__algorithm/copy_n.h @@ -11,6 +11,7 @@ #include <__algorithm/copy.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__type_traits/enable_if.h> #include <__utility/convert_to_integral.h> @@ -31,6 +32,8 @@ >::type copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(*__first)); typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; _IntegralSize __n = __orig_n; if (__n > 0) @@ -56,6 +59,8 @@ >::type copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) { + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_InputIterator); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(*__first)); typedef typename iterator_traits<_InputIterator>::difference_type difference_type; typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; _IntegralSize __n = __orig_n; diff --git a/libcxx/include/__algorithm/count.h b/libcxx/include/__algorithm/count.h --- a/libcxx/include/__algorithm/count.h +++ b/libcxx/include/__algorithm/count.h @@ -11,6 +11,7 @@ #define _LIBCPP___ALGORITHM_COUNT_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -23,6 +24,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 typename iterator_traits<_InputIterator>::difference_type count(_InputIterator __first, _InputIterator __last, const _Tp& __value) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); typename iterator_traits<_InputIterator>::difference_type __r(0); for (; __first != __last; ++__first) if (*__first == __value) diff --git a/libcxx/include/__algorithm/count_if.h b/libcxx/include/__algorithm/count_if.h --- a/libcxx/include/__algorithm/count_if.h +++ b/libcxx/include/__algorithm/count_if.h @@ -11,6 +11,7 @@ #define _LIBCPP___ALGORITHM_COUNT_IF_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -23,6 +24,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 typename iterator_traits<_InputIterator>::difference_type count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); typename iterator_traits<_InputIterator>::difference_type __r(0); for (; __first != __last; ++__first) if (__pred(*__first)) diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h --- a/libcxx/include/__algorithm/equal.h +++ b/libcxx/include/__algorithm/equal.h @@ -15,6 +15,7 @@ #include <__config> #include <__functional/identity.h> #include <__functional/invoke.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__string/constexpr_c_functions.h> @@ -56,6 +57,8 @@ template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator1); + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator2); return std::__equal_iter_impl( std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred); } @@ -125,6 +128,8 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator1); + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator2); return _VSTD::__equal<_BinaryPredicate&>( __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_InputIterator1>::iterator_category(), typename iterator_traits<_InputIterator2>::iterator_category()); diff --git a/libcxx/include/__algorithm/equal_range.h b/libcxx/include/__algorithm/equal_range.h --- a/libcxx/include/__algorithm/equal_range.h +++ b/libcxx/include/__algorithm/equal_range.h @@ -19,6 +19,7 @@ #include <__functional/identity.h> #include <__functional/invoke.h> #include <__iterator/advance.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__iterator/next.h> @@ -60,10 +61,10 @@ template _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, "The comparator has to be callable"); - static_assert(is_copy_constructible<_ForwardIterator>::value, - "Iterator has to be copy constructible"); + return std::__equal_range<_ClassicAlgPolicy>( std::move(__first), std::move(__last), diff --git a/libcxx/include/__algorithm/fill.h b/libcxx/include/__algorithm/fill.h --- a/libcxx/include/__algorithm/fill.h +++ b/libcxx/include/__algorithm/fill.h @@ -11,6 +11,7 @@ #include <__algorithm/fill_n.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -43,6 +44,7 @@ void fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); _VSTD::__fill(__first, __last, __value, typename iterator_traits<_ForwardIterator>::iterator_category()); } diff --git a/libcxx/include/__algorithm/fill_n.h b/libcxx/include/__algorithm/fill_n.h --- a/libcxx/include/__algorithm/fill_n.h +++ b/libcxx/include/__algorithm/fill_n.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_FILL_N_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__utility/convert_to_integral.h> @@ -36,6 +37,7 @@ _OutputIterator fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) { + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, const _Tp&); return _VSTD::__fill_n(__first, _VSTD::__convert_to_integral(__n), __value); } diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h --- a/libcxx/include/__algorithm/find.h +++ b/libcxx/include/__algorithm/find.h @@ -14,6 +14,7 @@ #include <__config> #include <__functional/identity.h> #include <__functional/invoke.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__string/constexpr_c_functions.h> #include <__type_traits/is_same.h> @@ -67,6 +68,7 @@ template _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find(_InputIterator __first, _InputIterator __last, const _Tp& __value) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); __identity __proj; return std::__rewrap_iter( __first, std::__find_impl(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __value, __proj)); diff --git a/libcxx/include/__algorithm/find_end.h b/libcxx/include/__algorithm/find_end.h --- a/libcxx/include/__algorithm/find_end.h +++ b/libcxx/include/__algorithm/find_end.h @@ -17,6 +17,7 @@ #include <__functional/identity.h> #include <__functional/invoke.h> #include <__iterator/advance.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__iterator/next.h> #include <__iterator/reverse_iterator.h> @@ -212,6 +213,8 @@ _ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2); return std::__find_end_classic(__first1, __last1, __first2, __last2, __pred); } diff --git a/libcxx/include/__algorithm/find_first_of.h b/libcxx/include/__algorithm/find_first_of.h --- a/libcxx/include/__algorithm/find_first_of.h +++ b/libcxx/include/__algorithm/find_first_of.h @@ -12,6 +12,7 @@ #include <__algorithm/comp.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -34,16 +35,20 @@ return __last1; } -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 -find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __pred) { +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +find_first_of(_InputIterator __first1, _InputIterator __last1, _ForwardIterator __first2, + _ForwardIterator __last2, _BinaryPredicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred); } -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of( - _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { +template +_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find_first_of( + _InputIterator __first1, _InputIterator __last1, _ForwardIterator __first2, _ForwardIterator __last2) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); return std::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to()); } diff --git a/libcxx/include/__algorithm/find_if.h b/libcxx/include/__algorithm/find_if.h --- a/libcxx/include/__algorithm/find_if.h +++ b/libcxx/include/__algorithm/find_if.h @@ -11,6 +11,7 @@ #define _LIBCPP___ALGORITHM_FIND_IF_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,6 +22,7 @@ template _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); for (; __first != __last; ++__first) if (__pred(*__first)) break; diff --git a/libcxx/include/__algorithm/find_if_not.h b/libcxx/include/__algorithm/find_if_not.h --- a/libcxx/include/__algorithm/find_if_not.h +++ b/libcxx/include/__algorithm/find_if_not.h @@ -11,6 +11,7 @@ #define _LIBCPP___ALGORITHM_FIND_IF_NOT_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,6 +22,7 @@ template _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); for (; __first != __last; ++__first) if (!__pred(*__first)) break; diff --git a/libcxx/include/__algorithm/for_each.h b/libcxx/include/__algorithm/for_each.h --- a/libcxx/include/__algorithm/for_each.h +++ b/libcxx/include/__algorithm/for_each.h @@ -11,6 +11,7 @@ #define _LIBCPP___ALGORITHM_FOR_EACH_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -22,6 +23,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _Function for_each(_InputIterator __first, _InputIterator __last, _Function __f) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); for (; __first != __last; ++__first) __f(*__first); return __f; diff --git a/libcxx/include/__algorithm/for_each_n.h b/libcxx/include/__algorithm/for_each_n.h --- a/libcxx/include/__algorithm/for_each_n.h +++ b/libcxx/include/__algorithm/for_each_n.h @@ -11,6 +11,7 @@ #define _LIBCPP___ALGORITHM_FOR_EACH_N_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__utility/convert_to_integral.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -25,6 +26,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator for_each_n(_InputIterator __first, _Size __orig_n, _Function __f) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; _IntegralSize __n = __orig_n; while (__n > 0) { diff --git a/libcxx/include/__algorithm/generate.h b/libcxx/include/__algorithm/generate.h --- a/libcxx/include/__algorithm/generate.h +++ b/libcxx/include/__algorithm/generate.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_GENERATE_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -22,6 +23,7 @@ void generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); for (; __first != __last; ++__first) *__first = __gen(); } diff --git a/libcxx/include/__algorithm/generate_n.h b/libcxx/include/__algorithm/generate_n.h --- a/libcxx/include/__algorithm/generate_n.h +++ b/libcxx/include/__algorithm/generate_n.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_GENERATE_N_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__utility/convert_to_integral.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -23,6 +24,7 @@ _OutputIterator generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) { + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(__gen())); typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; _IntegralSize __n = __orig_n; for (; __n > 0; ++__first, (void) --__n) diff --git a/libcxx/include/__algorithm/includes.h b/libcxx/include/__algorithm/includes.h --- a/libcxx/include/__algorithm/includes.h +++ b/libcxx/include/__algorithm/includes.h @@ -14,6 +14,7 @@ #include <__config> #include <__functional/identity.h> #include <__functional/invoke.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__type_traits/is_callable.h> #include <__utility/move.h> @@ -45,6 +46,8 @@ _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator1); + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator2); static_assert(__is_callable<_Compare, decltype(*__first1), decltype(*__first2)>::value, "Comparator has to be callable"); diff --git a/libcxx/include/__algorithm/inplace_merge.h b/libcxx/include/__algorithm/inplace_merge.h --- a/libcxx/include/__algorithm/inplace_merge.h +++ b/libcxx/include/__algorithm/inplace_merge.h @@ -20,6 +20,7 @@ #include <__config> #include <__functional/identity.h> #include <__iterator/advance.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__iterator/reverse_iterator.h> @@ -237,6 +238,7 @@ template inline _LIBCPP_HIDE_FROM_ABI void inplace_merge( _BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(_BidirectionalIterator); std::__inplace_merge<_ClassicAlgPolicy>( std::move(__first), std::move(__middle), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)); } diff --git a/libcxx/include/__algorithm/is_heap.h b/libcxx/include/__algorithm/is_heap.h --- a/libcxx/include/__algorithm/is_heap.h +++ b/libcxx/include/__algorithm/is_heap.h @@ -13,6 +13,7 @@ #include <__algorithm/comp_ref_type.h> #include <__algorithm/is_heap_until.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -27,6 +28,7 @@ bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator); return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)) == __last; } diff --git a/libcxx/include/__algorithm/is_heap_until.h b/libcxx/include/__algorithm/is_heap_until.h --- a/libcxx/include/__algorithm/is_heap_until.h +++ b/libcxx/include/__algorithm/is_heap_until.h @@ -12,6 +12,7 @@ #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -51,6 +52,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator); return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)); } @@ -58,6 +60,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) { + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator); return _VSTD::__is_heap_until(__first, __last, __less<>()); } diff --git a/libcxx/include/__algorithm/is_partitioned.h b/libcxx/include/__algorithm/is_partitioned.h --- a/libcxx/include/__algorithm/is_partitioned.h +++ b/libcxx/include/__algorithm/is_partitioned.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_IS_PARTITIONED_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,6 +22,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); for (; __first != __last; ++__first) if (!__pred(*__first)) break; diff --git a/libcxx/include/__algorithm/is_permutation.h b/libcxx/include/__algorithm/is_permutation.h --- a/libcxx/include/__algorithm/is_permutation.h +++ b/libcxx/include/__algorithm/is_permutation.h @@ -16,6 +16,7 @@ #include <__functional/identity.h> #include <__functional/invoke.h> #include <__iterator/concepts.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__iterator/next.h> @@ -188,6 +189,8 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2); static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, "The predicate has to be callable"); @@ -208,6 +211,8 @@ template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2); return std::__is_permutation<_ClassicAlgPolicy>( std::move(__first1), std::move(__last1), @@ -223,6 +228,8 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2); static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, "The predicate has to be callable"); diff --git a/libcxx/include/__algorithm/is_sorted.h b/libcxx/include/__algorithm/is_sorted.h --- a/libcxx/include/__algorithm/is_sorted.h +++ b/libcxx/include/__algorithm/is_sorted.h @@ -13,6 +13,7 @@ #include <__algorithm/comp_ref_type.h> #include <__algorithm/is_sorted_until.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -27,6 +28,7 @@ bool is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); return _VSTD::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp) == __last; } diff --git a/libcxx/include/__algorithm/is_sorted_until.h b/libcxx/include/__algorithm/is_sorted_until.h --- a/libcxx/include/__algorithm/is_sorted_until.h +++ b/libcxx/include/__algorithm/is_sorted_until.h @@ -12,6 +12,7 @@ #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -41,6 +42,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); return _VSTD::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp); } diff --git a/libcxx/include/__algorithm/iter_swap.h b/libcxx/include/__algorithm/iter_swap.h --- a/libcxx/include/__algorithm/iter_swap.h +++ b/libcxx/include/__algorithm/iter_swap.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_ITER_SWAP_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__utility/declval.h> #include <__utility/swap.h> @@ -24,6 +25,8 @@ _ForwardIterator2 __b) // _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b))) _NOEXCEPT_(_NOEXCEPT_(swap(*std::declval<_ForwardIterator1>(), *std::declval<_ForwardIterator2>()))) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2); swap(*__a, *__b); } diff --git a/libcxx/include/__algorithm/lexicographical_compare.h b/libcxx/include/__algorithm/lexicographical_compare.h --- a/libcxx/include/__algorithm/lexicographical_compare.h +++ b/libcxx/include/__algorithm/lexicographical_compare.h @@ -12,6 +12,7 @@ #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -42,6 +43,8 @@ lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator1); + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator2); return _VSTD::__lexicographical_compare<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __comp); } diff --git a/libcxx/include/__algorithm/lexicographical_compare_three_way.h b/libcxx/include/__algorithm/lexicographical_compare_three_way.h --- a/libcxx/include/__algorithm/lexicographical_compare_three_way.h +++ b/libcxx/include/__algorithm/lexicographical_compare_three_way.h @@ -15,6 +15,7 @@ #include <__compare/ordering.h> #include <__concepts/arithmetic.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__type_traits/common_type.h> #include <__type_traits/is_copy_constructible.h> @@ -37,11 +38,6 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_fast_path( _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp) -> decltype(__comp(*__first1, *__first2)) { - static_assert( - signed_integral<__iter_diff_t<_InputIterator1>>, "Using a non-integral difference_type is undefined behavior."); - static_assert( - signed_integral<__iter_diff_t<_InputIterator2>>, "Using a non-integral difference_type is undefined behavior."); - using _Len1 = __iter_diff_t<_InputIterator1>; using _Len2 = __iter_diff_t<_InputIterator2>; using _Common = common_type_t<_Len1, _Len2>; @@ -95,8 +91,9 @@ -> decltype(__comp(*__first1, *__first2)) { static_assert(__comparison_category, "The comparator passed to lexicographical_compare_three_way must return a comparison category type."); - static_assert(std::is_copy_constructible_v<_InputIterator1>, "Iterators must be copy constructible."); - static_assert(std::is_copy_constructible_v<_InputIterator2>, "Iterators must be copy constructible."); + static_assert(__cpp17_input_iterator<_InputIterator1>); + static_assert(__cpp17_input_iterator<_InputIterator2>); + __three_way_comp_ref_type<_Cmp> __wrapped_comp_ref(__comp); if constexpr (__has_random_access_iterator_category<_InputIterator1>::value && __has_random_access_iterator_category<_InputIterator2>::value) { diff --git a/libcxx/include/__algorithm/lower_bound.h b/libcxx/include/__algorithm/lower_bound.h --- a/libcxx/include/__algorithm/lower_bound.h +++ b/libcxx/include/__algorithm/lower_bound.h @@ -16,6 +16,7 @@ #include <__functional/identity.h> #include <__functional/invoke.h> #include <__iterator/advance.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__type_traits/is_callable.h> @@ -49,6 +50,7 @@ template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, "The comparator has to be callable"); auto __proj = std::__identity(); diff --git a/libcxx/include/__algorithm/make_heap.h b/libcxx/include/__algorithm/make_heap.h --- a/libcxx/include/__algorithm/make_heap.h +++ b/libcxx/include/__algorithm/make_heap.h @@ -14,6 +14,7 @@ #include <__algorithm/iterator_operations.h> #include <__algorithm/sift_down.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__utility/move.h> @@ -41,6 +42,7 @@ template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator); std::__make_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } diff --git a/libcxx/include/__algorithm/max_element.h b/libcxx/include/__algorithm/max_element.h --- a/libcxx/include/__algorithm/max_element.h +++ b/libcxx/include/__algorithm/max_element.h @@ -12,6 +12,7 @@ #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -40,6 +41,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); return _VSTD::__max_element<__comp_ref_type<_Compare> >(__first, __last, __comp); } diff --git a/libcxx/include/__algorithm/merge.h b/libcxx/include/__algorithm/merge.h --- a/libcxx/include/__algorithm/merge.h +++ b/libcxx/include/__algorithm/merge.h @@ -13,6 +13,7 @@ #include <__algorithm/comp_ref_type.h> #include <__algorithm/copy.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -51,6 +52,9 @@ merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator1); + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator2); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(*__first1)); return _VSTD::__merge<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __result, __comp); } diff --git a/libcxx/include/__algorithm/min_element.h b/libcxx/include/__algorithm/min_element.h --- a/libcxx/include/__algorithm/min_element.h +++ b/libcxx/include/__algorithm/min_element.h @@ -14,6 +14,7 @@ #include <__config> #include <__functional/identity.h> #include <__functional/invoke.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__type_traits/is_callable.h> #include <__utility/move.h> @@ -49,8 +50,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { - static_assert(__has_forward_iterator_category<_ForwardIterator>::value, - "std::min_element requires a ForwardIterator"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, "The comparator has to be callable"); diff --git a/libcxx/include/__algorithm/minmax_element.h b/libcxx/include/__algorithm/minmax_element.h --- a/libcxx/include/__algorithm/minmax_element.h +++ b/libcxx/include/__algorithm/minmax_element.h @@ -13,6 +13,7 @@ #include <__config> #include <__functional/identity.h> #include <__functional/invoke.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__type_traits/is_callable.h> #include <__utility/pair.h> @@ -83,8 +84,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { - static_assert(__has_forward_iterator_category<_ForwardIterator>::value, - "std::minmax_element requires a ForwardIterator"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, "The comparator has to be callable"); auto __proj = __identity(); diff --git a/libcxx/include/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h --- a/libcxx/include/__algorithm/mismatch.h +++ b/libcxx/include/__algorithm/mismatch.h @@ -12,6 +12,7 @@ #include <__algorithm/comp.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__utility/pair.h> @@ -25,6 +26,8 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator1); + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator2); for (; __first1 != __last1; ++__first1, (void)++__first2) if (!__pred(*__first1, *__first2)) break; @@ -44,6 +47,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator1); + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator2); for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) if (!__pred(*__first1, *__first2)) break; diff --git a/libcxx/include/__algorithm/move.h b/libcxx/include/__algorithm/move.h --- a/libcxx/include/__algorithm/move.h +++ b/libcxx/include/__algorithm/move.h @@ -14,6 +14,7 @@ #include <__algorithm/iterator_operations.h> #include <__algorithm/min.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/segmented_iterator.h> #include <__type_traits/common_type.h> #include <__type_traits/is_copy_constructible.h> @@ -116,8 +117,8 @@ template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { - static_assert(is_copy_constructible<_InputIterator>::value, "Iterators has to be copy constructible."); - static_assert(is_copy_constructible<_OutputIterator>::value, "The output iterator has to be copy constructible."); + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(std::move(*__first))); return std::__move<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second; } diff --git a/libcxx/include/__algorithm/move_backward.h b/libcxx/include/__algorithm/move_backward.h --- a/libcxx/include/__algorithm/move_backward.h +++ b/libcxx/include/__algorithm/move_backward.h @@ -13,6 +13,7 @@ #include <__algorithm/iterator_operations.h> #include <__algorithm/min.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/segmented_iterator.h> #include <__type_traits/common_type.h> #include <__type_traits/is_copy_constructible.h> @@ -129,6 +130,8 @@ template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator2 move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) { + _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(_BidirectionalIterator1); + _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(_BidirectionalIterator2); return std::__move_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second; } diff --git a/libcxx/include/__algorithm/next_permutation.h b/libcxx/include/__algorithm/next_permutation.h --- a/libcxx/include/__algorithm/next_permutation.h +++ b/libcxx/include/__algorithm/next_permutation.h @@ -14,6 +14,7 @@ #include <__algorithm/iterator_operations.h> #include <__algorithm/reverse.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__utility/move.h> #include <__utility/pair.h> @@ -60,6 +61,7 @@ bool next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(_BidirectionalIterator); return std::__next_permutation<_ClassicAlgPolicy>( std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second; } diff --git a/libcxx/include/__algorithm/none_of.h b/libcxx/include/__algorithm/none_of.h --- a/libcxx/include/__algorithm/none_of.h +++ b/libcxx/include/__algorithm/none_of.h @@ -11,6 +11,7 @@ #define _LIBCPP___ALGORITHM_NONE_OF_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -21,6 +22,7 @@ template _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); for (; __first != __last; ++__first) if (__pred(*__first)) return false; diff --git a/libcxx/include/__algorithm/nth_element.h b/libcxx/include/__algorithm/nth_element.h --- a/libcxx/include/__algorithm/nth_element.h +++ b/libcxx/include/__algorithm/nth_element.h @@ -16,6 +16,7 @@ #include <__config> #include <__debug> #include <__debug_utils/randomize_range.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__utility/move.h> @@ -243,6 +244,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator); std::__nth_element_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__nth), std::move(__last), __comp); } diff --git a/libcxx/include/__algorithm/partial_sort.h b/libcxx/include/__algorithm/partial_sort.h --- a/libcxx/include/__algorithm/partial_sort.h +++ b/libcxx/include/__algorithm/partial_sort.h @@ -18,6 +18,7 @@ #include <__config> #include <__debug> #include <__debug_utils/randomize_range.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__type_traits/is_copy_assignable.h> #include <__type_traits/is_copy_constructible.h> @@ -77,8 +78,7 @@ partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) { - static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); - static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator); (void)std::__partial_sort<_ClassicAlgPolicy>(std::move(__first), std::move(__middle), std::move(__last), __comp); } diff --git a/libcxx/include/__algorithm/partial_sort_copy.h b/libcxx/include/__algorithm/partial_sort_copy.h --- a/libcxx/include/__algorithm/partial_sort_copy.h +++ b/libcxx/include/__algorithm/partial_sort_copy.h @@ -19,6 +19,7 @@ #include <__config> #include <__functional/identity.h> #include <__functional/invoke.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__type_traits/is_callable.h> #include <__utility/move.h> @@ -65,6 +66,7 @@ partial_sort_copy(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator); static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__result_first)>::value, "Comparator has to be callable"); diff --git a/libcxx/include/__algorithm/partition.h b/libcxx/include/__algorithm/partition.h --- a/libcxx/include/__algorithm/partition.h +++ b/libcxx/include/__algorithm/partition.h @@ -11,6 +11,7 @@ #include <__algorithm/iterator_operations.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__utility/move.h> #include <__utility/pair.h> @@ -87,6 +88,7 @@ _ForwardIterator partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category; auto __result = std::__partition<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred, _IterCategory()); return __result.first; diff --git a/libcxx/include/__algorithm/partition_copy.h b/libcxx/include/__algorithm/partition_copy.h --- a/libcxx/include/__algorithm/partition_copy.h +++ b/libcxx/include/__algorithm/partition_copy.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_PARTITION_COPY_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__utility/pair.h> @@ -26,6 +27,10 @@ _OutputIterator1 __out_true, _OutputIterator2 __out_false, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator1, decltype(*__first)); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator2, decltype(*__first)); + for (; __first != __last; ++__first) { if (__pred(*__first)) diff --git a/libcxx/include/__algorithm/partition_point.h b/libcxx/include/__algorithm/partition_point.h --- a/libcxx/include/__algorithm/partition_point.h +++ b/libcxx/include/__algorithm/partition_point.h @@ -12,6 +12,7 @@ #include <__algorithm/half_positive.h> #include <__config> #include <__iterator/advance.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> @@ -25,6 +26,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; difference_type __len = _VSTD::distance(__first, __last); while (__len != 0) diff --git a/libcxx/include/__algorithm/pop_heap.h b/libcxx/include/__algorithm/pop_heap.h --- a/libcxx/include/__algorithm/pop_heap.h +++ b/libcxx/include/__algorithm/pop_heap.h @@ -16,6 +16,7 @@ #include <__algorithm/sift_down.h> #include <__assert> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__type_traits/is_copy_assignable.h> #include <__type_traits/is_copy_constructible.h> @@ -55,8 +56,7 @@ template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); - static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator); typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first; std::__pop_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp, __len); diff --git a/libcxx/include/__algorithm/prev_permutation.h b/libcxx/include/__algorithm/prev_permutation.h --- a/libcxx/include/__algorithm/prev_permutation.h +++ b/libcxx/include/__algorithm/prev_permutation.h @@ -14,6 +14,7 @@ #include <__algorithm/iterator_operations.h> #include <__algorithm/reverse.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__utility/move.h> #include <__utility/pair.h> @@ -61,6 +62,7 @@ bool prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(_BidirectionalIterator); return std::__prev_permutation<_ClassicAlgPolicy>( std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second; } diff --git a/libcxx/include/__algorithm/remove.h b/libcxx/include/__algorithm/remove.h --- a/libcxx/include/__algorithm/remove.h +++ b/libcxx/include/__algorithm/remove.h @@ -12,6 +12,7 @@ #include <__algorithm/find.h> #include <__algorithm/find_if.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -24,6 +25,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); __first = _VSTD::find(__first, __last, __value); if (__first != __last) { diff --git a/libcxx/include/__algorithm/remove_copy.h b/libcxx/include/__algorithm/remove_copy.h --- a/libcxx/include/__algorithm/remove_copy.h +++ b/libcxx/include/__algorithm/remove_copy.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_REMOVE_COPY_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -22,6 +23,8 @@ _OutputIterator remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(*__first)); for (; __first != __last; ++__first) { if (!(*__first == __value)) diff --git a/libcxx/include/__algorithm/remove_copy_if.h b/libcxx/include/__algorithm/remove_copy_if.h --- a/libcxx/include/__algorithm/remove_copy_if.h +++ b/libcxx/include/__algorithm/remove_copy_if.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -22,6 +23,7 @@ _OutputIterator remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); for (; __first != __last; ++__first) { if (!__pred(*__first)) diff --git a/libcxx/include/__algorithm/remove_if.h b/libcxx/include/__algorithm/remove_if.h --- a/libcxx/include/__algorithm/remove_if.h +++ b/libcxx/include/__algorithm/remove_if.h @@ -11,6 +11,7 @@ #include <__algorithm/find_if.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -23,6 +24,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); __first = _VSTD::find_if<_ForwardIterator, _Predicate&>(__first, __last, __pred); if (__first != __last) { diff --git a/libcxx/include/__algorithm/replace.h b/libcxx/include/__algorithm/replace.h --- a/libcxx/include/__algorithm/replace.h +++ b/libcxx/include/__algorithm/replace.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_REPLACE_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -22,6 +23,7 @@ void replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); for (; __first != __last; ++__first) if (*__first == __old_value) *__first = __new_value; diff --git a/libcxx/include/__algorithm/replace_copy.h b/libcxx/include/__algorithm/replace_copy.h --- a/libcxx/include/__algorithm/replace_copy.h +++ b/libcxx/include/__algorithm/replace_copy.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_REPLACE_COPY_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -23,6 +24,8 @@ replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __old_value, const _Tp& __new_value) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, const _Tp&); for (; __first != __last; ++__first, (void) ++__result) if (*__first == __old_value) *__result = __new_value; diff --git a/libcxx/include/__algorithm/replace_copy_if.h b/libcxx/include/__algorithm/replace_copy_if.h --- a/libcxx/include/__algorithm/replace_copy_if.h +++ b/libcxx/include/__algorithm/replace_copy_if.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -23,6 +24,8 @@ replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred, const _Tp& __new_value) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, const _Tp&); for (; __first != __last; ++__first, (void) ++__result) if (__pred(*__first)) *__result = __new_value; diff --git a/libcxx/include/__algorithm/replace_if.h b/libcxx/include/__algorithm/replace_if.h --- a/libcxx/include/__algorithm/replace_if.h +++ b/libcxx/include/__algorithm/replace_if.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_REPLACE_IF_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -22,6 +23,7 @@ void replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); for (; __first != __last; ++__first) if (__pred(*__first)) *__first = __new_value; diff --git a/libcxx/include/__algorithm/reverse.h b/libcxx/include/__algorithm/reverse.h --- a/libcxx/include/__algorithm/reverse.h +++ b/libcxx/include/__algorithm/reverse.h @@ -12,6 +12,7 @@ #include <__algorithm/iter_swap.h> #include <__algorithm/iterator_operations.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__utility/move.h> @@ -57,6 +58,7 @@ void reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) { + _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(_BidirectionalIterator); std::__reverse<_ClassicAlgPolicy>(std::move(__first), std::move(__last)); } diff --git a/libcxx/include/__algorithm/reverse_copy.h b/libcxx/include/__algorithm/reverse_copy.h --- a/libcxx/include/__algorithm/reverse_copy.h +++ b/libcxx/include/__algorithm/reverse_copy.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_REVERSE_COPY_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -22,6 +23,8 @@ _OutputIterator reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) { + _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(_BidirectionalIterator); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(*__first)); for (; __first != __last; ++__result) *__result = *--__last; return __result; diff --git a/libcxx/include/__algorithm/rotate.h b/libcxx/include/__algorithm/rotate.h --- a/libcxx/include/__algorithm/rotate.h +++ b/libcxx/include/__algorithm/rotate.h @@ -14,6 +14,7 @@ #include <__algorithm/move_backward.h> #include <__algorithm/swap_ranges.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__type_traits/is_trivially_move_assignable.h> #include <__utility/move.h> @@ -212,6 +213,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); return std::__rotate<_ClassicAlgPolicy>( std::move(__first), std::move(__middle), std::move(__last)).first; } diff --git a/libcxx/include/__algorithm/rotate_copy.h b/libcxx/include/__algorithm/rotate_copy.h --- a/libcxx/include/__algorithm/rotate_copy.h +++ b/libcxx/include/__algorithm/rotate_copy.h @@ -11,6 +11,7 @@ #include <__algorithm/copy.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -23,6 +24,8 @@ _OutputIterator rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(*__first)); return _VSTD::copy(__first, __middle, _VSTD::copy(__middle, __last, __result)); } diff --git a/libcxx/include/__algorithm/sample.h b/libcxx/include/__algorithm/sample.h --- a/libcxx/include/__algorithm/sample.h +++ b/libcxx/include/__algorithm/sample.h @@ -13,6 +13,7 @@ #include <__algorithm/min.h> #include <__assert> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__random/uniform_int_distribution.h> diff --git a/libcxx/include/__algorithm/search.h b/libcxx/include/__algorithm/search.h --- a/libcxx/include/__algorithm/search.h +++ b/libcxx/include/__algorithm/search.h @@ -17,6 +17,7 @@ #include <__functional/invoke.h> #include <__iterator/advance.h> #include <__iterator/concepts.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__type_traits/enable_if.h> #include <__type_traits/is_callable.h> @@ -175,6 +176,8 @@ _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2); static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, "BinaryPredicate has to be callable"); auto __proj = __identity(); diff --git a/libcxx/include/__algorithm/search_n.h b/libcxx/include/__algorithm/search_n.h --- a/libcxx/include/__algorithm/search_n.h +++ b/libcxx/include/__algorithm/search_n.h @@ -17,6 +17,7 @@ #include <__functional/invoke.h> #include <__iterator/advance.h> #include <__iterator/concepts.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__ranges/concepts.h> @@ -165,6 +166,7 @@ _Size __count, const _Tp& __value, _BinaryPredicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); static_assert(__is_callable<_BinaryPredicate, decltype(*__first), const _Tp&>::value, "BinaryPredicate has to be callable"); auto __proj = __identity(); diff --git a/libcxx/include/__algorithm/set_difference.h b/libcxx/include/__algorithm/set_difference.h --- a/libcxx/include/__algorithm/set_difference.h +++ b/libcxx/include/__algorithm/set_difference.h @@ -16,6 +16,7 @@ #include <__config> #include <__functional/identity.h> #include <__functional/invoke.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__type_traits/remove_cvref.h> #include <__utility/move.h> @@ -54,6 +55,9 @@ _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator1); + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator2); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(*__first1)); return std::__set_difference<_ClassicAlgPolicy, __comp_ref_type<_Compare> >( __first1, __last1, __first2, __last2, __result, __comp) .second; diff --git a/libcxx/include/__algorithm/set_intersection.h b/libcxx/include/__algorithm/set_intersection.h --- a/libcxx/include/__algorithm/set_intersection.h +++ b/libcxx/include/__algorithm/set_intersection.h @@ -13,6 +13,7 @@ #include <__algorithm/comp_ref_type.h> #include <__algorithm/iterator_operations.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__iterator/next.h> #include <__utility/move.h> @@ -66,6 +67,9 @@ _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator1); + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator2); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(*__first1)); return std::__set_intersection<_ClassicAlgPolicy, __comp_ref_type<_Compare> >( std::move(__first1), std::move(__last1), @@ -83,14 +87,13 @@ _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) { - return std::__set_intersection<_ClassicAlgPolicy>( - std::move(__first1), - std::move(__last1), - std::move(__first2), - std::move(__last2), - std::move(__result), - __less<>()) - .__out_; + return std::set_intersection( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/set_symmetric_difference.h b/libcxx/include/__algorithm/set_symmetric_difference.h --- a/libcxx/include/__algorithm/set_symmetric_difference.h +++ b/libcxx/include/__algorithm/set_symmetric_difference.h @@ -14,6 +14,7 @@ #include <__algorithm/copy.h> #include <__algorithm/iterator_operations.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__utility/move.h> #include <__utility/pair.h> @@ -73,6 +74,9 @@ _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator1); + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator2); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(*__first1)); return std::__set_symmetric_difference<_ClassicAlgPolicy, __comp_ref_type<_Compare> >( std::move(__first1), std::move(__last1), diff --git a/libcxx/include/__algorithm/set_union.h b/libcxx/include/__algorithm/set_union.h --- a/libcxx/include/__algorithm/set_union.h +++ b/libcxx/include/__algorithm/set_union.h @@ -14,6 +14,7 @@ #include <__algorithm/copy.h> #include <__algorithm/iterator_operations.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__utility/move.h> #include <__utility/pair.h> @@ -69,6 +70,9 @@ _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator1); + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator2); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(*__first1)); return std::__set_union<_ClassicAlgPolicy, __comp_ref_type<_Compare> >( std::move(__first1), std::move(__last1), diff --git a/libcxx/include/__algorithm/shift_left.h b/libcxx/include/__algorithm/shift_left.h --- a/libcxx/include/__algorithm/shift_left.h +++ b/libcxx/include/__algorithm/shift_left.h @@ -11,6 +11,7 @@ #include <__algorithm/move.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -27,6 +28,7 @@ shift_left(_ForwardIterator __first, _ForwardIterator __last, typename iterator_traits<_ForwardIterator>::difference_type __n) { + static_assert(__cpp17_forward_iterator<_ForwardIterator>); if (__n == 0) { return __last; } diff --git a/libcxx/include/__algorithm/shift_right.h b/libcxx/include/__algorithm/shift_right.h --- a/libcxx/include/__algorithm/shift_right.h +++ b/libcxx/include/__algorithm/shift_right.h @@ -13,6 +13,7 @@ #include <__algorithm/move_backward.h> #include <__algorithm/swap_ranges.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__utility/swap.h> @@ -30,6 +31,7 @@ shift_right(_ForwardIterator __first, _ForwardIterator __last, typename iterator_traits<_ForwardIterator>::difference_type __n) { + static_assert(__cpp17_forward_iterator<_ForwardIterator>); if (__n == 0) { return __first; } diff --git a/libcxx/include/__algorithm/shuffle.h b/libcxx/include/__algorithm/shuffle.h --- a/libcxx/include/__algorithm/shuffle.h +++ b/libcxx/include/__algorithm/shuffle.h @@ -12,6 +12,7 @@ #include <__algorithm/iterator_operations.h> #include <__config> #include <__debug> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__random/uniform_int_distribution.h> #include <__utility/forward.h> @@ -164,6 +165,7 @@ template _LIBCPP_HIDE_FROM_ABI void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, _UniformRandomNumberGenerator&& __g) { + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator); (void)std::__shuffle<_ClassicAlgPolicy>( std::move(__first), std::move(__last), std::forward<_UniformRandomNumberGenerator>(__g)); } diff --git a/libcxx/include/__algorithm/sort.h b/libcxx/include/__algorithm/sort.h --- a/libcxx/include/__algorithm/sort.h +++ b/libcxx/include/__algorithm/sort.h @@ -26,6 +26,7 @@ #include <__debug_utils/strict_weak_ordering_check.h> #include <__functional/operations.h> #include <__functional/ranges_operations.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__type_traits/conditional.h> #include <__type_traits/disjunction.h> @@ -929,6 +930,7 @@ template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator); std::__sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } diff --git a/libcxx/include/__algorithm/sort_heap.h b/libcxx/include/__algorithm/sort_heap.h --- a/libcxx/include/__algorithm/sort_heap.h +++ b/libcxx/include/__algorithm/sort_heap.h @@ -15,6 +15,7 @@ #include <__algorithm/pop_heap.h> #include <__config> #include <__debug_utils/strict_weak_ordering_check.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__type_traits/is_copy_assignable.h> #include <__type_traits/is_copy_constructible.h> @@ -41,8 +42,7 @@ template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); - static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator); std::__sort_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } diff --git a/libcxx/include/__algorithm/stable_partition.h b/libcxx/include/__algorithm/stable_partition.h --- a/libcxx/include/__algorithm/stable_partition.h +++ b/libcxx/include/__algorithm/stable_partition.h @@ -13,6 +13,7 @@ #include <__algorithm/rotate.h> #include <__config> #include <__iterator/advance.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__memory/destruct_n.h> @@ -318,6 +319,7 @@ _ForwardIterator stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category; return std::__stable_partition<_ClassicAlgPolicy, _Predicate&>( std::move(__first), std::move(__last), __pred, _IterCategory()); diff --git a/libcxx/include/__algorithm/stable_sort.h b/libcxx/include/__algorithm/stable_sort.h --- a/libcxx/include/__algorithm/stable_sort.h +++ b/libcxx/include/__algorithm/stable_sort.h @@ -16,6 +16,7 @@ #include <__algorithm/sort.h> #include <__config> #include <__debug_utils/strict_weak_ordering_check.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__memory/destruct_n.h> #include <__memory/temporary_buffer.h> @@ -266,6 +267,7 @@ template inline _LIBCPP_HIDE_FROM_ABI void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator); std::__stable_sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } diff --git a/libcxx/include/__algorithm/swap_ranges.h b/libcxx/include/__algorithm/swap_ranges.h --- a/libcxx/include/__algorithm/swap_ranges.h +++ b/libcxx/include/__algorithm/swap_ranges.h @@ -11,6 +11,7 @@ #include <__algorithm/iterator_operations.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__utility/move.h> #include <__utility/pair.h> @@ -51,6 +52,8 @@ template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator2 swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2); return std::__swap_ranges<_ClassicAlgPolicy>( std::move(__first1), std::move(__last1), std::move(__first2)).second; } diff --git a/libcxx/include/__algorithm/transform.h b/libcxx/include/__algorithm/transform.h --- a/libcxx/include/__algorithm/transform.h +++ b/libcxx/include/__algorithm/transform.h @@ -10,6 +10,7 @@ #define _LIBCPP___ALGORITHM_TRANSFORM_H #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -22,6 +23,8 @@ _OutputIterator transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(__op(*__first))); for (; __first != __last; ++__first, (void) ++__result) *__result = __op(*__first); return __result; @@ -33,6 +36,9 @@ transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _OutputIterator __result, _BinaryOperation __binary_op) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator1); + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator2); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(__binary_op(*__first1, *__first2))); for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__result) *__result = __binary_op(*__first1, *__first2); return __result; diff --git a/libcxx/include/__algorithm/unique.h b/libcxx/include/__algorithm/unique.h --- a/libcxx/include/__algorithm/unique.h +++ b/libcxx/include/__algorithm/unique.h @@ -13,6 +13,7 @@ #include <__algorithm/comp.h> #include <__algorithm/iterator_operations.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__utility/move.h> #include <__utility/pair.h> @@ -45,6 +46,7 @@ template _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); return std::__unique<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred).first; } diff --git a/libcxx/include/__algorithm/unique_copy.h b/libcxx/include/__algorithm/unique_copy.h --- a/libcxx/include/__algorithm/unique_copy.h +++ b/libcxx/include/__algorithm/unique_copy.h @@ -12,6 +12,7 @@ #include <__algorithm/comp.h> #include <__algorithm/iterator_operations.h> #include <__config> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__type_traits/conditional.h> #include <__type_traits/is_base_of.h> @@ -97,6 +98,8 @@ template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred) { + _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(_InputIterator); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_OutputIterator, decltype(*__first)); using __algo_tag = __conditional_t< is_base_of::iterator_category>::value, __unique_copy_tags::__reread_from_input_tag, diff --git a/libcxx/include/__algorithm/upper_bound.h b/libcxx/include/__algorithm/upper_bound.h --- a/libcxx/include/__algorithm/upper_bound.h +++ b/libcxx/include/__algorithm/upper_bound.h @@ -16,6 +16,7 @@ #include <__functional/identity.h> #include <__functional/invoke.h> #include <__iterator/advance.h> +#include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__type_traits/is_copy_constructible.h> @@ -47,7 +48,7 @@ template _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { - static_assert(is_copy_constructible<_ForwardIterator>::value, "Iterator has to be copy constructible"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); return std::__upper_bound<_ClassicAlgPolicy>( std::move(__first), std::move(__last), __value, std::move(__comp), std::__identity()); } diff --git a/libcxx/test/libcxx/algorithms/bad_iterator_traits.verify.cpp b/libcxx/test/libcxx/algorithms/bad_iterator_traits.verify.cpp --- a/libcxx/test/libcxx/algorithms/bad_iterator_traits.verify.cpp +++ b/libcxx/test/libcxx/algorithms/bad_iterator_traits.verify.cpp @@ -57,5 +57,6 @@ // behavior when these iterators are passed to standard algorithms. void test() { std::sort(BadIter(), BadIter()); - //expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}It looks like your iterator's `iterator_traits::reference` does not match the return type of dereferencing the iterator}} + // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}It looks like your iterator's `iterator_traits::reference` does not match the return type of dereferencing the iterator}} + // expected-error-re@*:* 3 {{{{(static_assert|static assertion)}}}} } diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.min.max/requires_forward_iterator.fail.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.min.max/requires_forward_iterator.fail.cpp deleted file mode 100644 --- a/libcxx/test/std/algorithms/alg.sorting/alg.min.max/requires_forward_iterator.fail.cpp +++ /dev/null @@ -1,38 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// - -// template -// max_element(Iter first, Iter last); - -#include -#include - -#include "test_iterators.h" - -int main(int, char**) { - int arr[] = {1, 2, 3}; - const int *b = std::begin(arr), *e = std::end(arr); - typedef cpp17_input_iterator Iter; - { - // expected-error@*:* {{std::min_element requires a ForwardIterator}} - (void) std::min_element(Iter(b), Iter(e)); - } - { - // expected-error@*:* {{std::max_element requires a ForwardIterator}} - (void) std::max_element(Iter(b), Iter(e)); - } - { - // expected-error@*:* {{std::minmax_element requires a ForwardIterator}} - (void) std::minmax_element(Iter(b), Iter(e)); - } - - - return 0; -} diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.verify.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.verify.cpp deleted file mode 100644 --- a/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.verify.cpp +++ /dev/null @@ -1,47 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11, c++14, c++17 - -// - -// template -// constexpr auto -// lexicographical_compare_three_way(InputIterator1 first1, InputIterator1 last1, -// InputIterator2 first2, InputIterator2 last2, -// Cmp comp) -// -> decltype(comp(*b1, *b2)); - -#include -#include -#include -#include - -#include "test_macros.h" -#include "almost_satisfies_types.h" - -constexpr bool incorrect_comparator(int a, int b) { return a < b; } - -auto test_incorrect_comparator() { - std::array a{90, 81}; - std::array b{10, 11}; - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed{{.*}}The comparator passed to lexicographical_compare_three_way must return a comparison category type}} - // expected-error@*:* {{no viable conversion}} - return std::lexicographical_compare_three_way(a.begin(), a.end(), b.begin(), b.end(), incorrect_comparator); -} - -auto test_invalid_difference_type_first( - RandomAccessIteratorBadDifferenceType a, RandomAccessIteratorBadDifferenceType b, int* c, int* d) { - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed{{.*}}Using a non-integral difference_type is undefined behavior}}}} - return std::lexicographical_compare_three_way(a, b, c, d, std::compare_three_way()); -} - -auto test_invalid_difference_type_second( - int* a, int* b, RandomAccessIteratorBadDifferenceType c, RandomAccessIteratorBadDifferenceType d) { - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed{{.*}}Using a non-integral difference_type is undefined behavior}}}} - return std::lexicographical_compare_three_way(a, b, c, d, std::compare_three_way()); -}