110 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// 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 == true58 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 == false65 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 == true74 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 == false81 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 valid96 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