-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libc++][spaceship] Implements X::iterator container requirements. (#99343) #100440
Conversation
@llvm/pr-subscribers-libcxx Author: Mark de Wever (mordante) Changes…99343) This implements the requirements for the container iterator requirements for array, deque, vector, and Implements:
Implements parts of:
Fixes: #62486 Patch is 24.67 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/100440.diff 14 Files Affected:
diff --git a/libcxx/docs/Status/Cxx20Issues.csv b/libcxx/docs/Status/Cxx20Issues.csv
index 1a40a4472a405..8a431c922a2d9 100644
--- a/libcxx/docs/Status/Cxx20Issues.csv
+++ b/libcxx/docs/Status/Cxx20Issues.csv
@@ -264,7 +264,7 @@
"`3349 <https://wg21.link/LWG3349>`__","Missing ``__cpp_lib_constexpr_complex``\ for P0415R1","Prague","|Complete|","16.0"
"`3350 <https://wg21.link/LWG3350>`__","Simplify return type of ``lexicographical_compare_three_way``\ ","Prague","|Complete|","17.0","|spaceship|"
"`3351 <https://wg21.link/LWG3351>`__","``ranges::enable_safe_range``\ should not be constrained","Prague","|Complete|","15.0","|ranges|"
-"`3352 <https://wg21.link/LWG3352>`__","``strong_equality``\ isn't a thing","Prague","|Nothing To Do|","","|spaceship|"
+"`3352 <https://wg21.link/LWG3352>`__","``strong_equality``\ isn't a thing","Prague","|Complete|","19.0","|spaceship|"
"`3354 <https://wg21.link/LWG3354>`__","``has_strong_structural_equality``\ has a meaningless definition","Prague","|Nothing To Do|","","|spaceship|"
"`3355 <https://wg21.link/LWG3355>`__","The memory algorithms should support move-only input iterators introduced by P1207","Prague","|Complete|","15.0","|ranges|"
"`3356 <https://wg21.link/LWG3356>`__","``__cpp_lib_nothrow_convertible``\ should be ``__cpp_lib_is_nothrow_convertible``\ ","Prague","|Complete|","12.0"
diff --git a/libcxx/docs/Status/SpaceshipProjects.csv b/libcxx/docs/Status/SpaceshipProjects.csv
index e1cf2044cfd78..4dc43cdbbd08f 100644
--- a/libcxx/docs/Status/SpaceshipProjects.csv
+++ b/libcxx/docs/Status/SpaceshipProjects.csv
@@ -83,7 +83,7 @@ Section,Description,Dependencies,Assignee,Complete
"| `[string.view.synop] <https://wg21.link/string.view.synop>`_
| `[string.view.comparison] <https://wg21.link/string.view.comparison>`_",| `basic_string_view <https://reviews.llvm.org/D130295>`_,None,Mark de Wever,|Complete|
- `5.7 Clause 22: Containers library <https://wg21.link/p1614r2#clause-22-containers-library>`_,,,,
-| `[container.requirements.general] <https://wg21.link/container.requirements.general>`_,|,None,Unassigned,|Not Started|
+| `[container.requirements.general] <https://wg21.link/container.requirements.general>`_,|,None,Mark de Wever,|Complete|
| `[array.syn] <https://wg21.link/array.syn>`_ (`general <https://wg21.link/container.opt.reqmts>`_),| `array <https://reviews.llvm.org/D132265>`_,[expos.only.func],"| Adrian Vogelsgesang
| Hristo Hristov",|Complete|
| `[deque.syn] <https://wg21.link/deque.syn>`_ (`general <https://wg21.link/container.opt.reqmts>`_),| `deque <https://reviews.llvm.org/D144821>`_,[expos.only.func],Hristo Hristov,|Complete|
diff --git a/libcxx/include/__bit_reference b/libcxx/include/__bit_reference
index 606069d98be72..22637d4397412 100644
--- a/libcxx/include/__bit_reference
+++ b/libcxx/include/__bit_reference
@@ -16,6 +16,7 @@
#include <__bit/countr.h>
#include <__bit/invert_if.h>
#include <__bit/popcount.h>
+#include <__compare/ordering.h>
#include <__config>
#include <__fwd/bit_reference.h>
#include <__iterator/iterator_traits.h>
@@ -913,6 +914,7 @@ public:
return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;
}
+#if _LIBCPP_STD_VER <= 17
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
operator!=(const __bit_iterator& __x, const __bit_iterator& __y) {
return !(__x == __y);
@@ -937,6 +939,18 @@ public:
operator>=(const __bit_iterator& __x, const __bit_iterator& __y) {
return !(__x < __y);
}
+#else // _LIBCPP_STD_VER <= 17
+ _LIBCPP_HIDE_FROM_ABI constexpr friend strong_ordering
+ operator<=>(const __bit_iterator& __x, const __bit_iterator& __y) {
+ if (__x.__seg_ < __y.__seg_)
+ return strong_ordering::less;
+
+ if (__x.__seg_ == __y.__seg_)
+ return __x.__ctz_ <=> __y.__ctz_;
+
+ return strong_ordering::greater;
+ }
+#endif // _LIBCPP_STD_VER <= 17
private:
_LIBCPP_HIDE_FROM_ABI
diff --git a/libcxx/include/__iterator/bounded_iter.h b/libcxx/include/__iterator/bounded_iter.h
index ce0823b8c97e4..8a81c9ffbfc3f 100644
--- a/libcxx/include/__iterator/bounded_iter.h
+++ b/libcxx/include/__iterator/bounded_iter.h
@@ -11,6 +11,8 @@
#define _LIBCPP___ITERATOR_BOUNDED_ITER_H
#include <__assert>
+#include <__compare/ordering.h>
+#include <__compare/three_way_comparable.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__memory/pointer_traits.h>
@@ -201,10 +203,15 @@ struct __bounded_iter {
operator==(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
return __x.__current_ == __y.__current_;
}
+
+#if _LIBCPP_STD_VER <= 17
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
operator!=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
return __x.__current_ != __y.__current_;
}
+#endif
+
+ // TODO(mordante) disable these overloads in the LLVM 20 release.
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
operator<(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
return __x.__current_ < __y.__current_;
@@ -222,6 +229,23 @@ struct __bounded_iter {
return __x.__current_ >= __y.__current_;
}
+#if _LIBCPP_STD_VER >= 20
+ _LIBCPP_HIDE_FROM_ABI constexpr friend strong_ordering
+ operator<=>(__bounded_iter const& __x, __bounded_iter const& __y) noexcept {
+ if constexpr (three_way_comparable<_Iterator, strong_ordering>) {
+ return __x.__current_ <=> __y.__current_;
+ } else {
+ if (__x.__current_ < __y.__current_)
+ return strong_ordering::less;
+
+ if (__x.__current_ == __y.__current_)
+ return strong_ordering::equal;
+
+ return strong_ordering::greater;
+ }
+ }
+#endif // _LIBCPP_STD_VER >= 20
+
private:
template <class>
friend struct pointer_traits;
diff --git a/libcxx/include/__iterator/wrap_iter.h b/libcxx/include/__iterator/wrap_iter.h
index 252d13b26c9e2..56183c0ee794d 100644
--- a/libcxx/include/__iterator/wrap_iter.h
+++ b/libcxx/include/__iterator/wrap_iter.h
@@ -10,6 +10,8 @@
#ifndef _LIBCPP___ITERATOR_WRAP_ITER_H
#define _LIBCPP___ITERATOR_WRAP_ITER_H
+#include <__compare/ordering.h>
+#include <__compare/three_way_comparable.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
@@ -131,6 +133,7 @@ operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC
return __x.base() < __y.base();
}
+#if _LIBCPP_STD_VER <= 17
template <class _Iter1>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT {
@@ -142,7 +145,9 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {
return !(__x == __y);
}
+#endif
+// TODO(mordante) disable these overloads in the LLVM 20 release.
template <class _Iter1>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT {
@@ -179,6 +184,24 @@ operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEX
return !(__y < __x);
}
+#if _LIBCPP_STD_VER >= 20
+template <class _Iter1, class _Iter2>
+_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering
+operator<=>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) noexcept {
+ if constexpr (three_way_comparable_with<_Iter1, _Iter2, strong_ordering>) {
+ return __x.base() <=> __y.base();
+ } else {
+ if (__x.base() < __y.base())
+ return strong_ordering::less;
+
+ if (__x.base() == __y.base())
+ return strong_ordering::equal;
+
+ return strong_ordering::greater;
+ }
+}
+#endif // _LIBCPP_STD_VER >= 20
+
template <class _Iter1, class _Iter2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
#ifndef _LIBCPP_CXX03_LANG
diff --git a/libcxx/include/deque b/libcxx/include/deque
index 4fc994a6e229b..e73135a8647b9 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -376,10 +376,13 @@ public:
return __x.__ptr_ == __y.__ptr_;
}
+#if _LIBCPP_STD_VER <= 17
_LIBCPP_HIDE_FROM_ABI friend bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y) {
return !(__x == __y);
}
+#endif
+ // TODO(mordante) disable these overloads in the LLVM 20 release.
_LIBCPP_HIDE_FROM_ABI friend bool operator<(const __deque_iterator& __x, const __deque_iterator& __y) {
return __x.__m_iter_ < __y.__m_iter_ || (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);
}
@@ -396,6 +399,29 @@ public:
return !(__x < __y);
}
+#if _LIBCPP_STD_VER >= 20
+ _LIBCPP_HIDE_FROM_ABI friend strong_ordering operator<=>(const __deque_iterator& __x, const __deque_iterator& __y) {
+ if (__x.__m_iter_ < __y.__m_iter_)
+ return strong_ordering::less;
+
+ if (__x.__m_iter_ == __y.__m_iter_) {
+ if constexpr (three_way_comparable<pointer, strong_ordering>) {
+ return __x.__ptr_ <=> __y.__ptr_;
+ } else {
+ if (__x.__ptr_ < __y.__ptr_)
+ return strong_ordering::less;
+
+ if (__x.__ptr_ == __y.__ptr_)
+ return strong_ordering::equal;
+
+ return strong_ordering::greater;
+ }
+ }
+
+ return strong_ordering::greater;
+ }
+#endif // _LIBCPP_STD_VER >= 20
+
private:
_LIBCPP_HIDE_FROM_ABI explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT
: __m_iter_(__m),
@@ -2530,8 +2556,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const deque<_Tp, _Allocator>& __x,
template <class _Tp, class _Allocator>
_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp>
operator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) {
- return std::lexicographical_compare_three_way(
- __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
+ return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
}
#endif // _LIBCPP_STD_VER <= 17
diff --git a/libcxx/test/libcxx/iterators/bounded_iter/comparison.pass.cpp b/libcxx/test/libcxx/iterators/bounded_iter/comparison.pass.cpp
index 9c5df5da55b9c..cef2157469c8f 100644
--- a/libcxx/test/libcxx/iterators/bounded_iter/comparison.pass.cpp
+++ b/libcxx/test/libcxx/iterators/bounded_iter/comparison.pass.cpp
@@ -11,6 +11,7 @@
//
// Comparison operators
+#include <concepts>
#include <__iterator/bounded_iter.h>
#include "test_iterators.h"
@@ -59,6 +60,12 @@ TEST_CONSTEXPR_CXX14 bool tests() {
assert(iter1 >= iter1);
}
+#if TEST_STD_VER >= 20
+ // P1614
+ std::same_as<std::strong_ordering> decltype(auto) r1 = iter1 <=> iter2;
+ assert(r1 == std::strong_ordering::less);
+#endif
+
return true;
}
@@ -69,8 +76,11 @@ int main(int, char**) {
#endif
#if TEST_STD_VER > 17
- tests<contiguous_iterator<int*> >();
- static_assert(tests<contiguous_iterator<int*> >(), "");
+ tests<contiguous_iterator<int*>>();
+ static_assert(tests<contiguous_iterator<int*>>());
+
+ tests<three_way_contiguous_iterator<int*>>();
+ static_assert(tests<three_way_contiguous_iterator<int*>>());
#endif
return 0;
diff --git a/libcxx/test/std/containers/sequences/array/iterators.pass.cpp b/libcxx/test/std/containers/sequences/array/iterators.pass.cpp
index 106bc45c70998..710994c68295e 100644
--- a/libcxx/test/std/containers/sequences/array/iterators.pass.cpp
+++ b/libcxx/test/std/containers/sequences/array/iterators.pass.cpp
@@ -148,6 +148,15 @@ TEST_CONSTEXPR_CXX17 bool tests()
assert(std::rbegin(c) != std::rend(c));
assert(std::cbegin(c) != std::cend(c));
assert(std::crbegin(c) != std::crend(c));
+
+# if TEST_STD_VER >= 20
+ // P1614 + LWG3352
+ std::same_as<std::strong_ordering> decltype(auto) r1 = ii1 <=> ii2;
+ assert(r1 == std::strong_ordering::equal);
+
+ std::same_as<std::strong_ordering> decltype(auto) r2 = cii <=> ii2;
+ assert(r2 == std::strong_ordering::equal);
+# endif
}
{
typedef std::array<int, 0> C;
@@ -189,6 +198,15 @@ TEST_CONSTEXPR_CXX17 bool tests()
assert(std::rbegin(c) == std::rend(c));
assert(std::cbegin(c) == std::cend(c));
assert(std::crbegin(c) == std::crend(c));
+
+# if TEST_STD_VER >= 20
+ // P1614 + LWG3352
+ std::same_as<std::strong_ordering> decltype(auto) r1 = ii1 <=> ii2;
+ assert(r1 == std::strong_ordering::equal);
+
+ std::same_as<std::strong_ordering> decltype(auto) r2 = cii <=> ii2;
+ assert(r2 == std::strong_ordering::equal);
+# endif
}
}
#endif
diff --git a/libcxx/test/std/containers/sequences/deque/iterators.pass.cpp b/libcxx/test/std/containers/sequences/deque/iterators.pass.cpp
index 1f06ffde41ac2..484a2961fdb0c 100644
--- a/libcxx/test/std/containers/sequences/deque/iterators.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/iterators.pass.cpp
@@ -41,7 +41,27 @@ int main(int, char**)
i = c.begin();
C::const_iterator j;
j = c.cbegin();
+
assert(i == j);
+ assert(!(i != j));
+
+ assert(!(i < j));
+ assert((i <= j));
+
+ assert(!(i > j));
+ assert((i >= j));
+
+# if TEST_STD_VER >= 20
+ // P1614 + LWG3352
+ // When the allocator does not have operator<=> then the iterator uses a
+ // fallback to provide operator<=>.
+ // Make sure to test with an allocator that does not have operator<=>.
+ static_assert(!std::three_way_comparable<min_allocator<int>, std::strong_ordering>);
+ static_assert(std::three_way_comparable<typename C::iterator, std::strong_ordering>);
+
+ std::same_as<std::strong_ordering> decltype(auto) r1 = i <=> j;
+ assert(r1 == std::strong_ordering::equal);
+# endif
}
#endif
#if TEST_STD_VER > 11
@@ -74,6 +94,15 @@ int main(int, char**)
// assert ( cii != c.begin());
// assert ( cii != c.cend());
// assert ( ii1 != c.end());
+
+# if TEST_STD_VER >= 20
+ // P1614 + LWG3352
+ std::same_as<std::strong_ordering> decltype(auto) r1 = ii1 <=> ii2;
+ assert(r1 == std::strong_ordering::equal);
+
+ std::same_as<std::strong_ordering> decltype(auto) r2 = cii <=> ii2;
+ assert(r2 == std::strong_ordering::equal);
+# endif // TEST_STD_VER > 20
}
#endif
diff --git a/libcxx/test/std/containers/sequences/vector.bool/iterators.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/iterators.pass.cpp
index 9aaaac7a5557f..1e4877e8d2443 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/iterators.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/iterators.pass.cpp
@@ -77,7 +77,21 @@ TEST_CONSTEXPR_CXX20 bool tests()
C::iterator i = c.begin();
C::iterator j = c.end();
assert(std::distance(i, j) == 0);
+
assert(i == j);
+ assert(!(i != j));
+
+ assert(!(i < j));
+ assert((i <= j));
+
+ assert(!(i > j));
+ assert((i >= j));
+
+# if TEST_STD_VER >= 20
+ // P1614 + LWG3352
+ std::same_as<std::strong_ordering> decltype(auto) r = i <=> j;
+ assert(r == std::strong_ordering::equal);
+# endif
}
{
typedef bool T;
@@ -86,7 +100,21 @@ TEST_CONSTEXPR_CXX20 bool tests()
C::const_iterator i = c.begin();
C::const_iterator j = c.end();
assert(std::distance(i, j) == 0);
+
assert(i == j);
+ assert(!(i != j));
+
+ assert(!(i < j));
+ assert((i <= j));
+
+ assert(!(i > j));
+ assert((i >= j));
+
+# if TEST_STD_VER >= 20
+ // P1614 + LWG3352
+ std::same_as<std::strong_ordering> decltype(auto) r = i <=> j;
+ assert(r == std::strong_ordering::equal);
+# endif
}
{
typedef bool T;
@@ -131,6 +159,15 @@ TEST_CONSTEXPR_CXX20 bool tests()
assert ( (cii >= ii1 ));
assert (cii - ii1 == 0);
assert (ii1 - cii == 0);
+
+# if TEST_STD_VER >= 20
+ // P1614 + LWG3352
+ std::same_as<std::strong_ordering> decltype(auto) r1 = ii1 <=> ii2;
+ assert(r1 == std::strong_ordering::equal);
+
+ std::same_as<std::strong_ordering> decltype(auto) r2 = cii <=> ii2;
+ assert(r2 == std::strong_ordering::equal);
+# endif // TEST_STD_VER > 20
}
#endif
diff --git a/libcxx/test/std/containers/sequences/vector/iterators.pass.cpp b/libcxx/test/std/containers/sequences/vector/iterators.pass.cpp
index 70e0e35767e09..0aa7ad0d42ed7 100644
--- a/libcxx/test/std/containers/sequences/vector/iterators.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/iterators.pass.cpp
@@ -87,7 +87,27 @@ TEST_CONSTEXPR_CXX20 bool tests()
C::iterator i = c.begin();
C::iterator j = c.end();
assert(std::distance(i, j) == 0);
+
assert(i == j);
+ assert(!(i != j));
+
+ assert(!(i < j));
+ assert((i <= j));
+
+ assert(!(i > j));
+ assert((i >= j));
+
+# if TEST_STD_VER >= 20
+ // P1614 + LWG3352
+ // When the allocator does not have operator<=> then the iterator uses a
+ // fallback to provide operator<=>.
+ // Make sure to test with an allocator that does not have operator<=>.
+ static_assert(!std::three_way_comparable<min_allocator<int>, std::strong_ordering>);
+ static_assert(std::three_way_comparable<typename C::iterator, std::strong_ordering>);
+
+ std::same_as<std::strong_ordering> decltype(auto) r1 = i <=> j;
+ assert(r1 == std::strong_ordering::equal);
+# endif
}
{
typedef int T;
@@ -96,7 +116,26 @@ TEST_CONSTEXPR_CXX20 bool tests()
C::const_iterator i = c.begin();
C::const_iterator j = c.end();
assert(std::distance(i, j) == 0);
+
assert(i == j);
+ assert(!(i != j));
+
+ assert(!(i < j));
+ assert((i <= j));
+
+ assert(!(i > j));
+ assert((i >= j));
+
+# if TEST_STD_VER >= 20
+ // When the allocator does not have operator<=> then the iterator uses a
+ // fallback to provide operator<=>.
+ // Make sure to test with an allocator that does not have operator<=>.
+ static_assert(!std::three_way_comparable<min_allocator<int>, std::strong_ordering>);
+ static_assert(std::three_way_comparable<typename C::iterator, std::strong_ordering>);
+
+ std::same_as<std::strong_ordering> decltype(auto) r1 = i <=> j;
+ assert(r1 == std::strong_ordering::equal);
+# endif
}
{
typedef int T;
@@ -164,8 +203,16 @@ TEST_CONSTEXPR_CXX20 bool tests()
assert ( (cii >= ii1 ));
assert (cii - ii1 == 0);
assert (ii1 - cii == 0);
+# if TEST_STD_VER >= 20
+ // P1614 + LWG3352
+ std::same_as<std::strong_ordering> decltype(auto) r1 = ii1 <=> ii2;
+ assert(r1 == std::strong_ordering::equal);
+
+ std::same_as<std::strong_ordering> decltype(auto) r2 = cii <=> ii2;
+ assert(r2 == std::strong_ordering::equal);
+# endif // TEST_STD_VER > 20
}
-#endif
+#endif // TEST_STD_VER > 11
return true;
}
diff --git a/libcxx/test/std/containers/views/views.span/span.iterators/iterator.pass.cpp b/libcxx/test/std/containers/views/views.span/span.iterators/iterator.pass.cpp
new file mode 100644
index 0000000000000..13a7628e6043d
--- /dev/null
+++ b/libcxx/test/std/containers/views/views.span/span.iterators/iterator.pass.cpp
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <span>
+
+// class iterator
+
+#include <cassert>
+#include <concepts>
+#include <iterator>
+#include <span>
+#include <string>
+#include <version> // __cpp_lib_ranges_as_const is not defined in span.
+
+#include "test_macros.h"
+
+template <class T>
+constexpr void test_type() {
+ using C = std::span<T>;
+ typename C::iterator ii1{}, ii2{};
+ typename C::iterator ii4 = ii1;
+ // TODO Test against C++23 after implementing
+ // P2278R4 cbegin should always return a constant iterator
+ // The means adjusting the #ifdef to guard against C++23.
+#ifdef __cpp_lib_r...
[truncated]
|
Cherry-picking #99343 failed. |
…lvm#99343) This implements the requirements for the container iterator requirements for array, deque, vector, and `vector<bool>`. Implements: - LWG3352 strong_equality isn't a thing Implements parts of: - P1614R2 The Mothership has Landed Fixes: llvm#62486
456668e
to
05446fb
Compare
@mordante (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR. |
This implements the requirements for the container iterator requirements for array, deque, vector, and
vector<bool>
.Implements:
Implements parts of:
Fixes: #62486