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// REQUIRES: std-at-least-c++23
10
11// <ranges>
12
13// template<bool OtherConst>
14// requires sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
15// friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
16
17#include <ranges>
18
19#include <cassert>
20#include <type_traits>
21#include <utility>
22#include <vector>
23
24#include "../types.h"
25#include "test_comparisons.h"
26#include "test_iterators.h"
27
28struct NonCrossConstComparableView : std::ranges::view_base {
29 using NonConstRange = std::vector<int>;
30 NonConstRange* begin();
31 sentinel_wrapper<NonConstRange*> end();
32
33 using ConstRange = BasicVectorView<int, ViewProperties{}, forward_iterator>;
34 ConstRange* begin() const;
35 sentinel_wrapper<ConstRange*> end() const;
36};
37
38static_assert(std::ranges::range<NonCrossConstComparableView>);
39static_assert(std::ranges::range<const NonCrossConstComparableView>);
40
41constexpr bool test() {
42 using Inner = BasicVectorView<int, ViewProperties{.common = false}, cpp20_input_iterator>;
43 using V = std::vector<Inner>;
44 using Pattern = std::ranges::single_view<int>;
45 using JWV = std::ranges::join_with_view<std::ranges::owning_view<V>, Pattern>;
46 static_assert(!std::ranges::common_range<JWV>);
47
48 using Iter = std::ranges::iterator_t<JWV>;
49 using CIter = std::ranges::iterator_t<const JWV>;
50 static_assert(!std::same_as<Iter, CIter>);
51
52 using Sent = std::ranges::sentinel_t<JWV>;
53 using CSent = std::ranges::sentinel_t<const JWV>;
54 static_assert(!std::same_as<Sent, CSent>);
55
56 { // Compare iterator<Const> with sentinel<Const>
57 { // Const == true
58 AssertEqualityReturnBool<CIter, CSent>();
59 const JWV jwv(V{Inner{1, 2}, Inner{4}}, 3);
60 assert(testEquality(std::ranges::next(jwv.begin(), 4), jwv.end(), true));
61 assert(testEquality(jwv.begin(), jwv.end(), false));
62 }
63
64 { // Const == false
65 AssertEqualityReturnBool<Iter, Sent>();
66 JWV jwv(V{Inner{5}, Inner{7, 8}}, 6);
67 assert(testEquality(std::ranges::next(jwv.begin(), 4), jwv.end(), true));
68 assert(testEquality(std::ranges::next(jwv.begin(), 2), jwv.end(), false));
69 }
70 }
71
72 { // Compare iterator<Const> with sentinel<!Const>
73 { // Const == true
74 AssertEqualityReturnBool<CIter, Sent>();
75 JWV jwv(V{Inner{9, 10}, Inner{12}}, 11);
76 assert(testEquality(std::ranges::next(std::as_const(jwv).begin(), 4), jwv.end(), true));
77 assert(testEquality(std::ranges::next(std::as_const(jwv).begin(), 2), jwv.end(), false));
78 }
79
80 { // Const == false
81 AssertEqualityReturnBool<Iter, CSent>();
82 JWV jwv(V{Inner{13}, Inner{15, 16}}, 14);
83 assert(testEquality(std::ranges::next(jwv.begin(), 4), std::as_const(jwv).end(), true));
84 assert(testEquality(std::ranges::next(jwv.begin(), 3), std::as_const(jwv).end(), false));
85 }
86 }
87
88 { // Check invalid comparisons between iterator<Const> and sentinel<!Const>
89 using JWV2 = std::ranges::join_with_view<NonCrossConstComparableView, Pattern>;
90 static_assert(!std::ranges::common_range<JWV2>);
91
92 static_assert(!weakly_equality_comparable_with<std::ranges::iterator_t<const JWV2>, std::ranges::sentinel_t<JWV2>>);
93 static_assert(!weakly_equality_comparable_with<std::ranges::iterator_t<JWV2>, std::ranges::sentinel_t<const JWV2>>);
94
95 // Those should be valid
96 static_assert(weakly_equality_comparable_with<std::ranges::iterator_t<JWV2>, std::ranges::sentinel_t<JWV2>>);
97 static_assert(
98 weakly_equality_comparable_with<std::ranges::iterator_t<const JWV2>, std::ranges::sentinel_t<const JWV2>>);
99 }
100
101 return true;
102}
103
104int main(int, char**) {
105 test();
106 static_assert(test());
107
108 return 0;
109}
110

source code of libcxx/test/std/ranges/range.adaptors/range.join.with/range.join.with.sentinel/eq.pass.cpp