brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · 1e4d2a4 Raw
144 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 CI<Const>& y, const sentinel& x);12// template<bool OtherConst = !Const>13//   requires sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>14// friend constexpr bool operator==(const CI<OtherConst>& y, const sentinel& x);15 16#include <cassert>17#include <cstddef>18#include <ranges>19#include <type_traits>20#include <utility>21 22#include "test_comparisons.h"23#include "test_iterators.h"24#include "test_range.h"25 26template <bool Const>27using MaybeConstIterator = cpp20_input_iterator<std::conditional_t<Const, const int*, int*>>;28 29template <bool Const>30class CrossConstComparableSentinel {31  using Base = std::conditional_t<Const, const int*, int*>;32  Base base_;33 34public:35  CrossConstComparableSentinel() = default;36  constexpr explicit CrossConstComparableSentinel(Base base) : base_(base) {}37 38  friend constexpr bool operator==(const MaybeConstIterator<Const>& it, const CrossConstComparableSentinel& se) {39    return base(it) == se.base_;40  }41 42  friend constexpr bool operator==(const MaybeConstIterator<!Const>& it, const CrossConstComparableSentinel& se) {43    return base(it) == se.base_;44  }45};46 47static_assert(std::sentinel_for<CrossConstComparableSentinel<true>, MaybeConstIterator<false>>);48static_assert(std::sentinel_for<CrossConstComparableSentinel<true>, MaybeConstIterator<true>>);49static_assert(std::sentinel_for<CrossConstComparableSentinel<false>, MaybeConstIterator<false>>);50static_assert(std::sentinel_for<CrossConstComparableSentinel<false>, MaybeConstIterator<true>>);51 52struct CrossConstComparableView : std::ranges::view_base {53  template <std::size_t N>54  constexpr explicit CrossConstComparableView(int (&arr)[N]) : b_(arr), e_(arr + N) {}55 56  constexpr MaybeConstIterator<false> begin() { return MaybeConstIterator<false>{b_}; }57  constexpr CrossConstComparableSentinel<false> end() { return CrossConstComparableSentinel<false>{e_}; }58 59  constexpr MaybeConstIterator<true> begin() const { return MaybeConstIterator<true>{b_}; }60  constexpr CrossConstComparableSentinel<true> end() const { return CrossConstComparableSentinel<true>{e_}; }61 62private:63  int* b_;64  int* e_;65};66 67static_assert(std::ranges::range<CrossConstComparableView>);68static_assert(std::ranges::range<const CrossConstComparableView>);69 70struct NonCrossConstComparableView : std::ranges::view_base {71  int* begin();72  sentinel_wrapper<int*> end();73 74  long* begin() const;75  sentinel_wrapper<long*> end() const;76};77 78static_assert(std::ranges::range<NonCrossConstComparableView>);79static_assert(std::ranges::range<const NonCrossConstComparableView>);80 81constexpr bool test() {82  int buffer[8]                      = {1, 2, 3, 4, 5, 6, 7, 8};83  using CrossConstComparableTakeView = std::ranges::take_view<CrossConstComparableView>;84 85  {   // Compare CI<Const> with sentinel<Const>86    { // Const == true87      AssertEqualityReturnBool<std::ranges::iterator_t<const CrossConstComparableTakeView>,88                               std::ranges::sentinel_t<const CrossConstComparableTakeView>>();89      const CrossConstComparableTakeView tv(CrossConstComparableView{buffer}, 4);90      assert(testEquality(std::ranges::next(tv.begin(), 4), tv.end(), true));91      assert(testEquality(tv.begin(), tv.end(), false));92    }93 94    { // Const == false95      AssertEqualityReturnBool<std::ranges::iterator_t<CrossConstComparableTakeView>,96                               std::ranges::sentinel_t<CrossConstComparableTakeView>>();97      CrossConstComparableTakeView tv(CrossConstComparableView{buffer}, 4);98      assert(testEquality(std::ranges::next(tv.begin(), 4), tv.end(), true));99      assert(testEquality(std::ranges::next(tv.begin(), 1), tv.end(), false));100    }101  }102 103  {   // Compare CI<Const> with sentinel<!Const>104    { // Const == true105      AssertEqualityReturnBool<std::ranges::iterator_t<const CrossConstComparableTakeView>,106                               std::ranges::sentinel_t<CrossConstComparableTakeView>>();107      CrossConstComparableTakeView tv(CrossConstComparableView{buffer}, 4);108      assert(testEquality(std::ranges::next(std::as_const(tv).begin(), 4), tv.end(), true));109      assert(testEquality(std::ranges::next(std::as_const(tv).begin(), 2), tv.end(), false));110    }111 112    { // Const == false113      AssertEqualityReturnBool<std::ranges::iterator_t<CrossConstComparableTakeView>,114                               std::ranges::sentinel_t<const CrossConstComparableTakeView>>();115      CrossConstComparableTakeView tv(CrossConstComparableView{buffer}, 4);116      assert(testEquality(std::ranges::next(tv.begin(), 4), std::as_const(tv).end(), true));117      assert(testEquality(std::ranges::next(tv.begin(), 3), std::as_const(tv).end(), false));118    }119  }120 121  { // Check invalid comparisons between CI<Const> and sentinel<!Const>122    using TakeView = std::ranges::take_view<NonCrossConstComparableView>;123    static_assert(124        !weakly_equality_comparable_with<std::ranges::iterator_t<const TakeView>, std::ranges::sentinel_t<TakeView>>);125    static_assert(126        !weakly_equality_comparable_with<std::ranges::iterator_t<TakeView>, std::ranges::sentinel_t<const TakeView>>);127 128    // Those should be valid129    static_assert(130        weakly_equality_comparable_with<std::ranges::iterator_t<TakeView>, std::ranges::sentinel_t<TakeView>>);131    static_assert(weakly_equality_comparable_with<std::ranges::iterator_t<const TakeView>,132                                                  std::ranges::sentinel_t<const TakeView>>);133  }134 135  return true;136}137 138int main(int, char**) {139  test();140  static_assert(test());141 142  return 0;143}144