xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/eq.pass.cpp (revision 808d794a45e169601ff16f72beae2f7bd79342a2)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10 
11 // template<bool OtherConst>
12 //   requires sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
13 // friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
14 
15 #include <cassert>
16 #include <concepts>
17 #include <functional>
18 #include <ranges>
19 #include <type_traits>
20 
21 #include "../types.h"
22 #include "test_range.h"
23 
24 using Iterator = random_access_iterator<BufferView<int*>*>;
25 using ConstIterator = random_access_iterator<const BufferView<int*>*>;
26 
27 template <bool Const>
28 struct ConstComparableSentinel {
29 
30   using Iter = std::conditional_t<Const, ConstIterator, Iterator>;
31   Iter iter_;
32 
33   explicit ConstComparableSentinel() = default;
ConstComparableSentinelConstComparableSentinel34   constexpr explicit ConstComparableSentinel(const Iter& it) : iter_(it) {}
35 
operator ==(const Iterator & i,const ConstComparableSentinel & s)36   constexpr friend bool operator==(const Iterator& i, const ConstComparableSentinel& s) {
37     return base(i) == base(s.iter_);
38   }
39 
operator ==(const ConstIterator & i,const ConstComparableSentinel & s)40   constexpr friend bool operator==(const ConstIterator& i, const ConstComparableSentinel& s) {
41     return base(i) == base(s.iter_);
42   }
43 };
44 
45 struct ConstComparableView : BufferView<BufferView<int*>*> {
46   using BufferView<BufferView<int*>*>::BufferView;
47 
beginConstComparableView48   constexpr auto begin() { return Iterator(data_); }
beginConstComparableView49   constexpr auto begin() const { return ConstIterator(data_); }
endConstComparableView50   constexpr auto end() { return ConstComparableSentinel<false>(Iterator(data_ + size_)); }
endConstComparableView51   constexpr auto end() const { return ConstComparableSentinel<true>(ConstIterator(data_ + size_)); }
52 };
53 
54 static_assert(weakly_equality_comparable_with<std::ranges::iterator_t<ConstComparableView>,
55                                               std::ranges::sentinel_t<const ConstComparableView>>);
56 static_assert(weakly_equality_comparable_with<std::ranges::iterator_t<const ConstComparableView>,
57                                               std::ranges::sentinel_t<ConstComparableView>>);
58 
test()59 constexpr bool test() {
60   int buffer[4][4] = {{1111, 2222, 3333, 4444}, {555, 666, 777, 888}, {99, 1010, 1111, 1212}, {13, 14, 15, 16}};
61 
62   // test iterator<false> == sentinel<false>
63   {
64     ChildView children[4] = {ChildView(buffer[0]), ChildView(buffer[1]), ChildView(buffer[2]), ChildView(buffer[3])};
65     auto jv               = std::ranges::join_view(ParentView(children));
66     assert(jv.end() == std::ranges::next(jv.begin(), 16));
67   }
68 
69   // test iterator<false> == sentinel<true>
70   {
71     ChildView children[4] = {ChildView(buffer[0]), ChildView(buffer[1]), ChildView(buffer[2]), ChildView(buffer[3])};
72     using ParentT         = std::remove_all_extents_t<decltype(children)>;
73     auto jv               = std::ranges::join_view(ForwardParentView<ParentT>(children));
74     assert(std::as_const(jv).end() == std::ranges::next(jv.begin(), 16));
75   }
76 
77   // test iterator<true> == sentinel<true>
78   {
79     CopyableChild children[4] = {CopyableChild(buffer[0]), CopyableChild(buffer[1]), CopyableChild(buffer[2]),
80                                  CopyableChild(buffer[3])};
81     using ParentT             = std::remove_all_extents_t<decltype(children)>;
82     const auto jv             = std::ranges::join_view(ForwardParentView<ParentT>(children));
83     assert(jv.end() == std::ranges::next(jv.begin(), 16));
84   }
85 
86   // test iterator<Const> == sentinel<!Const>
87   {
88     BufferView<int*> inners[] = {buffer[0], buffer[1]};
89     ConstComparableView outer(inners);
90     auto jv = std::ranges::join_view(outer);
91     assert(jv.end() == std::ranges::next(jv.begin(), 8));
92     assert(std::as_const(jv).end() == std::ranges::next(jv.begin(), 8));
93     assert(jv.end() == std::ranges::next(std::as_const(jv).begin(), 8));
94   }
95 
96   return true;
97 }
98 
main(int,char **)99 int main(int, char**) {
100   test();
101   static_assert(test());
102 
103   return 0;
104 }
105