xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/increment.pass.cpp (revision f73050e722dd2e484358d03674eb186f3a2f4799)
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 // constexpr iterator& operator++();
1294461822SHui Xie // constexpr void operator++(int);
1394461822SHui Xie // constexpr iterator operator++(int) requires forward_range<Base>;
1494461822SHui Xie 
1594461822SHui Xie #include <array>
1694461822SHui Xie #include <cassert>
17*f73050e7SLouis Dionne #include <iterator>
1894461822SHui Xie #include <ranges>
1994461822SHui Xie #include <tuple>
2094461822SHui Xie 
2194461822SHui Xie #include "test_iterators.h"
2294461822SHui Xie 
2394461822SHui Xie template <class Iter, class Sent = sentinel_wrapper<Iter>>
2494461822SHui Xie constexpr void testOne() {
2594461822SHui Xie   using Range          = std::ranges::subrange<Iter, Sent>;
2694461822SHui Xie   std::tuple<int> ts[] = {{1}, {2}, {3}};
2794461822SHui Xie 
2894461822SHui Xie   // ++i
2994461822SHui Xie   {
30*f73050e7SLouis Dionne     auto ev               = Range{Iter{std::begin(ts)}, Sent{Iter{std::end(ts)}}} | std::views::elements<0>;
3194461822SHui Xie     auto it               = ev.begin();
3294461822SHui Xie     decltype(auto) result = ++it;
3394461822SHui Xie 
34*f73050e7SLouis Dionne     using ElementIter = std::ranges::iterator_t<decltype(ev)>;
3594461822SHui Xie     static_assert(std::is_same_v<decltype(result), ElementIter&>);
3694461822SHui Xie     assert(&result == &it);
3794461822SHui Xie 
3894461822SHui Xie     assert(base(it.base()) == &ts[1]);
3994461822SHui Xie   }
4094461822SHui Xie 
4194461822SHui Xie   // i++
4294461822SHui Xie   {
43*f73050e7SLouis Dionne     auto ev = Range{Iter{std::begin(ts)}, Sent{Iter{std::end(ts)}}} | std::views::elements<0>;
4494461822SHui Xie     if constexpr (std::forward_iterator<Iter>) {
4594461822SHui Xie       auto it               = ev.begin();
4694461822SHui Xie       decltype(auto) result = it++;
4794461822SHui Xie 
48*f73050e7SLouis Dionne       using ElementIter = std::ranges::iterator_t<decltype(ev)>;
4994461822SHui Xie       static_assert(std::is_same_v<decltype(result), ElementIter>);
5094461822SHui Xie 
5194461822SHui Xie       assert(base(it.base()) == &ts[1]);
5294461822SHui Xie       assert(base(result.base()) == &ts[0]);
5394461822SHui Xie     } else {
5494461822SHui Xie       auto it = ev.begin();
5594461822SHui Xie       it++;
5694461822SHui Xie 
5794461822SHui Xie       static_assert(std::is_same_v<decltype(it++), void>);
5894461822SHui Xie       assert(base(it.base()) == &ts[1]);
5994461822SHui Xie     }
6094461822SHui Xie   }
6194461822SHui Xie }
6294461822SHui Xie 
6394461822SHui Xie constexpr bool test() {
6494461822SHui Xie   using Ptr = std::tuple<int>*;
6594461822SHui Xie   testOne<cpp20_input_iterator<Ptr>>();
6694461822SHui Xie   testOne<forward_iterator<Ptr>>();
6794461822SHui Xie   testOne<bidirectional_iterator<Ptr>>();
6894461822SHui Xie   testOne<random_access_iterator<Ptr>>();
6994461822SHui Xie   testOne<contiguous_iterator<Ptr>>();
7094461822SHui Xie   testOne<Ptr>();
7194461822SHui Xie 
7294461822SHui Xie   return true;
7394461822SHui Xie }
7494461822SHui Xie 
7594461822SHui Xie int main(int, char**) {
7694461822SHui Xie   test();
7794461822SHui Xie   static_assert(test());
7894461822SHui Xie 
7994461822SHui Xie   return 0;
8094461822SHui Xie }
81