brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · d8a3149 Raw
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