brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · b00b3dd Raw
201 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//  friend constexpr bool operator==(const iterator_t<Base>& x, const sentinel& y);12//13//  template<bool OtherConst = !Const>14//    requires sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>15//  friend constexpr bool operator==(const iterator_t<maybe-const<OtherConst, V>>& x,16//                                   const sentinel& y);17 18#include <array>19#include <cassert>20#include <ranges>21 22#include "../types.h"23 24template <bool Const>25struct Iter {26  int* it_;27 28  using value_type       = int;29  using difference_type  = std::intptr_t;30  using iterator_concept = std::input_iterator_tag;31 32  constexpr decltype(auto) operator*() const { return *it_; }33  constexpr Iter& operator++() {34    ++it_;35    return *this;36  }37  constexpr void operator++(int) { ++it_; }38};39 40template <bool Const>41struct Sent {42  int* end_;43 44  constexpr bool operator==(const Iter<Const>& i) const { return i.it_ == end_; }45};46 47template <bool Const>48struct CrossComparableSent {49  int* end_;50 51  template <bool C>52  constexpr bool operator==(const Iter<C>& i) const {53    return i.it_ == end_;54  }55};56 57template <template <bool> typename St>58struct Range : IntBufferViewBase {59  using IntBufferViewBase::IntBufferViewBase;60  constexpr Iter<false> begin() { return Iter<false>{buffer_}; }61  constexpr Iter<true> begin() const { return Iter<true>{buffer_}; }62  constexpr St<false> end() { return St<false>{buffer_ + size_}; }63  constexpr St<true> end() const { return St<true>{buffer_ + size_}; }64};65 66using R                = Range<Sent>;67using CrossComparableR = Range<CrossComparableSent>;68 69struct LessThan3 {70  constexpr bool operator()(int i) const { return i < 3; }71};72 73using std::ranges::iterator_t;74using std::ranges::sentinel_t;75using std::ranges::take_while_view;76 77static_assert(weakly_equality_comparable_with<iterator_t<take_while_view<R, LessThan3>>, //78                                              sentinel_t<take_while_view<R, LessThan3>>>);79 80static_assert(!weakly_equality_comparable_with<iterator_t<const take_while_view<R, LessThan3>>, //81                                               sentinel_t<take_while_view<R, LessThan3>>>);82 83static_assert(!weakly_equality_comparable_with<iterator_t<take_while_view<R, LessThan3>>, //84                                               sentinel_t<const take_while_view<R, LessThan3>>>);85 86static_assert(weakly_equality_comparable_with<iterator_t<const take_while_view<R, LessThan3>>, //87                                              sentinel_t<const take_while_view<R, LessThan3>>>);88 89static_assert(weakly_equality_comparable_with<iterator_t<take_while_view<CrossComparableR, LessThan3>>, //90                                              sentinel_t<take_while_view<CrossComparableR, LessThan3>>>);91 92static_assert(weakly_equality_comparable_with<iterator_t<const take_while_view<CrossComparableR, LessThan3>>, //93                                              sentinel_t<take_while_view<CrossComparableR, LessThan3>>>);94 95static_assert(weakly_equality_comparable_with<iterator_t<take_while_view<CrossComparableR, LessThan3>>, //96                                              sentinel_t<const take_while_view<CrossComparableR, LessThan3>>>);97 98static_assert(weakly_equality_comparable_with<iterator_t<const take_while_view<CrossComparableR, LessThan3>>, //99                                              sentinel_t<const take_while_view<CrossComparableR, LessThan3>>>);100 101template <class R, bool ConstIter, bool ConstSent>102constexpr void testOne() {103  auto getBegin = [](auto&& rng) {104    if constexpr (ConstIter) {105      return std::as_const(rng).begin();106    } else {107      return rng.begin();108    }109  };110 111  auto getEnd = [](auto&& rng) {112    if constexpr (ConstSent) {113      return std::as_const(rng).end();114    } else {115      return rng.end();116    }117  };118 119  // iter == sentinel.base120  {121    int buffer[] = {1};122    R v{buffer};123    std::ranges::take_while_view twv(v, LessThan3{});124    auto iter = getBegin(twv);125    auto st   = getEnd(twv);126    ++iter;127    assert(iter == st);128  }129 130  // iter != sentinel.base && pred(*iter)131  {132    int buffer[] = {1, 3, 4};133    R v{buffer};134    std::ranges::take_while_view twv(v, LessThan3{});135    auto iter = getBegin(twv);136    auto st   = getEnd(twv);137    assert(iter != st);138    ++iter;139    assert(iter == st);140  }141 142  // iter != sentinel.base && !pred(*iter)143  {144    int buffer[] = {1, 2, 3, 4, 3, 2, 1};145    R v{buffer};146    std::ranges::take_while_view twv(v, LessThan3{});147    auto iter = getBegin(twv);148    auto sent = getEnd(twv);149    assert(iter != sent);150  }151 152  // empty range153  {154    std::array<int, 0> arr;155    R v{arr};156    std::ranges::take_while_view twv(v, LessThan3{});157    auto iter = getBegin(twv);158    auto sent = getEnd(twv);159    assert(iter == sent);160  }161}162 163constexpr bool test() {164  testOne<R, false, false>();165  testOne<R, true, true>();166  testOne<CrossComparableR, false, false>();167  testOne<CrossComparableR, true, true>();168 169  // LWG 3449 `take_view` and `take_while_view`'s `sentinel<false>` not comparable with their const iterator170  testOne<CrossComparableR, true, false>();171  testOne<CrossComparableR, false, true>();172 173  // test std::invoke is used174  {175    struct Data {176      bool b;177    };178 179    Data buffer[] = {{true}, {true}, {false}};180    std::ranges::take_while_view twv(buffer, &Data::b);181    auto it = twv.begin();182    auto st = twv.end();183    assert(it != st);184 185    ++it;186    assert(it != st);187 188    ++it;189    assert(it == st);190  }191 192  return true;193}194 195int main(int, char**) {196  test();197  static_assert(test());198 199  return 0;200}201