[libcxx-commits] [libcxx] 6adb1ca - [libc++] Add concepts that ensure a given iterator meets the syntactic requirements

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jun 9 08:38:30 PDT 2023


Author: Nikolas Klauser
Date: 2023-06-09T08:38:22-07:00
New Revision: 6adb1ca555ec7e3ac8d9bc19d3a5710bd7964276

URL: https://github.com/llvm/llvm-project/commit/6adb1ca555ec7e3ac8d9bc19d3a5710bd7964276
DIFF: https://github.com/llvm/llvm-project/commit/6adb1ca555ec7e3ac8d9bc19d3a5710bd7964276.diff

LOG: [libc++] Add concepts that ensure a given iterator meets the syntactic requirements

These concepts are used to ensure valid iterators are passed to PSTL algorithms, but can also be used for other interfaces.

Reviewed By: ldionne, #libc

Spies: EricWF, libcxx-commits

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

Added: 
    libcxx/include/__iterator/cpp17_iterator_concepts.h
    libcxx/test/libcxx/algorithms/cpp17_iterator_concepts.verify.cpp

Modified: 
    libcxx/include/CMakeLists.txt
    libcxx/include/__algorithm/pstl_any_all_none_of.h
    libcxx/include/__algorithm/pstl_fill.h
    libcxx/include/__algorithm/pstl_find.h
    libcxx/include/__algorithm/pstl_for_each.h
    libcxx/include/__algorithm/pstl_transform.h
    libcxx/include/module.modulemap.in

Removed: 
    


################################################################################
diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 4b5aef4496988..62e9449ded9b5 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -435,6 +435,7 @@ set(files
   __iterator/common_iterator.h
   __iterator/concepts.h
   __iterator/counted_iterator.h
+  __iterator/cpp17_iterator_concepts.h
   __iterator/data.h
   __iterator/default_sentinel.h
   __iterator/distance.h

diff  --git a/libcxx/include/__algorithm/pstl_any_all_none_of.h b/libcxx/include/__algorithm/pstl_any_all_none_of.h
index 374d9af17cc0b..c6febf4ec2784 100644
--- a/libcxx/include/__algorithm/pstl_any_all_none_of.h
+++ b/libcxx/include/__algorithm/pstl_any_all_none_of.h
@@ -12,6 +12,7 @@
 #include <__algorithm/pstl_find.h>
 #include <__algorithm/pstl_frontend_dispatch.h>
 #include <__config>
+#include <__iterator/cpp17_iterator_concepts.h>
 #include <__iterator/iterator_traits.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/is_execution_policy.h>
@@ -36,6 +37,7 @@ template <class _ExecutionPolicy,
           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
 any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
   return std::__pstl_frontend_dispatch(
       _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_any_of),
       [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
@@ -56,6 +58,7 @@ template <class _ExecutionPolicy,
           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
 all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
   return std::__pstl_frontend_dispatch(
       _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_all_of),
       [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) {
@@ -78,6 +81,7 @@ template <class _ExecutionPolicy,
           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
 _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool
 none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
   return std::__pstl_frontend_dispatch(
       _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_none_of),
       [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) {

diff  --git a/libcxx/include/__algorithm/pstl_fill.h b/libcxx/include/__algorithm/pstl_fill.h
index 03217b36d49a6..ef608ce9f7b5b 100644
--- a/libcxx/include/__algorithm/pstl_fill.h
+++ b/libcxx/include/__algorithm/pstl_fill.h
@@ -13,6 +13,7 @@
 #include <__algorithm/pstl_for_each.h>
 #include <__algorithm/pstl_frontend_dispatch.h>
 #include <__config>
+#include <__iterator/cpp17_iterator_concepts.h>
 #include <__iterator/iterator_traits.h>
 #include <__type_traits/is_execution_policy.h>
 #include <__type_traits/remove_cvref.h>
@@ -36,6 +37,7 @@ template <class _ExecutionPolicy,
           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
 _LIBCPP_HIDE_FROM_ABI void
 fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
   std::__pstl_frontend_dispatch(
       _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill),
       [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {
@@ -59,6 +61,7 @@ template <class _ExecutionPolicy,
           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
 _LIBCPP_HIDE_FROM_ABI void
 fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _SizeT __n, const _Tp& __value) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
   std::__pstl_frontend_dispatch(
       _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill_n),
       [&](_ForwardIterator __g_first, _SizeT __g_n, const _Tp& __g_value) {

diff  --git a/libcxx/include/__algorithm/pstl_find.h b/libcxx/include/__algorithm/pstl_find.h
index 6d69560dc42f8..08f72c50e9863 100644
--- a/libcxx/include/__algorithm/pstl_find.h
+++ b/libcxx/include/__algorithm/pstl_find.h
@@ -14,6 +14,7 @@
 #include <__algorithm/pstl_backend.h>
 #include <__algorithm/pstl_frontend_dispatch.h>
 #include <__config>
+#include <__iterator/cpp17_iterator_concepts.h>
 #include <__iterator/iterator_traits.h>
 #include <__type_traits/is_execution_policy.h>
 #include <__type_traits/remove_cvref.h>
@@ -34,6 +35,7 @@ template <class _ExecutionPolicy,
           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
 _LIBCPP_HIDE_FROM_ABI _ForwardIterator
 find_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
   using _Backend = typename __select_backend<_RawPolicy>::type;
   return std::__pstl_find_if<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__pred));
 }
@@ -48,6 +50,7 @@ template <class _ExecutionPolicy,
           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
 _LIBCPP_HIDE_FROM_ABI _ForwardIterator
 find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
   return std::__pstl_frontend_dispatch(
       _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find_if_not),
       [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) {
@@ -70,6 +73,7 @@ template <class _ExecutionPolicy,
           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
 _LIBCPP_HIDE_FROM_ABI _ForwardIterator
 find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
   return std::__pstl_frontend_dispatch(
       _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find),
       [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) {

diff  --git a/libcxx/include/__algorithm/pstl_for_each.h b/libcxx/include/__algorithm/pstl_for_each.h
index 1c435385defcf..a4a9914733013 100644
--- a/libcxx/include/__algorithm/pstl_for_each.h
+++ b/libcxx/include/__algorithm/pstl_for_each.h
@@ -14,6 +14,7 @@
 #include <__algorithm/pstl_backend.h>
 #include <__algorithm/pstl_frontend_dispatch.h>
 #include <__config>
+#include <__iterator/cpp17_iterator_concepts.h>
 #include <__iterator/iterator_traits.h>
 #include <__type_traits/is_execution_policy.h>
 #include <__type_traits/remove_cvref.h>
@@ -35,6 +36,7 @@ template <class _ExecutionPolicy,
           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
 _LIBCPP_HIDE_FROM_ABI void
 for_each(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __func) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
   using _Backend = typename __select_backend<_RawPolicy>::type;
   std::__pstl_for_each<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__func));
 }
@@ -50,6 +52,7 @@ template <class _ExecutionPolicy,
           enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
 _LIBCPP_HIDE_FROM_ABI void
 for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
   return std::__pstl_frontend_dispatch(
       _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_for_each_n),
       [&](_ForwardIterator __g_first, _Size __g_size, _Function __g_func) {

diff  --git a/libcxx/include/__algorithm/pstl_transform.h b/libcxx/include/__algorithm/pstl_transform.h
index 9d2d731eeb150..aa7d49b75ea3e 100644
--- a/libcxx/include/__algorithm/pstl_transform.h
+++ b/libcxx/include/__algorithm/pstl_transform.h
@@ -11,6 +11,7 @@
 
 #include <__algorithm/pstl_backend.h>
 #include <__config>
+#include <__iterator/cpp17_iterator_concepts.h>
 #include <__iterator/iterator_traits.h>
 #include <__type_traits/is_execution_policy.h>
 #include <__utility/terminate_on_exception.h>
@@ -35,6 +36,9 @@ _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
     _ForwardIterator __last,
     _ForwardOutIterator __result,
     _UnaryOperation __op) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator);
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+  _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first)));
   using _Backend = typename __select_backend<_RawPolicy>::type;
   return std::__pstl_transform<_RawPolicy>(
       _Backend{}, std::move(__first), std::move(__last), std::move(__result), std::move(__op));
