xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/compare.pass.cpp (revision 808d794a45e169601ff16f72beae2f7bd79342a2)
194461822SHui Xie //===----------------------------------------------------------------------===//
294461822SHui Xie //
394461822SHui Xie // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
494461822SHui Xie // See https://llvm.org/LICENSE.txt for license information.
594461822SHui Xie // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
694461822SHui Xie //
794461822SHui Xie //===----------------------------------------------------------------------===//
894461822SHui Xie 
994461822SHui Xie // UNSUPPORTED: c++03, c++11, c++14, c++17
1094461822SHui Xie 
1194461822SHui Xie // friend constexpr bool operator==(const iterator& x, const iterator& y)
1294461822SHui Xie //   requires equality_comparable<iterator_t<Base>>;
1394461822SHui Xie // friend constexpr bool operator<(const iterator& x, const iterator& y)
1494461822SHui Xie //   requires random_access_range<Base>;
1594461822SHui Xie // friend constexpr bool operator>(const iterator& x, const iterator& y)
1694461822SHui Xie //   requires random_access_range<Base>;
1794461822SHui Xie // friend constexpr bool operator<=(const iterator& x, const iterator& y)
1894461822SHui Xie //   requires random_access_range<Base>;
1994461822SHui Xie // friend constexpr bool operator>=(const iterator& x, const iterator& y)
2094461822SHui Xie //   requires random_access_range<Base>;
2194461822SHui Xie // friend constexpr auto operator<=>(const iterator& x, const iterator& y)
2294461822SHui Xie //   requires random_access_range<Base> && three_way_comparable<iterator_t<Base>>;
2394461822SHui Xie 
2494461822SHui Xie #include <compare>
2594461822SHui Xie #include <functional>
2694461822SHui Xie #include <ranges>
2794461822SHui Xie #include <tuple>
2894461822SHui Xie 
2994461822SHui Xie #include "test_iterators.h"
30*808d794aSWill Hawkins #include "test_range.h"
3194461822SHui Xie 
compareOperatorTest(const auto & iter1,const auto & iter2)3294461822SHui Xie constexpr void compareOperatorTest(const auto& iter1, const auto& iter2) {
3394461822SHui Xie   assert(!(iter1 < iter1));
3494461822SHui Xie   assert(iter1 < iter2);
3594461822SHui Xie   assert(!(iter2 < iter1));
3694461822SHui Xie 
3794461822SHui Xie   assert(iter1 <= iter1);
3894461822SHui Xie   assert(iter1 <= iter2);
3994461822SHui Xie   assert(!(iter2 <= iter1));
4094461822SHui Xie 
4194461822SHui Xie   assert(!(iter1 > iter1));
4294461822SHui Xie   assert(!(iter1 > iter2));
4394461822SHui Xie   assert(iter2 > iter1);
4494461822SHui Xie 
4594461822SHui Xie   assert(iter1 >= iter1);
4694461822SHui Xie   assert(!(iter1 >= iter2));
4794461822SHui Xie   assert(iter2 >= iter1);
4894461822SHui Xie 
4994461822SHui Xie   assert(iter1 == iter1);
5094461822SHui Xie   assert(!(iter1 == iter2));
5194461822SHui Xie   assert(iter2 == iter2);
5294461822SHui Xie 
5394461822SHui Xie   assert(!(iter1 != iter1));
5494461822SHui Xie   assert(iter1 != iter2);
5594461822SHui Xie   assert(!(iter2 != iter2));
5694461822SHui Xie }
5794461822SHui Xie 
inequalityOperatorsDoNotExistTest(const auto & iter1,const auto & iter2)5894461822SHui Xie constexpr void inequalityOperatorsDoNotExistTest(const auto& iter1, const auto& iter2) {
5994461822SHui Xie   using Iter1 = decltype(iter1);
6094461822SHui Xie   using Iter2 = decltype(iter2);
6194461822SHui Xie   static_assert(!std::is_invocable_v<std::less<>, Iter1, Iter2>);
6294461822SHui Xie   static_assert(!std::is_invocable_v<std::less_equal<>, Iter1, Iter2>);
6394461822SHui Xie   static_assert(!std::is_invocable_v<std::greater<>, Iter1, Iter2>);
6494461822SHui Xie   static_assert(!std::is_invocable_v<std::greater_equal<>, Iter1, Iter2>);
6594461822SHui Xie }
6694461822SHui Xie 
test()6794461822SHui Xie constexpr bool test() {
6894461822SHui Xie   std::tuple<int> ts[] = {{1}, {2}, {3}};
6994461822SHui Xie 
7094461822SHui Xie   {
7194461822SHui Xie     // Test a new-school iterator with operator<=>; the iterator should also have operator<=>.
7294461822SHui Xie     using It       = three_way_contiguous_iterator<std::tuple<int>*>;
7394461822SHui Xie     using Subrange = std::ranges::subrange<It>;
7494461822SHui Xie     static_assert(std::three_way_comparable<It>);
7594461822SHui Xie     using R = std::ranges::elements_view<Subrange, 0>;
7694461822SHui Xie     static_assert(std::three_way_comparable<std::ranges::iterator_t<R>>);
7794461822SHui Xie 
7894461822SHui Xie     auto ev    = Subrange{It{&ts[0]}, It{&ts[0] + 3}} | std::views::elements<0>;
7994461822SHui Xie     auto iter1 = ev.begin();
8094461822SHui Xie     auto iter2 = iter1 + 1;
8194461822SHui Xie 
8294461822SHui Xie     compareOperatorTest(iter1, iter2);
8394461822SHui Xie 
8494461822SHui Xie     assert((iter1 <=> iter2) == std::strong_ordering::less);
8594461822SHui Xie     assert((iter1 <=> iter1) == std::strong_ordering::equal);
8694461822SHui Xie     assert((iter2 <=> iter1) == std::strong_ordering::greater);
8794461822SHui Xie   }
8894461822SHui Xie 
8994461822SHui Xie   {
9094461822SHui Xie     // Test an old-school iterator with no operator<=>; the elements view iterator shouldn't have
9194461822SHui Xie     // operator<=> either.
9294461822SHui Xie     using It       = random_access_iterator<std::tuple<int>*>;
9394461822SHui Xie     using Subrange = std::ranges::subrange<It>;
9494461822SHui Xie     static_assert(!std::three_way_comparable<It>);
9594461822SHui Xie     using R = std::ranges::elements_view<Subrange, 0>;
9694461822SHui Xie     static_assert(!std::three_way_comparable<std::ranges::iterator_t<R>>);
9794461822SHui Xie 
9894461822SHui Xie     auto ev    = Subrange{It{&ts[0]}, It{&ts[0] + 3}} | std::views::elements<0>;
9994461822SHui Xie     auto iter1 = ev.begin();
10094461822SHui Xie     auto iter2 = iter1 + 1;
10194461822SHui Xie 
10294461822SHui Xie     compareOperatorTest(iter1, iter2);
10394461822SHui Xie   }
10494461822SHui Xie 
10594461822SHui Xie   {
10694461822SHui Xie     // non random_access_range
10794461822SHui Xie     using It       = bidirectional_iterator<std::tuple<int>*>;
10894461822SHui Xie     using Subrange = std::ranges::subrange<It>;
10994461822SHui Xie     static_assert(!std::ranges::random_access_range<Subrange>);
11094461822SHui Xie     using R = std::ranges::elements_view<Subrange, 0>;
11194461822SHui Xie     static_assert(!std::three_way_comparable<std::ranges::iterator_t<R>>);
11294461822SHui Xie 
11394461822SHui Xie     auto ev = Subrange{It{&ts[0]}, It{&ts[0] + 1}} | std::views::elements<0>;
11494461822SHui Xie 
11594461822SHui Xie     auto it1 = ev.begin();
11694461822SHui Xie     auto it2 = ev.end();
11794461822SHui Xie 
11894461822SHui Xie     assert(it1 == it1);
11994461822SHui Xie     assert(!(it1 != it1));
12094461822SHui Xie     assert(it2 == it2);
12194461822SHui Xie     assert(!(it2 != it2));
12294461822SHui Xie 
12394461822SHui Xie     assert(it1 != it2);
12494461822SHui Xie 
12594461822SHui Xie     ++it1;
12694461822SHui Xie     assert(it1 == it2);
12794461822SHui Xie 
12894461822SHui Xie     inequalityOperatorsDoNotExistTest(it1, it2);
12994461822SHui Xie   }
13094461822SHui Xie 
13194461822SHui Xie   {
13294461822SHui Xie     // underlying iterator does not support ==
13394461822SHui Xie     using Iter     = cpp20_input_iterator<std::tuple<int>*>;
13494461822SHui Xie     using Sent     = sentinel_wrapper<Iter>;
13594461822SHui Xie     using Subrange = std::ranges::subrange<Iter, Sent>;
13694461822SHui Xie     using R        = std::ranges::elements_view<Subrange, 0>;
13794461822SHui Xie     static_assert(!std::three_way_comparable<std::ranges::iterator_t<R>>);
13894461822SHui Xie 
13994461822SHui Xie     auto ev = Subrange{Iter{&ts[0]}, Sent{Iter{&ts[0] + 1}}} | std::views::elements<0>;
14094461822SHui Xie     auto it = ev.begin();
14194461822SHui Xie 
14294461822SHui Xie     using ElemIter = decltype(it);
143*808d794aSWill Hawkins     static_assert(!weakly_equality_comparable_with<ElemIter, ElemIter>);
14494461822SHui Xie     inequalityOperatorsDoNotExistTest(it, it);
14594461822SHui Xie   }
14694461822SHui Xie 
14794461822SHui Xie   return true;
14894461822SHui Xie }
14994461822SHui Xie 
main(int,char **)15094461822SHui Xie int main(int, char**) {
15194461822SHui Xie   test();
15294461822SHui Xie   static_assert(test());
15394461822SHui Xie 
15494461822SHui Xie   return 0;
15594461822SHui Xie }
156