brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · 4dd52a8 Raw
156 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& x, const iterator& y)12//   requires equality_comparable<iterator_t<Base>>;13// friend constexpr bool operator<(const iterator& x, const iterator& y)14//   requires random_access_range<Base>;15// friend constexpr bool operator>(const iterator& x, const iterator& y)16//   requires random_access_range<Base>;17// friend constexpr bool operator<=(const iterator& x, const iterator& y)18//   requires random_access_range<Base>;19// friend constexpr bool operator>=(const iterator& x, const iterator& y)20//   requires random_access_range<Base>;21// friend constexpr auto operator<=>(const iterator& x, const iterator& y)22//   requires random_access_range<Base> && three_way_comparable<iterator_t<Base>>;23 24#include <compare>25#include <functional>26#include <ranges>27#include <tuple>28 29#include "test_iterators.h"30#include "test_range.h"31 32constexpr void compareOperatorTest(const auto& iter1, const auto& iter2) {33  assert(!(iter1 < iter1));34  assert(iter1 < iter2);35  assert(!(iter2 < iter1));36 37  assert(iter1 <= iter1);38  assert(iter1 <= iter2);39  assert(!(iter2 <= iter1));40 41  assert(!(iter1 > iter1));42  assert(!(iter1 > iter2));43  assert(iter2 > iter1);44 45  assert(iter1 >= iter1);46  assert(!(iter1 >= iter2));47  assert(iter2 >= iter1);48 49  assert(iter1 == iter1);50  assert(!(iter1 == iter2));51  assert(iter2 == iter2);52 53  assert(!(iter1 != iter1));54  assert(iter1 != iter2);55  assert(!(iter2 != iter2));56}57 58constexpr void inequalityOperatorsDoNotExistTest(const auto& iter1, const auto& iter2) {59  using Iter1 = decltype(iter1);60  using Iter2 = decltype(iter2);61  static_assert(!std::is_invocable_v<std::less<>, Iter1, Iter2>);62  static_assert(!std::is_invocable_v<std::less_equal<>, Iter1, Iter2>);63  static_assert(!std::is_invocable_v<std::greater<>, Iter1, Iter2>);64  static_assert(!std::is_invocable_v<std::greater_equal<>, Iter1, Iter2>);65}66 67constexpr bool test() {68  std::tuple<int> ts[] = {{1}, {2}, {3}};69 70  {71    // Test a new-school iterator with operator<=>; the iterator should also have operator<=>.72    using It       = three_way_contiguous_iterator<std::tuple<int>*>;73    using Subrange = std::ranges::subrange<It>;74    static_assert(std::three_way_comparable<It>);75    using R = std::ranges::elements_view<Subrange, 0>;76    static_assert(std::three_way_comparable<std::ranges::iterator_t<R>>);77 78    auto ev    = Subrange{It{&ts[0]}, It{&ts[0] + 3}} | std::views::elements<0>;79    auto iter1 = ev.begin();80    auto iter2 = iter1 + 1;81 82    compareOperatorTest(iter1, iter2);83 84    assert((iter1 <=> iter2) == std::strong_ordering::less);85    assert((iter1 <=> iter1) == std::strong_ordering::equal);86    assert((iter2 <=> iter1) == std::strong_ordering::greater);87  }88 89  {90    // Test an old-school iterator with no operator<=>; the elements view iterator shouldn't have91    // operator<=> either.92    using It       = random_access_iterator<std::tuple<int>*>;93    using Subrange = std::ranges::subrange<It>;94    static_assert(!std::three_way_comparable<It>);95    using R = std::ranges::elements_view<Subrange, 0>;96    static_assert(!std::three_way_comparable<std::ranges::iterator_t<R>>);97 98    auto ev    = Subrange{It{&ts[0]}, It{&ts[0] + 3}} | std::views::elements<0>;99    auto iter1 = ev.begin();100    auto iter2 = iter1 + 1;101 102    compareOperatorTest(iter1, iter2);103  }104 105  {106    // non random_access_range107    using It       = bidirectional_iterator<std::tuple<int>*>;108    using Subrange = std::ranges::subrange<It>;109    static_assert(!std::ranges::random_access_range<Subrange>);110    using R = std::ranges::elements_view<Subrange, 0>;111    static_assert(!std::three_way_comparable<std::ranges::iterator_t<R>>);112 113    auto ev = Subrange{It{&ts[0]}, It{&ts[0] + 1}} | std::views::elements<0>;114 115    auto it1 = ev.begin();116    auto it2 = ev.end();117 118    assert(it1 == it1);119    assert(!(it1 != it1));120    assert(it2 == it2);121    assert(!(it2 != it2));122 123    assert(it1 != it2);124 125    ++it1;126    assert(it1 == it2);127 128    inequalityOperatorsDoNotExistTest(it1, it2);129  }130 131  {132    // underlying iterator does not support ==133    using Iter     = cpp20_input_iterator<std::tuple<int>*>;134    using Sent     = sentinel_wrapper<Iter>;135    using Subrange = std::ranges::subrange<Iter, Sent>;136    using R        = std::ranges::elements_view<Subrange, 0>;137    static_assert(!std::three_way_comparable<std::ranges::iterator_t<R>>);138 139    auto ev = Subrange{Iter{&ts[0]}, Sent{Iter{&ts[0] + 1}}} | std::views::elements<0>;140    auto it = ev.begin();141 142    using ElemIter = decltype(it);143    static_assert(!weakly_equality_comparable_with<ElemIter, ElemIter>);144    inequalityOperatorsDoNotExistTest(it, it);145  }146 147  return true;148}149 150int main(int, char**) {151  test();152  static_assert(test());153 154  return 0;155}156