xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/increment.pass.cpp (revision f73050e722dd2e484358d03674eb186f3a2f4799)
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10 
11 // constexpr iterator& operator++();
12 // constexpr void operator++(int);
13 // constexpr iterator operator++(int) requires forward_range<Base>;
14 
15 #include <array>
16 #include <cassert>
17 #include <iterator>
18 #include <ranges>
19 #include <tuple>
20 
21 #include "test_iterators.h"
22 
23 template <class Iter, class Sent = sentinel_wrapper<Iter>>
24 constexpr void testOne() {
25   using Range          = std::ranges::subrange<Iter, Sent>;
26   std::tuple<int> ts[] = {{1}, {2}, {3}};
27 
28   // ++i
29   {
30     auto ev               = Range{Iter{std::begin(ts)}, Sent{Iter{std::end(ts)}}} | std::views::elements<0>;
31     auto it               = ev.begin();
32     decltype(auto) result = ++it;
33 
34     using ElementIter = std::ranges::iterator_t<decltype(ev)>;
35     static_assert(std::is_same_v<decltype(result), ElementIter&>);
36     assert(&result == &it);
37 
38     assert(base(it.base()) == &ts[1]);
39   }
40 
41   // i++
42   {
43     auto ev = Range{Iter{std::begin(ts)}, Sent{Iter{std::end(ts)}}} | std::views::elements<0>;
44     if constexpr (std::forward_iterator<Iter>) {
45       auto it               = ev.begin();
46       decltype(auto) result = it++;
47 
48       using ElementIter = std::ranges::iterator_t<decltype(ev)>;
49       static_assert(std::is_same_v<decltype(result), ElementIter>);
50 
51       assert(base(it.base()) == &ts[1]);
52       assert(base(result.base()) == &ts[0]);
53     } else {
54       auto it = ev.begin();
55       it++;
56 
57       static_assert(std::is_same_v<decltype(it++), void>);
58       assert(base(it.base()) == &ts[1]);
59     }
60   }
61 }
62 
63 constexpr bool test() {
64   using Ptr = std::tuple<int>*;
65   testOne<cpp20_input_iterator<Ptr>>();
66   testOne<forward_iterator<Ptr>>();
67   testOne<bidirectional_iterator<Ptr>>();
68   testOne<random_access_iterator<Ptr>>();
69   testOne<contiguous_iterator<Ptr>>();
70   testOne<Ptr>();
71 
72   return true;
73 }
74 
75 int main(int, char**) {
76   test();
77   static_assert(test());
78 
79   return 0;
80 }
81