162 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// UNSUPPORTED: c++03, c++11, c++14, c++1710 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 <array>16#include <cassert>17#include <ranges>18 19#include "../types.h"20#include "test_range.h"21 22template <bool Const>23struct Iter {24 std::tuple<int>* it_;25 26 using value_type = std::tuple<int>;27 using difference_type = std::intptr_t;28 using iterator_concept = std::input_iterator_tag;29 30 constexpr decltype(auto) operator*() const { return *it_; }31 constexpr Iter& operator++() {32 ++it_;33 return *this;34 }35 constexpr void operator++(int) { ++it_; }36};37 38template <bool Const>39struct Sent {40 std::tuple<int>* end_;41 42 constexpr bool operator==(const Iter<Const>& i) const { return i.it_ == end_; }43};44 45template <bool Const>46struct CrossComparableSent {47 std::tuple<int>* end_;48 49 template <bool C>50 constexpr bool operator==(const Iter<C>& i) const {51 return i.it_ == end_;52 }53};54 55template <template <bool> typename St>56struct Range : TupleBufferView {57 using TupleBufferView::TupleBufferView;58 constexpr Iter<false> begin() { return Iter<false>{buffer_}; }59 constexpr Iter<true> begin() const { return Iter<true>{buffer_}; }60 constexpr St<false> end() { return St<false>{buffer_ + size_}; }61 constexpr St<true> end() const { return St<true>{buffer_ + size_}; }62};63 64using R = Range<Sent>;65using CrossComparableR = Range<CrossComparableSent>;66 67using std::ranges::elements_view;68using std::ranges::iterator_t;69using std::ranges::sentinel_t;70 71static_assert(weakly_equality_comparable_with<iterator_t<elements_view<R, 0>>, //72 sentinel_t<elements_view<R, 0>>>);73 74static_assert(!weakly_equality_comparable_with<iterator_t<const elements_view<R, 0>>, //75 sentinel_t<elements_view<R, 0>>>);76 77static_assert(!weakly_equality_comparable_with<iterator_t<elements_view<R, 0>>, //78 sentinel_t<const elements_view<R, 0>>>);79 80static_assert(weakly_equality_comparable_with<iterator_t<const elements_view<R, 0>>, //81 sentinel_t<const elements_view<R, 0>>>);82 83static_assert(weakly_equality_comparable_with<iterator_t<elements_view<CrossComparableR, 0>>, //84 sentinel_t<elements_view<CrossComparableR, 0>>>);85 86static_assert(weakly_equality_comparable_with<iterator_t<const elements_view<CrossComparableR, 0>>, //87 sentinel_t<elements_view<CrossComparableR, 0>>>);88 89static_assert(weakly_equality_comparable_with<iterator_t<elements_view<CrossComparableR, 0>>, //90 sentinel_t<const elements_view<CrossComparableR, 0>>>);91 92static_assert(weakly_equality_comparable_with<iterator_t<const elements_view<CrossComparableR, 0>>, //93 sentinel_t<const elements_view<CrossComparableR, 0>>>);94 95template <class R, bool ConstIter, bool ConstSent>96constexpr void testOne() {97 auto getBegin = [](auto&& rng) {98 if constexpr (ConstIter) {99 return std::as_const(rng).begin();100 } else {101 return rng.begin();102 }103 };104 105 auto getEnd = [](auto&& rng) {106 if constexpr (ConstSent) {107 return std::as_const(rng).end();108 } else {109 return rng.end();110 }111 };112 113 // iter == sentinel.base114 {115 std::tuple<int> buffer[] = {{1}};116 R v{buffer};117 std::ranges::elements_view<R, 0> ev(v);118 auto iter = getBegin(ev);119 auto st = getEnd(ev);120 ++iter;121 assert(iter == st);122 }123 124 // iter != sentinel.base125 {126 std::tuple<int> buffer[] = {{1}};127 R v{buffer};128 std::ranges::elements_view<R, 0> ev(v);129 auto iter = getBegin(ev);130 auto st = getEnd(ev);131 assert(iter != st);132 }133 134 // empty range135 {136 std::array<std::tuple<int>, 0> arr;137 R v{arr};138 std::ranges::elements_view<R, 0> ev(v);139 auto iter = getBegin(ev);140 auto sent = getEnd(ev);141 assert(iter == sent);142 }143}144 145constexpr bool test() {146 testOne<R, false, false>();147 testOne<R, true, true>();148 testOne<CrossComparableR, false, false>();149 testOne<CrossComparableR, true, true>();150 testOne<CrossComparableR, true, false>();151 testOne<CrossComparableR, false, true>();152 153 return true;154}155 156int main(int, char**) {157 test();158 static_assert(test());159 160 return 0;161}162