xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/arithmetic.pass.cpp (revision 94461822c75d5080bf648f86552f7a59b76905c9)
1*94461822SHui Xie //===----------------------------------------------------------------------===//
2*94461822SHui Xie //
3*94461822SHui Xie // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*94461822SHui Xie // See https://llvm.org/LICENSE.txt for license information.
5*94461822SHui Xie // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*94461822SHui Xie //
7*94461822SHui Xie //===----------------------------------------------------------------------===//
8*94461822SHui Xie 
9*94461822SHui Xie // UNSUPPORTED: c++03, c++11, c++14, c++17
10*94461822SHui Xie 
11*94461822SHui Xie // constexpr iterator& operator+=(difference_type n)
12*94461822SHui Xie //    requires random_access_range<Base>;
13*94461822SHui Xie //
14*94461822SHui Xie // constexpr iterator& operator-=(difference_type n)
15*94461822SHui Xie //   requires random_access_range<Base>;
16*94461822SHui Xie //
17*94461822SHui Xie // friend constexpr iterator operator+(const iterator& x, difference_type y)
18*94461822SHui Xie //     requires random_access_range<Base>;
19*94461822SHui Xie //
20*94461822SHui Xie // friend constexpr iterator operator+(difference_type x, const iterator& y)
21*94461822SHui Xie //   requires random_access_range<Base>;
22*94461822SHui Xie //
23*94461822SHui Xie // friend constexpr iterator operator-(const iterator& x, difference_type y)
24*94461822SHui Xie //   requires random_access_range<Base>;
25*94461822SHui Xie //
26*94461822SHui Xie // friend constexpr difference_type operator-(const iterator& x, const iterator& y)
27*94461822SHui Xie //   requires sized_sentinel_for<iterator_t<Base>, iterator_t<Base>>;
28*94461822SHui Xie 
29*94461822SHui Xie #include <ranges>
30*94461822SHui Xie 
31*94461822SHui Xie #include <tuple>
32*94461822SHui Xie 
33*94461822SHui Xie #include "test_iterators.h"
34*94461822SHui Xie 
35*94461822SHui Xie template <class T, class U>
36*94461822SHui Xie concept CanPlus = requires(T t, U u) { t + u; };
37*94461822SHui Xie 
38*94461822SHui Xie template <class T, class U>
39*94461822SHui Xie concept CanPlusEqual = requires(T t, U u) { t += u; };
40*94461822SHui Xie 
41*94461822SHui Xie template <class T, class U>
42*94461822SHui Xie concept CanMinus = requires(T t, U u) { t - u; };
43*94461822SHui Xie 
44*94461822SHui Xie template <class T, class U>
45*94461822SHui Xie concept CanMinusEqual = requires(T t, U u) { t -= u; };
46*94461822SHui Xie 
47*94461822SHui Xie template <class BaseRange>
48*94461822SHui Xie using ElemIter = std::ranges::iterator_t<std::ranges::elements_view<BaseRange, 0>>;
49*94461822SHui Xie 
50*94461822SHui Xie using RandomAccessRange = std::ranges::subrange<std::tuple<int>*>;
51*94461822SHui Xie static_assert(std::ranges::random_access_range<RandomAccessRange>);
52*94461822SHui Xie static_assert(std::sized_sentinel_for<std::ranges::iterator_t<RandomAccessRange>, //
53*94461822SHui Xie                                       std::ranges::iterator_t<RandomAccessRange>>);
54*94461822SHui Xie 
55*94461822SHui Xie static_assert(CanPlus<ElemIter<RandomAccessRange>, int>);
56*94461822SHui Xie static_assert(CanPlus<int, ElemIter<RandomAccessRange>>);
57*94461822SHui Xie static_assert(CanPlusEqual<ElemIter<RandomAccessRange>, int>);
58*94461822SHui Xie static_assert(CanMinus<ElemIter<RandomAccessRange>, int>);
59*94461822SHui Xie static_assert(CanMinus<ElemIter<RandomAccessRange>, ElemIter<RandomAccessRange>>);
60*94461822SHui Xie static_assert(CanMinusEqual<ElemIter<RandomAccessRange>, int>);
61*94461822SHui Xie 
62*94461822SHui Xie using BidiRange = std::ranges::subrange<bidirectional_iterator<std::tuple<int>*>>;
63*94461822SHui Xie static_assert(!std::ranges::random_access_range<BidiRange>);
64*94461822SHui Xie static_assert(!std::sized_sentinel_for<std::ranges::iterator_t<BidiRange>, //
65*94461822SHui Xie                                        std::ranges::iterator_t<BidiRange>>);
66*94461822SHui Xie 
67*94461822SHui Xie static_assert(!CanPlus<ElemIter<BidiRange>, int>);
68*94461822SHui Xie static_assert(!CanPlus<int, ElemIter<BidiRange>>);
69*94461822SHui Xie static_assert(!CanPlusEqual<ElemIter<BidiRange>, int>);
70*94461822SHui Xie static_assert(!CanMinus<ElemIter<BidiRange>, int>);
71*94461822SHui Xie static_assert(!CanMinus<ElemIter<BidiRange>, ElemIter<BidiRange>>);
72*94461822SHui Xie static_assert(!CanMinusEqual<ElemIter<BidiRange>, int>);
73*94461822SHui Xie 
test()74*94461822SHui Xie constexpr bool test() {
75*94461822SHui Xie   std::tuple<int> ts[] = {{1}, {2}, {3}, {4}};
76*94461822SHui Xie 
77*94461822SHui Xie   RandomAccessRange r{&ts[0], &ts[0] + 4};
78*94461822SHui Xie   auto ev = r | std::views::elements<0>;
79*94461822SHui Xie   {
80*94461822SHui Xie     // operator+(x, n) operator+(n,x) and operator+=
81*94461822SHui Xie     auto it1 = ev.begin();
82*94461822SHui Xie 
83*94461822SHui Xie     auto it2 = it1 + 3;
84*94461822SHui Xie     assert(it2.base() == &ts[3]);
85*94461822SHui Xie 
86*94461822SHui Xie     auto it3 = 3 + it1;
87*94461822SHui Xie     assert(it3.base() == &ts[3]);
88*94461822SHui Xie 
89*94461822SHui Xie     it1 += 3;
90*94461822SHui Xie     assert(it1 == it2);
91*94461822SHui Xie     assert(it1.base() == &ts[3]);
92*94461822SHui Xie   }
93*94461822SHui Xie 
94*94461822SHui Xie   {
95*94461822SHui Xie     // operator-(x, n) and operator-=
96*94461822SHui Xie     auto it1 = ev.end();
97*94461822SHui Xie 
98*94461822SHui Xie     auto it2 = it1 - 3;
99*94461822SHui Xie     assert(it2.base() == &ts[1]);
100*94461822SHui Xie 
101*94461822SHui Xie     it1 -= 3;
102*94461822SHui Xie     assert(it1 == it2);
103*94461822SHui Xie     assert(it1.base() == &ts[1]);
104*94461822SHui Xie   }
105*94461822SHui Xie 
106*94461822SHui Xie   {
107*94461822SHui Xie     // operator-(x, y)
108*94461822SHui Xie     assert((ev.end() - ev.begin()) == 4);
109*94461822SHui Xie 
110*94461822SHui Xie     auto it1 = ev.begin() + 2;
111*94461822SHui Xie     auto it2 = ev.end() - 1;
112*94461822SHui Xie     assert((it1 - it2) == -1);
113*94461822SHui Xie   }
114*94461822SHui Xie 
115*94461822SHui Xie   return true;
116*94461822SHui Xie }
117*94461822SHui Xie 
main(int,char **)118*94461822SHui Xie int main(int, char**) {
119*94461822SHui Xie   test();
120*94461822SHui Xie   static_assert(test());
121*94461822SHui Xie 
122*94461822SHui Xie   return 0;
123*94461822SHui Xie }
124