@@ -54,6 +58,10 @@ _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
     _ForwardIterator2 __first2,
     _ForwardOutIterator __result,
     _BinaryOperation __op) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1);
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2);
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator);
+  _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first1, *__first2)));
   using _Backend = typename __select_backend<_RawPolicy>::type;
   return std::__pstl_transform<_RawPolicy>(
       _Backend{}, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__result), std::move(__op));

diff  --git a/libcxx/include/__iterator/cpp17_iterator_concepts.h b/libcxx/include/__iterator/cpp17_iterator_concepts.h
new file mode 100644
index 0000000000000..c4f49fe742271
--- /dev/null
+++ b/libcxx/include/__iterator/cpp17_iterator_concepts.h
@@ -0,0 +1,185 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H
+#define _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H
+
+#include <__concepts/boolean_testable.h>
+#include <__concepts/convertible_to.h>
+#include <__concepts/same_as.h>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__type_traits/is_default_constructible.h>
+#include <__type_traits/is_move_constructible.h>
+#include <__type_traits/is_signed.h>
+#include <__type_traits/is_void.h>
+#include <__utility/as_const.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 20
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+concept __cpp17_move_constructible = is_move_constructible_v<_Tp>;
+
+template <class _Tp>
+concept __cpp17_copy_constructible = __cpp17_move_constructible<_Tp> && is_copy_constructible_v<_Tp>;
+
+template <class _Tp>
+concept __cpp17_move_assignable = requires(_Tp __lhs, _Tp __rhs) {
+  { __lhs = std::move(__rhs) } -> same_as<_Tp&>;
+};
+
+template <class _Tp>
+concept __cpp17_copy_assignable = __cpp17_move_assignable<_Tp> && requires(_Tp __lhs, _Tp __rhs) {
+  { __lhs = __rhs } -> same_as<_Tp&>;
+  { __lhs = std::as_const(__rhs) } -> same_as<_Tp&>;
+};
+
+template <class _Tp>
+concept __cpp17_destructible = requires(_Tp __v) { __v.~_Tp(); };
+
+template <class _Tp>
+concept __cpp17_equality_comparable = requires(_Tp __lhs, _Tp __rhs) {
+  { __lhs == __rhs } -> __boolean_testable;
+  { std::as_const(__lhs) == __rhs } -> __boolean_testable;
+  { __lhs == std::as_const(__rhs) } -> __boolean_testable;
+  { std::as_const(__lhs) == std::as_const(__rhs) } -> __boolean_testable;
+};
+
+template <class _Tp>
+concept __cpp17_default_constructible = is_default_constructible_v<_Tp>;
+
+template <class _Iter>
+concept __cpp17_iterator =
+    __cpp17_copy_constructible<_Iter> && __cpp17_copy_assignable<_Iter> && __cpp17_destructible<_Iter> &&
+    (is_signed_v<__iter_
diff _t<_Iter>> || is_void_v<__iter_
diff _t<_Iter>>)&&requires(_Iter __iter) {
+      { *__iter };
+      { ++__iter } -> same_as<_Iter&>;
+    };
+
+template <class _Iter>
+concept __cpp17_input_iterator =
+    __cpp17_iterator<_Iter> && __cpp17_equality_comparable<_Iter> && requires(_Iter __lhs, _Iter __rhs) {
+      { __lhs != __rhs } -> __boolean_testable;
+      { std::as_const(__lhs) != __rhs } -> __boolean_testable;
+      { __lhs != std::as_const(__rhs) } -> __boolean_testable;
+      { std::as_const(__lhs) != std::as_const(__rhs) } -> __boolean_testable;
+
+      { *__lhs } -> same_as<__iter_reference<_Iter>>;
+      { *std::as_const(__lhs) } -> same_as<__iter_reference<_Iter>>;
+
+      { ++__lhs } -> same_as<_Iter&>;
+      { (void)__lhs++ };
+      { *__lhs++ };
+    };
+
+template <class _Iter, class _WriteTo>
+concept __cpp17_output_iterator = __cpp17_iterator<_Iter> && requires(_Iter __iter, _WriteTo __write) {
+  { *__iter = std::forward<_WriteTo>(__write) };
+  { ++__iter } -> same_as<_Iter&>;
+  { __iter++ } -> convertible_to<const _Iter&>;
+  { *__iter++ = std::forward<_WriteTo>(__write) };
+};
+
+template <class _Iter>
+concept __cpp17_forward_iterator =
+    __cpp17_input_iterator<_Iter> && __cpp17_default_constructible<_Iter> && requires(_Iter __iter) {
+      { __iter++ } -> convertible_to<const _Iter&>;
+      { *__iter++ } -> same_as<__iter_reference<_Iter>>;
+    };
+
+template <class _Iter>
+concept __cpp17_bidirectional_iterator = __cpp17_forward_iterator<_Iter> && requires(_Iter __iter) {
+  { --__iter } -> same_as<_Iter&>;
+  { __iter-- } -> convertible_to<const _Iter&>;
+  { *__iter-- } -> same_as<__iter_reference<_Iter>>;
+};
+
+template <class _Iter>
+concept __cpp17_random_access_iterator =
+    __cpp17_bidirectional_iterator<_Iter> && requires(_Iter __iter, __iter_
diff _t<_Iter> __n) {
+      { __iter += __n } -> same_as<_Iter&>;
+
+      { __iter + __n } -> same_as<_Iter>;
+      { __n + __iter } -> same_as<_Iter>;
+      { std::as_const(__iter) + __n } -> same_as<_Iter>;
+      { __n + std::as_const(__iter) } -> same_as<_Iter>;
+
+      { __iter -= __n } -> same_as<_Iter&>;
+      { __iter - __n } -> same_as<_Iter>;
+      { std::as_const(__iter) - __n } -> same_as<_Iter>;
+
+      { __iter - __iter } -> same_as<__iter_
diff _t<_Iter>>;
+      { std::as_const(__iter) - __iter } -> same_as<__iter_
diff _t<_Iter>>;
+      { __iter - std::as_const(__iter) } -> same_as<__iter_
diff _t<_Iter>>;
+      { std::as_const(__iter) - std::as_const(__iter) } -> same_as<__iter_
diff _t<_Iter>>;
+
+      { __iter[__n] } -> convertible_to<__iter_reference<_Iter>>;
+      { std::as_const(__iter)[__n] } -> convertible_to<__iter_reference<_Iter>>;
+
+      { __iter < __iter } -> __boolean_testable;
+      { std::as_const(__iter) < __iter } -> __boolean_testable;
+      { __iter < std::as_const(__iter) } -> __boolean_testable;
+      { std::as_const(__iter) < std::as_const(__iter) } -> __boolean_testable;
+
+      { __iter > __iter } -> __boolean_testable;
+      { std::as_const(__iter) > __iter } -> __boolean_testable;
+      { __iter > std::as_const(__iter) } -> __boolean_testable;
+      { std::as_const(__iter) > std::as_const(__iter) } -> __boolean_testable;
+
+      { __iter >= __iter } -> __boolean_testable;
+      { std::as_const(__iter) >= __iter } -> __boolean_testable;
+      { __iter >= std::as_const(__iter) } -> __boolean_testable;
+      { std::as_const(__iter) >= std::as_const(__iter) } -> __boolean_testable;
+
+      { __iter <= __iter } -> __boolean_testable;
+      { std::as_const(__iter) <= __iter } -> __boolean_testable;
+      { __iter <= std::as_const(__iter) } -> __boolean_testable;
+      { std::as_const(__iter) <= std::as_const(__iter) } -> __boolean_testable;
+    };
+
+_LIBCPP_END_NAMESPACE_STD
+
+#  ifndef _LIBCPP_DISABLE_ITERATOR_CHECKS
+#    define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t) static_assert(::std::__cpp17_input_iterator<iter_t>);
+#    define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t)                                                     \
+      static_assert(::std::__cpp17_output_iterator<iter_t, write_t>);
+#    define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t) static_assert(::std::__cpp17_forward_iterator<iter_t>);
+#    define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t)                                                       \
+      static_assert(::std::__cpp17_bidirectional_iterator<iter_t>);
+#    define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t)                                                       \
+      static_assert(::std::__cpp17_random_access_iterator<iter_t>);
+#  else
+#    define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t)
+#    define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t)
+#    define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t)
+#    define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t)
+#    define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t)
+#  endif
+
+#else // _LIBCPP_STD_VER >= 20
+
+#  define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t)
+#  define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t)
+#  define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t)
+#  define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t)
+#  define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t)
+
+#endif // _LIBCPP_STD_VER >= 20
+
+#endif // _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H

