xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.elements/iterator/subscript.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 decltype(auto) operator[](difference_type n) const
12*94461822SHui Xie //   requires random_access_range<Base>
13*94461822SHui Xie 
14*94461822SHui Xie #include <cassert>
15*94461822SHui Xie #include <ranges>
16*94461822SHui Xie #include <tuple>
17*94461822SHui Xie 
18*94461822SHui Xie #include "test_iterators.h"
19*94461822SHui Xie 
20*94461822SHui Xie template <class T, class U>
21*94461822SHui Xie concept CanSubscript = requires(T t, U u) { t[u]; };
22*94461822SHui Xie 
23*94461822SHui Xie template <class BaseRange>
24*94461822SHui Xie using ElemIter = std::ranges::iterator_t<std::ranges::elements_view<BaseRange, 0>>;
25*94461822SHui Xie 
26*94461822SHui Xie using RandomAccessRange = std::ranges::subrange<std::tuple<int>*>;
27*94461822SHui Xie static_assert(std::ranges::random_access_range<RandomAccessRange>);
28*94461822SHui Xie 
29*94461822SHui Xie static_assert(CanSubscript<ElemIter<RandomAccessRange>, int>);
30*94461822SHui Xie 
31*94461822SHui Xie using BidiRange = std::ranges::subrange<bidirectional_iterator<std::tuple<int>*>>;
32*94461822SHui Xie static_assert(!std::ranges::random_access_range<BidiRange>);
33*94461822SHui Xie 
34*94461822SHui Xie static_assert(!CanSubscript<ElemIter<BidiRange>, int>);
35*94461822SHui Xie 
test()36*94461822SHui Xie constexpr bool test() {
37*94461822SHui Xie   {
38*94461822SHui Xie     // reference
39*94461822SHui Xie     std::tuple<int> ts[] = {{1}, {2}, {3}, {4}};
40*94461822SHui Xie     auto ev              = ts | std::views::elements<0>;
41*94461822SHui Xie     auto it              = ev.begin();
42*94461822SHui Xie 
43*94461822SHui Xie     assert(&it[0] == &*it);
44*94461822SHui Xie     assert(&it[2] == &*(it + 2));
45*94461822SHui Xie 
46*94461822SHui Xie     static_assert(std::is_same_v<decltype(it[2]), int&>);
47*94461822SHui Xie   }
48*94461822SHui Xie 
49*94461822SHui Xie   {
50*94461822SHui Xie     // value
51*94461822SHui Xie     auto ev = std::views::iota(0, 5) | std::views::transform([](int i) { return std::tuple<int>{i}; }) |
52*94461822SHui Xie               std::views::elements<0>;
53*94461822SHui Xie     auto it = ev.begin();
54*94461822SHui Xie     assert(it[0] == *it);
55*94461822SHui Xie     assert(it[2] == *(it + 2));
56*94461822SHui Xie     assert(it[4] == *(it + 4));
57*94461822SHui Xie 
58*94461822SHui Xie     static_assert(std::is_same_v<decltype(it[2]), int>);
59*94461822SHui Xie   }
60*94461822SHui Xie 
61*94461822SHui Xie   return true;
62*94461822SHui Xie }
63*94461822SHui Xie 
main(int,char **)64*94461822SHui Xie int main(int, char**) {
65*94461822SHui Xie   test();
66*94461822SHui Xie   static_assert(test());
67*94461822SHui Xie 
68*94461822SHui Xie   return 0;
69*94461822SHui Xie }
70