[libc++][spaceship] Implements X::iterator container requirements. (#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: https://github.com/llvm/llvm-project/issues/62486
This commit is contained in:
parent
5c03c4fc26
commit
05446fb31a
@ -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"
|
||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
@ -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|
|
||||
|
|
@ -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
|
||||
|
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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_ranges_as_const
|
||||
typename C::const_iterator cii{};
|
||||
#endif
|
||||
assert(ii1 == ii2);
|
||||
assert(ii1 == ii4);
|
||||
#ifdef __cpp_lib_ranges_as_const
|
||||
assert(ii1 == cii);
|
||||
#endif
|
||||
|
||||
assert(!(ii1 != ii2));
|
||||
#ifdef __cpp_lib_ranges_as_const
|
||||
assert(!(ii1 != cii));
|
||||
#endif
|
||||
|
||||
T v;
|
||||
C c{&v, 1};
|
||||
assert(c.begin() == std::begin(c));
|
||||
assert(c.rbegin() == std::rbegin(c));
|
||||
#ifdef __cpp_lib_ranges_as_const
|
||||
assert(c.cbegin() == std::cbegin(c));
|
||||
assert(c.crbegin() == std::crbegin(c));
|
||||
#endif
|
||||
|
||||
assert(c.end() == std::end(c));
|
||||
assert(c.rend() == std::rend(c));
|
||||
#ifdef __cpp_lib_ranges_as_const
|
||||
assert(c.cend() == std::cend(c));
|
||||
assert(c.crend() == std::crend(c));
|
||||
#endif
|
||||
|
||||
assert(std::begin(c) != std::end(c));
|
||||
assert(std::rbegin(c) != std::rend(c));
|
||||
#ifdef __cpp_lib_ranges_as_const
|
||||
assert(std::cbegin(c) != std::cend(c));
|
||||
assert(std::crbegin(c) != std::crend(c));
|
||||
#endif
|
||||
|
||||
// P1614 + LWG3352
|
||||
std::same_as<std::strong_ordering> decltype(auto) r1 = ii1 <=> ii2;
|
||||
assert(r1 == std::strong_ordering::equal);
|
||||
|
||||
#ifdef __cpp_lib_ranges_as_const
|
||||
std::same_as<std::strong_ordering> decltype(auto) r2 = cii <=> ii2;
|
||||
assert(r2 == std::strong_ordering::equal);
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr bool test() {
|
||||
test_type<char>();
|
||||
test_type<int>();
|
||||
test_type<std::string>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
static_assert(test(), "");
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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: !stdlib=libc++ && (c++03 || c++11 || c++14)
|
||||
|
||||
// <string_view>
|
||||
|
||||
// class iterator
|
||||
|
||||
#include <cassert>
|
||||
#include <concepts>
|
||||
#include <iterator>
|
||||
#include <string_view>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "make_string.h"
|
||||
|
||||
template <class CharT>
|
||||
TEST_CONSTEXPR_CXX14 void test_type() {
|
||||
using C = std::basic_string_view<CharT>;
|
||||
typename C::iterator ii1 = typename C::iterator(), ii2 = typename C::iterator();
|
||||
typename C::iterator ii4 = ii1;
|
||||
typename C::const_iterator cii = typename C::const_iterator();
|
||||
assert(ii1 == ii2);
|
||||
assert(ii1 == ii4);
|
||||
assert(ii1 == cii);
|
||||
|
||||
assert(!(ii1 != ii2));
|
||||
assert(!(ii1 != cii));
|
||||
|
||||
#if TEST_STD_VER >= 17
|
||||
C c = MAKE_STRING_VIEW(CharT, "abc");
|
||||
assert(c.begin() == std::begin(c));
|
||||
assert(c.rbegin() == std::rbegin(c));
|
||||
assert(c.cbegin() == std::cbegin(c));
|
||||
assert(c.crbegin() == std::crbegin(c));
|
||||
|
||||
assert(c.end() == std::end(c));
|
||||
assert(c.rend() == std::rend(c));
|
||||
assert(c.cend() == std::cend(c));
|
||||
assert(c.crend() == std::crend(c));
|
||||
|
||||
assert(std::begin(c) != std::end(c));
|
||||
assert(std::rbegin(c) != std::rend(c));
|
||||
assert(std::cbegin(c) != std::cend(c));
|
||||
assert(std::crbegin(c) != std::crend(c));
|
||||
#endif
|
||||
|
||||
#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 = ii1 <=> ii2;
|
||||
assert(r2 == std::strong_ordering::equal);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CONSTEXPR_CXX14 bool test() {
|
||||
test_type<char>();
|
||||
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
||||
test_type<wchar_t>();
|
||||
#endif
|
||||
#ifndef TEST_HAS_NO_CHAR8_T
|
||||
test_type<char8_t>();
|
||||
#endif
|
||||
test_type<char16_t>();
|
||||
test_type<char32_t>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
#if TEST_STD_VER >= 14
|
||||
static_assert(test(), "");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
@ -389,6 +389,8 @@ public:
|
||||
friend TEST_CONSTEXPR bool operator> (const contiguous_iterator& x, const contiguous_iterator& y) {return x.it_ > y.it_;}
|
||||
friend TEST_CONSTEXPR bool operator>=(const contiguous_iterator& x, const contiguous_iterator& y) {return x.it_ >= y.it_;}
|
||||
|
||||
// Note no operator<=>, use three_way_contiguous_iterator for testing operator<=>
|
||||
|
||||
friend TEST_CONSTEXPR It base(const contiguous_iterator& i) { return i.it_; }
|
||||
|
||||
template <class T>
|
||||
|
Loading…
x
Reference in New Issue
Block a user