260 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// REQUIRES: std-at-least-c++2310 11// <ranges>12 13// friend constexpr bool operator==(const iterator& x, const iterator& y)14// requires ref-is-glvalue && forward_range<Base> &&15// equality_comparable<InnerIter>;16 17#include <ranges>18 19#include <array>20#include <cassert>21#include <utility>22 23#include "../types.h"24#include "test_comparisons.h"25 26template <class I1, class I2 = I1>27concept CanEq = requires(const I1& i1, const I2& i2) {28 { i1 == i2 } -> std::same_as<bool>;29 { i2 == i1 } -> std::same_as<bool>;30 { i1 != i2 } -> std::same_as<bool>;31 { i2 != i1 } -> std::same_as<bool>;32};33 34constexpr bool test() {35 { // `V` and `Pattern` are not empty. Test return types too.36 using V = std::array<std::array<int, 2>, 3>;37 using Pattern = std::array<long, 1>;38 using JWV = std::ranges::join_with_view<std::ranges::owning_view<V>, std::ranges::owning_view<Pattern>>;39 40 using Iter = std::ranges::iterator_t<JWV>;41 using CIter = std::ranges::iterator_t<const JWV>;42 static_assert(!std::same_as<Iter, CIter>);43 static_assert(CanEq<Iter>);44 static_assert(CanEq<CIter>);45 static_assert(CanEq<Iter, CIter>);46 47 JWV jwv(V{{{9, 8}, {7, 6}, {5, 4}}}, Pattern{0L});48 49 Iter it1 = jwv.begin();50 assert(*it1 == 9);51 assert(testEquality(it1, it1, true));52 53 Iter it2 = std::ranges::prev(jwv.end());54 assert(*it2 == 4);55 assert(testEquality(it2, it2, true));56 assert(testEquality(it1, it2, false));57 58 CIter cit1 = std::as_const(jwv).begin();59 assert(*cit1 == 9);60 assert(testEquality(cit1, cit1, true));61 assert(testEquality(it1, cit1, true));62 assert(testEquality(it2, cit1, false));63 64 CIter cit2 = std::ranges::prev(std::as_const(jwv).end());65 assert(*cit2 == 4);66 assert(testEquality(cit2, cit2, true));67 assert(testEquality(cit1, cit2, false));68 assert(testEquality(it1, cit2, false));69 assert(testEquality(it2, cit2, true));70 71 // `it1.inner_it_` and `it2.inner_it_` are equal, but `it1.outer_it_` and `it2.outer_it_` are not.72 std::ranges::advance(it1, 2);73 assert(*it1 == 0);74 std::ranges::advance(it2, -2);75 assert(*it2 == 0);76 assert(testEquality(it1, it2, false));77 78 // `cit1.inner_it_` and `cit2.inner_it_` are equal, but `cit1.outer_it_` and `cit2.outer_it_` are not.79 std::ranges::advance(cit1, 2);80 assert(*cit1 == 0);81 assert(testEquality(it1, cit1, true));82 std::ranges::advance(cit2, -2);83 assert(*cit2 == 0);84 assert(testEquality(it2, cit2, true));85 assert(testEquality(cit1, cit2, false));86 87 // `it1.inner_it_` and `it2.inner_it_` are equal, `it1.outer_it_` and `it2.outer_it_` are equal too.88 // `it1.inner_it_index()` and `it2.inner_it_index()` are equal to 1.89 ++it1;90 assert(*it1 == 7);91 std::ranges::advance(it2, -2);92 assert(*it2 == 7);93 assert(testEquality(it1, it2, true));94 95 // `cit1.inner_it_` and `cit2.inner_it_` are equal, `cit1.outer_it_` and `cit2.outer_it_` are equal too.96 // `cit1.inner_it_index()` and `cit2.inner_it_index()` are equal to 1.97 ++cit1;98 assert(*cit1 == 7);99 assert(testEquality(it1, cit1, true));100 std::ranges::advance(cit2, -2);101 assert(*cit2 == 7);102 assert(testEquality(it2, cit2, true));103 assert(testEquality(cit1, cit2, true));104 105 // `it1.inner_it_` and `it2.inner_it_` are equal, `it1.outer_it_` and `it2.outer_it_` are equal too.106 // `it1.inner_it_index()` and `it2.inner_it_index()` are equal to 0.107 --it1;108 assert(*it1 == 0);109 --it2;110 assert(*it2 == 0);111 assert(testEquality(it1, it2, true));112 113 // `cit1.inner_it_` and `cit2.inner_it_` are equal, `cit1.outer_it_` and `cit2.outer_it_` are equal too.114 // `cit1.inner_it_index()` and `cit2.inner_it_index()` are equal to 0.115 --cit1;116 assert(*cit1 == 0);117 assert(testEquality(it1, cit1, true));118 --cit2;119 assert(*cit2 == 0);120 assert(testEquality(it2, cit2, true));121 assert(testEquality(cit2, cit2, true));122 }123 124 { // `InnerIter` models input iterator and equality comparable. `Pattern` is empty.125 using Inner = BasicVectorView<int, ViewProperties{.common = false}, EqComparableInputIter>;126 using V = std::vector<Inner>;127 using Pattern = std::ranges::empty_view<int>;128 using JWV = std::ranges::join_with_view<std::ranges::owning_view<V>, std::ranges::owning_view<Pattern>>;129 130 using Iter = std::ranges::iterator_t<JWV>;131 using CIter = std::ranges::iterator_t<const JWV>;132 static_assert(!std::same_as<Iter, CIter>);133 static_assert(CanEq<Iter>);134 static_assert(CanEq<CIter>);135 static_assert(!CanEq<CIter, Iter>);136 137 JWV jwv(V{Inner{1, 2}, Inner{5, 6}, Inner{9, 0}}, Pattern{});138 139 {140 Iter it1 = jwv.begin();141 assert(*it1 == 1);142 Iter it2 = std::ranges::next(jwv.begin(), 2);143 assert(*it2 == 5);144 assert(testEquality(it1, it2, false));145 ++it1;146 ++it1;147 assert(testEquality(it1, it2, true));148 ++it1;149 assert(testEquality(it1, it2, false));150 }151 152 {153 CIter cit1 = std::as_const(jwv).begin();154 assert(*cit1 == 1);155 CIter cit2 = std::ranges::next(std::as_const(jwv).begin(), 2);156 assert(*cit2 == 5);157 assert(testEquality(cit1, cit2, false));158 ++cit1;159 ++cit1;160 assert(testEquality(cit1, cit2, true));161 ++cit1;162 assert(testEquality(cit1, cit2, false));163 }164 }165 166 { // `Pattern` is not empty. Some elements of `V` are.167 using Inner = BasicVectorView<int, ViewProperties{.common = false}, EqComparableInputIter>;168 using V = BasicVectorView<Inner, ViewProperties{}, forward_iterator>;169 using Pattern = BasicVectorView<int, ViewProperties{.common = false}, forward_iterator>;170 using JWV = std::ranges::join_with_view<V, Pattern>;171 172 using Iter = std::ranges::iterator_t<JWV>;173 using CIter = std::ranges::iterator_t<const JWV>;174 static_assert(!std::same_as<Iter, CIter>);175 static_assert(CanEq<Iter>);176 static_assert(CanEq<CIter>);177 static_assert(!CanEq<CIter, Iter>);178 179 JWV jwv(V{Inner{1}, Inner{}, Inner{27}}, Pattern{0});180 181 {182 Iter it1 = jwv.begin();183 assert(*it1 == 1);184 ++it1;185 assert(*it1 == 0);186 Iter it2 = jwv.begin();187 assert(testEquality(it1, it2, false));188 ++it2;189 assert(testEquality(it1, it2, true));190 191 ++it2;192 assert(*it1 == *it2);193 assert(testEquality(it1, it2, false));194 195 std::ranges::advance(it1, 2);196 ++it2;197 assert(*it1 == *it2);198 assert(testEquality(it1, it2, true));199 }200 201 {202 CIter cit1 = std::as_const(jwv).begin();203 assert(*cit1 == 1);204 ++cit1;205 assert(*cit1 == 0);206 CIter cit2 = std::as_const(jwv).begin();207 assert(testEquality(cit1, cit2, false));208 ++cit2;209 assert(testEquality(cit1, cit2, true));210 211 ++cit2;212 assert(*cit1 == *cit2);213 assert(testEquality(cit1, cit2, false));214 215 std::ranges::advance(cit1, 2);216 ++cit2;217 assert(*cit1 == *cit2);218 assert(testEquality(cit1, cit2, true));219 }220 }221 222 { // `ref-is-glvalue` is false223 using Inner = std::vector<int>;224 using V = RvalueVector<Inner>;225 using Pattern = std::ranges::empty_view<int>;226 using JWV = std::ranges::join_with_view<std::ranges::owning_view<V>, std::ranges::owning_view<Pattern>>;227 using Iter = std::ranges::iterator_t<JWV>;228 static_assert(!CanEq<Iter>);229 }230 231 { // `Base` does not model forward range232 using Inner = std::vector<int>;233 using V = BasicVectorView<Inner, ViewProperties{}, DefaultCtorInputIter>;234 using Pattern = std::ranges::empty_view<int>;235 using JWV = std::ranges::join_with_view<std::ranges::owning_view<V>, std::ranges::owning_view<Pattern>>;236 using Iter = std::ranges::iterator_t<JWV>;237 static_assert(!CanEq<Iter>);238 }239 240 { // `InnerIter` does not model equality comparable241 using Inner = BasicVectorView<int, ViewProperties{.common = false}, cpp20_input_iterator>;242 using V = std::vector<Inner>;243 using Pattern = std::ranges::empty_view<int>;244 using JWV = std::ranges::join_with_view<std::ranges::owning_view<V>, std::ranges::owning_view<Pattern>>;245 using Iter = std::ranges::iterator_t<JWV>;246 using CIter = std::ranges::iterator_t<const JWV>;247 static_assert(!CanEq<Iter>);248 static_assert(!CanEq<CIter>);249 }250 251 return true;252}253 254int main(int, char**) {255 test();256 static_assert(test());257 258 return 0;259}260