diff  --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index ba4745043afdc..92b45d3ae0d9b 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1076,11 +1076,12 @@ module std [system] {
     export *
 
     module __iterator {
-      module access                { private header "__iterator/access.h" }
-      module advance               { private header "__iterator/advance.h" }
-      module back_insert_iterator  { private header "__iterator/back_insert_iterator.h" }
-      module bounded_iter          { private header "__iterator/bounded_iter.h" }
-      module common_iterator       { private header "__iterator/common_iterator.h" }
+      module access                  { private header "__iterator/access.h" }
+      module advance                 { private header "__iterator/advance.h" }
+      module back_insert_iterator    { private header "__iterator/back_insert_iterator.h" }
+      module bounded_iter            { private header "__iterator/bounded_iter.h" }
+      module common_iterator         { private header "__iterator/common_iterator.h" }
+      module cpp17_iterator_concepts { private header "__iterator/cpp17_iterator_concepts.h" }
       module concepts {
         private header "__iterator/concepts.h"
         export concepts.equality_comparable

diff  --git a/libcxx/test/libcxx/algorithms/cpp17_iterator_concepts.verify.cpp b/libcxx/test/libcxx/algorithms/cpp17_iterator_concepts.verify.cpp
new file mode 100644
index 0000000000000..6916fce05b37e
--- /dev/null
+++ b/libcxx/test/libcxx/algorithms/cpp17_iterator_concepts.verify.cpp
@@ -0,0 +1,422 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Check that __cpp17_*_iterator catch bad iterators
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// ADDITIONAL_COMPILE_FLAGS: -Wno-private-header
+
+#include <__iterator/cpp17_iterator_concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <compare>
+#include <cstddef>
+
+struct missing_deref {
+  using 
diff erence_type = std::ptr
diff _t;
+  using iterator_category = std::input_iterator_tag;
+  using value_type = int;
+  using reference = int&;
+
+  missing_deref& operator++();
+};
+
+struct missing_preincrement {
+  using 
diff erence_type = std::ptr
diff _t;
+  using iterator_category = std::input_iterator_tag;
+  using value_type = int;
+  using reference = int&;
+
+  int& operator*();
+};
+
+template <class Derived>
+struct valid_iterator {
+  using 
diff erence_type = std::ptr
diff _t;
+  using iterator_category = std::input_iterator_tag;
+  using value_type = int;
+  using reference = int&;
+
+  int& operator*() const;
+  Derived& operator++();
+
+  struct Proxy {
+    int operator*();
+  };
+
+  Proxy operator++(int);
+};
+
+struct not_move_constructible : valid_iterator<not_move_constructible> {
+  not_move_constructible(const not_move_constructible&) = default;
+  not_move_constructible(not_move_constructible&&) = delete;
+  not_move_constructible& operator=(not_move_constructible&&) = default;
+  not_move_constructible& operator=(const not_move_constructible&) = default;
+};
+
+struct not_copy_constructible : valid_iterator<not_copy_constructible> {
+  not_copy_constructible(const not_copy_constructible&) = delete;
+  not_copy_constructible(not_copy_constructible&&) = default;
+  not_copy_constructible& operator=(not_copy_constructible&&) = default;
+  not_copy_constructible& operator=(const not_copy_constructible&) = default;
+};
+
+struct not_move_assignable : valid_iterator<not_move_assignable> {
+  not_move_assignable(const not_move_assignable&) = default;
+  not_move_assignable(not_move_assignable&&) = default;
+  not_move_assignable& operator=(not_move_assignable&&) = delete;
+  not_move_assignable& operator=(const not_move_assignable&) = default;
+};
+
+struct not_copy_assignable : valid_iterator<not_copy_assignable> {
+  not_copy_assignable(const not_copy_assignable&) = default;
+  not_copy_assignable(not_copy_assignable&&) = default;
+  not_copy_assignable& operator=(not_copy_assignable&&) = default;
+  not_copy_assignable& operator=(const not_copy_assignable&) = delete;
+};
+
+struct 
diff _t_not_signed : valid_iterator<
diff _t_not_signed> {
+  using 
diff erence_type = unsigned;
+};
+
+void check_iterator_requirements() {
+  static_assert(std::__cpp17_iterator<missing_deref>); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{indirection requires pointer operand}}
+
+  static_assert(std::__cpp17_iterator<missing_preincrement>); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{cannot increment value of type 'missing_preincrement'}}
+
+
+  static_assert(std::__cpp17_iterator<not_move_constructible>); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'not_move_constructible' does not satisfy '__cpp17_move_constructible'}}
+
+  static_assert(std::__cpp17_iterator<not_copy_constructible>); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'not_copy_constructible' does not satisfy '__cpp17_copy_constructible'}}
+
+  static_assert(std::__cpp17_iterator<not_move_assignable>); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'not_move_assignable' does not satisfy '__cpp17_copy_assignable'}}
+
+  static_assert(std::__cpp17_iterator<not_copy_assignable>); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expectted-note@*:* {{because 'not_copy_assignable' does not satisfy '__cpp17_copy_assignable'}}
+
+  static_assert(std::__cpp17_iterator<
diff _t_not_signed>); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expectted-note@*:* {{'is_signed_v<__iter_
diff _t<
diff _t_not_signed> >' evaluated to false}}
+}
+
+struct not_equality_comparable : valid_iterator<not_equality_comparable> {};
+bool operator==(not_equality_comparable, not_equality_comparable) = delete;
+bool operator!=(not_equality_comparable, not_equality_comparable);
+
+struct not_unequality_comparable : valid_iterator<not_unequality_comparable> {};
+bool operator==(not_unequality_comparable, not_unequality_comparable);
+bool operator!=(not_unequality_comparable, not_unequality_comparable) = delete;
+
+void check_input_iterator_requirements() {
+  _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(not_equality_comparable); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{'__lhs == __rhs' would be invalid: overload resolution selected deleted operator '=='}}
+
+  _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(not_unequality_comparable); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{'__lhs != __rhs' would be invalid: overload resolution selected deleted operator '!='}}
+}
+
+template <class Derived>
+struct valid_forward_iterator : valid_iterator<Derived> {
+  Derived& operator++();
+  Derived operator++(int);
+
+  friend bool operator==(Derived, Derived);
+};
+
+struct not_default_constructible : valid_forward_iterator<not_default_constructible> {
+  not_default_constructible() = delete;
+};
+
+struct postincrement_not_ref : valid_iterator<postincrement_not_ref> {};
+bool operator==(postincrement_not_ref, postincrement_not_ref);
+
+void check_forward_iterator_requirements() {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(not_default_constructible); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'not_default_constructible' does not satisfy '__cpp17_default_constructible'}}
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(postincrement_not_ref); // expected-error-re {{{{static assertion|static_assert}} failed}}
+#ifndef _AIX
+  // expected-note@*:* {{because type constraint 'convertible_to<valid_iterator<postincrement_not_ref>::Proxy, const postincrement_not_ref &>' was not satisfied}}
+#endif
+}
+
+struct missing_predecrement : valid_forward_iterator<missing_predecrement> {
+  missing_deref operator--(int);
+};
+
+struct missing_postdecrement : valid_forward_iterator<missing_postdecrement> {
+  missing_postdecrement& operator--();
+};
+
+struct not_returning_iter_reference : valid_forward_iterator<not_returning_iter_reference> {
+
+  struct Proxy {
+    operator const not_returning_iter_reference&();
+
+    int operator*();
+  };
+
+  not_returning_iter_reference& operator--();
+  Proxy operator--(int);
+};
+
+void check_bidirectional_iterator_requirements() {
+  _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(missing_predecrement); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{cannot decrement value of type 'missing_predecrement'}}
+  _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(missing_postdecrement); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{cannot decrement value of type 'missing_postdecrement'}}
+  _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(not_returning_iter_reference); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because type constraint 'same_as<int, __iter_reference<not_returning_iter_reference> >' was not satisfied}}
+}
+
+template <class Derived>
+struct valid_random_access_iterator : valid_forward_iterator<Derived> {
+  using 
diff erence_type = typename valid_forward_iterator<Derived>::
diff erence_type;
+
+  Derived& operator--();
+  Derived operator--(int);
+
+  Derived& operator+=(
diff erence_type);
+  Derived& operator-=(
diff erence_type);
+
+  friend Derived operator+(valid_random_access_iterator, 
diff erence_type);
+  friend Derived operator+(
diff erence_type, valid_random_access_iterator);
+  friend Derived operator-(valid_random_access_iterator, 
diff erence_type);
+  friend Derived operator-(
diff erence_type, valid_random_access_iterator);
+  friend 
diff erence_type operator-(valid_random_access_iterator, valid_random_access_iterator);
+
+  int& operator[](
diff erence_type) const;
+
+  friend std::strong_ordering operator<=>(Derived, Derived);
+};
+
+struct missing_plus_equals : valid_random_access_iterator<missing_plus_equals> {
+  void operator+=(
diff erence_type) = delete;
+};
+
+struct missing_minus_equals : valid_random_access_iterator<missing_minus_equals> {
+  void operator-=(
diff erence_type) = delete;
+};
+
+struct missing_plus_iter_
diff  : valid_random_access_iterator<missing_plus_iter_
diff > {
+  void operator+(
diff erence_type) = delete;
+};
+
+struct missing_plus_
diff _iter : valid_random_access_iterator<missing_plus_
diff _iter> {
+  friend missing_plus_
diff _iter operator+(
diff erence_type, missing_plus_
diff _iter) = delete;
+};
+
+struct missing_plus_iter_
diff _const_mut : valid_random_access_iterator<missing_plus_iter_
diff _const_mut> {
+  friend missing_plus_iter_
diff _const_mut operator+(missing_plus_iter_
diff _const_mut&, 
diff erence_type);
+  friend missing_plus_iter_
diff _const_mut operator+(const missing_plus_iter_
diff _const_mut&, 
diff erence_type) = delete;
+};
+
+struct missing_plus_iter_
diff _mut_const : valid_random_access_iterator<missing_plus_iter_
diff _mut_const> {
+  friend missing_plus_iter_
diff _mut_const operator+(missing_plus_iter_
diff _mut_const, 
diff erence_type);
+  friend missing_plus_iter_
diff _mut_const operator+(
diff erence_type, missing_plus_iter_
diff _mut_const&);
+  friend missing_plus_iter_
diff _mut_const operator+(
diff erence_type, const missing_plus_iter_
diff _mut_const&) = delete;
+};
+
+struct missing_minus_iter_
diff _const : valid_random_access_iterator<missing_minus_iter_
diff _const> {
+  friend missing_minus_iter_
diff _const operator-(missing_minus_iter_
diff _const&, 
diff erence_type);
+  friend missing_minus_iter_
diff _const operator-(const missing_minus_iter_
diff _const&, 
diff erence_type) = delete;
+};
+
+struct missing_minus_iter_iter : valid_random_access_iterator<missing_minus_iter_iter> {
+  friend missing_minus_iter_iter operator-(missing_minus_iter_iter, missing_minus_iter_iter) = delete;
+};
+
+struct missing_minus_const_iter_iter : valid_random_access_iterator<missing_minus_const_iter_iter> {
+  friend 
diff erence_type operator-(missing_minus_const_iter_iter&, missing_minus_const_iter_iter);
+  friend 
diff erence_type operator-(const missing_minus_const_iter_iter&, missing_minus_const_iter_iter) = delete;
+};
+
+struct missing_minus_iter_const_iter : valid_random_access_iterator<missing_minus_iter_const_iter> {
+  friend 
diff erence_type operator-(missing_minus_iter_const_iter, missing_minus_iter_const_iter&);
+  friend 
diff erence_type operator-(missing_minus_iter_const_iter, const missing_minus_iter_const_iter&) = delete;
+};
+
+struct missing_minus_const_iter_const_iter : valid_random_access_iterator<missing_minus_const_iter_const_iter> {
+  friend 
diff erence_type operator-(missing_minus_const_iter_const_iter&, missing_minus_const_iter_const_iter&);
+  friend 
diff erence_type operator-(const missing_minus_const_iter_const_iter&, missing_minus_const_iter_const_iter&);
+  friend 
diff erence_type operator-(missing_minus_const_iter_const_iter&, const missing_minus_const_iter_const_iter&);
+  friend 
diff erence_type operator-(const missing_minus_const_iter_const_iter&, const missing_minus_const_iter_const_iter&) = delete;
+};
+
+struct missing_subscript_operator : valid_random_access_iterator<missing_subscript_operator> {
+  int& operator[](
diff erence_type) = delete;
+};
+
+struct missing_const_subscript_operator : valid_random_access_iterator<missing_const_subscript_operator> {
+  int& operator[](
diff erence_type);
+  int& operator[](
diff erence_type) const = delete;
+};
+
+struct missing_less : valid_random_access_iterator<missing_less> {
+  friend bool operator<(missing_less, missing_less) = delete;
+};
+
+struct missing_const_mut_less : valid_random_access_iterator<missing_const_mut_less> {
+  friend bool operator<(missing_const_mut_less&, missing_const_mut_less&);
+  friend bool operator<(missing_const_mut_less&, const missing_const_mut_less&);
+  friend bool operator<(const missing_const_mut_less&, missing_const_mut_less&) = delete;
+  friend bool operator<(const missing_const_mut_less&, const missing_const_mut_less&);
+};
+
+struct missing_mut_const_less : valid_random_access_iterator<missing_mut_const_less> {
+  friend bool operator<(missing_mut_const_less&, missing_mut_const_less&);
+  friend bool operator<(missing_mut_const_less&, const missing_mut_const_less&) = delete;
+  friend bool operator<(const missing_mut_const_less&, missing_mut_const_less&);
+  friend bool operator<(const missing_mut_const_less&, const missing_mut_const_less&);
+};
+
+struct missing_const_const_less : valid_random_access_iterator<missing_const_const_less> {
+  friend bool operator<(missing_const_const_less&, missing_const_const_less&);
+  friend bool operator<(missing_const_const_less&, const missing_const_const_less&);
+  friend bool operator<(const missing_const_const_less&, missing_const_const_less&);
+  friend bool operator<(const missing_const_const_less&, const missing_const_const_less&) = delete;
+};
+
+struct missing_greater : valid_random_access_iterator<missing_greater> {
+  friend bool operator>(missing_greater, missing_greater) = delete;
+};
+
+struct missing_const_mut_greater : valid_random_access_iterator<missing_const_mut_greater> {
+  friend bool operator>(missing_const_mut_greater&, missing_const_mut_greater&);
+  friend bool operator>(missing_const_mut_greater&, const missing_const_mut_greater&);
+  friend bool operator>(const missing_const_mut_greater&, missing_const_mut_greater&) = delete;
+  friend bool operator>(const missing_const_mut_greater&, const missing_const_mut_greater&);
+};
+
+struct missing_mut_const_greater : valid_random_access_iterator<missing_mut_const_greater> {
+  friend bool operator>(missing_mut_const_greater&, missing_mut_const_greater&);
+  friend bool operator>(missing_mut_const_greater&, const missing_mut_const_greater&) = delete;
+  friend bool operator>(const missing_mut_const_greater&, missing_mut_const_greater&);
+  friend bool operator>(const missing_mut_const_greater&, const missing_mut_const_greater&);
+};
+
+struct missing_const_const_greater : valid_random_access_iterator<missing_const_const_greater> {
+  friend bool operator>(missing_const_const_greater&, missing_const_const_greater&);
+  friend bool operator>(missing_const_const_greater&, const missing_const_const_greater&);
+  friend bool operator>(const missing_const_const_greater&, missing_const_const_greater&);
+  friend bool operator>(const missing_const_const_greater&, const missing_const_const_greater&) = delete;
+};
+
+struct missing_less_eq : valid_random_access_iterator<missing_less_eq> {
+  friend bool operator<=(missing_less_eq, missing_less_eq) = delete;
+};
+
+struct missing_const_mut_less_eq : valid_random_access_iterator<missing_const_mut_less_eq> {
+  friend bool operator<=(missing_const_mut_less_eq&, missing_const_mut_less_eq&);
+  friend bool operator<=(missing_const_mut_less_eq&, const missing_const_mut_less_eq&);
+  friend bool operator<=(const missing_const_mut_less_eq&, missing_const_mut_less_eq&) = delete;
+  friend bool operator<=(const missing_const_mut_less_eq&, const missing_const_mut_less_eq&);
+};
+
+struct missing_mut_const_less_eq : valid_random_access_iterator<missing_mut_const_less_eq> {
+  friend bool operator<=(missing_mut_const_less_eq&, missing_mut_const_less_eq&);
+  friend bool operator<=(missing_mut_const_less_eq&, const missing_mut_const_less_eq&) = delete;
+  friend bool operator<=(const missing_mut_const_less_eq&, missing_mut_const_less_eq&);
+  friend bool operator<=(const missing_mut_const_less_eq&, const missing_mut_const_less_eq&);
+};
+
+struct missing_const_const_less_eq : valid_random_access_iterator<missing_const_const_less_eq> {
+  friend bool operator<=(missing_const_const_less_eq&, missing_const_const_less_eq&);
+  friend bool operator<=(missing_const_const_less_eq&, const missing_const_const_less_eq&);
+  friend bool operator<=(const missing_const_const_less_eq&, missing_const_const_less_eq&);
+  friend bool operator<=(const missing_const_const_less_eq&, const missing_const_const_less_eq&) = delete;
+};
+
+struct missing_greater_eq : valid_random_access_iterator<missing_greater_eq> {
+  friend bool operator>=(missing_greater_eq, missing_greater_eq) = delete;
+};
+
+struct missing_const_mut_greater_eq : valid_random_access_iterator<missing_const_mut_greater_eq> {
+  friend bool operator>=(missing_const_mut_greater_eq&, missing_const_mut_greater_eq&);
+  friend bool operator>=(missing_const_mut_greater_eq&, const missing_const_mut_greater_eq&);
+  friend bool operator>=(const missing_const_mut_greater_eq&, missing_const_mut_greater_eq&) = delete;
+  friend bool operator>=(const missing_const_mut_greater_eq&, const missing_const_mut_greater_eq&);
+};
+
+struct missing_mut_const_greater_eq : valid_random_access_iterator<missing_mut_const_greater_eq> {
+  friend bool operator>=(missing_mut_const_greater_eq&, missing_mut_const_greater_eq&);
+  friend bool operator>=(missing_mut_const_greater_eq&, const missing_mut_const_greater_eq&) = delete;
+  friend bool operator>=(const missing_mut_const_greater_eq&, missing_mut_const_greater_eq&);
+  friend bool operator>=(const missing_mut_const_greater_eq&, const missing_mut_const_greater_eq&);
+};
+
+struct missing_const_const_greater_eq : valid_random_access_iterator<missing_const_const_greater_eq> {
+  friend bool operator>=(missing_const_const_greater_eq&, missing_const_const_greater_eq&);
+  friend bool operator>=(missing_const_const_greater_eq&, const missing_const_const_greater_eq&);
+  friend bool operator>=(const missing_const_const_greater_eq&, missing_const_const_greater_eq&);
+  friend bool operator>=(const missing_const_const_greater_eq&, const missing_const_const_greater_eq&) = delete;
+};
+
+void check_random_access_iterator() {
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_equals); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__iter += __n' would be invalid: overload resolution selected deleted operator '+='}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_equals); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__iter -= __n' would be invalid: overload resolution selected deleted operator '-='}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_iter_
diff ); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__iter + __n' would be invalid: overload resolution selected deleted operator '+'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_
diff _iter); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__n + __iter' would be invalid: overload resolution selected deleted operator '+'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_iter_
diff _const_mut); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'std::as_const(__iter) + __n' would be invalid: overload resolution selected deleted operator '+'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_plus_iter_
diff _mut_const); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__n + std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '+'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_iter_
diff _const); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'std::as_const(__iter) - __n' would be invalid: overload resolution selected deleted operator '-'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_iter_iter); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__iter - __iter' would be invalid: overload resolution selected deleted operator '-'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_const_iter_iter); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'std::as_const(__iter) - __iter' would be invalid: overload resolution selected deleted operator '-'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_iter_const_iter); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__iter - std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '-'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_minus_const_iter_const_iter); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'std::as_const(__iter) - std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '-'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_subscript_operator); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__iter[__n]' would be invalid: overload resolution selected deleted operator '[]'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_subscript_operator); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'std::as_const(__iter)[__n]' would be invalid: overload resolution selected deleted operator '[]'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_less); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__iter < __iter' would be invalid: overload resolution selected deleted operator '<'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_mut_less); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'std::as_const(__iter) < __iter' would be invalid: overload resolution selected deleted operator '<'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_mut_const_less); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__iter < std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '<'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_const_less); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'std::as_const(__iter) < std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '<'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_greater); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__iter > __iter' would be invalid: overload resolution selected deleted operator '>'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_mut_greater); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'std::as_const(__iter) > __iter' would be invalid: overload resolution selected deleted operator '>'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_mut_const_greater); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__iter > std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '>'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_const_greater); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'std::as_const(__iter) > std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '>'}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_less_eq); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__iter <= __iter' would be invalid: overload resolution selected deleted operator '<='}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_mut_less_eq); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'std::as_const(__iter) <= __iter' would be invalid: overload resolution selected deleted operator '<='}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_mut_const_less_eq); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__iter <= std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '<='}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_const_less_eq); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'std::as_const(__iter) <= std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '<='}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_greater_eq); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__iter >= __iter' would be invalid: overload resolution selected deleted operator '>='}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_mut_greater_eq); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'std::as_const(__iter) >= __iter' would be invalid: overload resolution selected deleted operator '>='}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_mut_const_greater_eq); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because '__iter >= std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '>='}}
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(missing_const_const_greater_eq); // expected-error-re {{{{static assertion|static_assert}} failed}}
+  // expected-note@*:* {{because 'std::as_const(__iter) >= std::as_const(__iter)' would be invalid: overload resolution selected deleted operator '>='}}
+}


        


More information about the libcxx-commits mailing list