[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