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 | // std::views::elements<N> |
12 | // std::views::keys |
13 | // std::views::values |
14 | |
15 | #include <algorithm> |
16 | #include <cassert> |
17 | #include <ranges> |
18 | #include <tuple> |
19 | #include <type_traits> |
20 | #include <utility> |
21 | |
22 | #include "test_range.h" |
23 | |
24 | template <class T> |
25 | struct View : std::ranges::view_base { |
26 | T* begin() const; |
27 | T* end() const; |
28 | }; |
29 | |
30 | static_assert(!std::is_invocable_v<decltype((std::views::elements<0>))>); |
31 | static_assert(!std::is_invocable_v<decltype((std::views::elements<0>)), View<int>>); |
32 | static_assert(std::is_invocable_v<decltype((std::views::elements<0>)), View<std::pair<int, int>>>); |
33 | static_assert(std::is_invocable_v<decltype((std::views::elements<0>)), View<std::tuple<int>>>); |
34 | static_assert(!std::is_invocable_v<decltype((std::views::elements<5>)), View<std::tuple<int>>>); |
35 | |
36 | static_assert(!std::is_invocable_v<decltype((std::views::keys))>); |
37 | static_assert(!std::is_invocable_v<decltype((std::views::keys)), View<int>>); |
38 | static_assert(std::is_invocable_v<decltype((std::views::keys)), View<std::pair<int, int>>>); |
39 | static_assert(std::is_invocable_v<decltype((std::views::keys)), View<std::tuple<int>>>); |
40 | |
41 | static_assert(!std::is_invocable_v<decltype((std::views::values))>); |
42 | static_assert(!std::is_invocable_v<decltype((std::views::values)), View<int>>); |
43 | static_assert(std::is_invocable_v<decltype((std::views::values)), View<std::pair<int, int>>>); |
44 | static_assert(!std::is_invocable_v<decltype((std::views::values)), View<std::tuple<int>>>); |
45 | |
46 | static_assert(!CanBePiped<View<int>, decltype((std::views::elements<0>))>); |
47 | static_assert(CanBePiped<View<std::pair<int, int>>, decltype((std::views::elements<0>))>); |
48 | static_assert(CanBePiped<View<std::tuple<int>>, decltype((std::views::elements<0>))>); |
49 | static_assert(!CanBePiped<View<std::tuple<int>>, decltype((std::views::elements<5>))>); |
50 | |
51 | static_assert(!CanBePiped<View<int>, decltype((std::views::keys))>); |
52 | static_assert(CanBePiped<View<std::pair<int, int>>, decltype((std::views::keys))>); |
53 | static_assert(CanBePiped<View<std::tuple<int>>, decltype((std::views::keys))>); |
54 | |
55 | static_assert(!CanBePiped<View<int>, decltype((std::views::values))>); |
56 | static_assert(CanBePiped<View<std::pair<int, int>>, decltype((std::views::values))>); |
57 | static_assert(!CanBePiped<View<std::tuple<int>>, decltype((std::views::values))>); |
58 | |
59 | constexpr bool test() { |
60 | std::pair<int, int> buff[] = {{1, 2}, {3, 4}, {5, 6}}; |
61 | |
62 | // Test `views::elements<N>(v)` |
63 | { |
64 | using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 0>; |
65 | std::same_as<Result> decltype(auto) result = std::views::elements<0>(buff); |
66 | auto expected = {1, 3, 5}; |
67 | assert(std::ranges::equal(result, expected)); |
68 | } |
69 | |
70 | // Test `views::keys(v)` |
71 | { |
72 | using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 0>; |
73 | std::same_as<Result> decltype(auto) result = std::views::keys(buff); |
74 | auto expected = {1, 3, 5}; |
75 | assert(std::ranges::equal(result, expected)); |
76 | } |
77 | |
78 | // Test `views::values(v)` |
79 | { |
80 | using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 1>; |
81 | std::same_as<Result> decltype(auto) result = std::views::values(buff); |
82 | auto expected = {2, 4, 6}; |
83 | assert(std::ranges::equal(result, expected)); |
84 | } |
85 | |
86 | // Test `v | views::elements<N>` |
87 | { |
88 | using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 1>; |
89 | std::same_as<Result> decltype(auto) result = buff | std::views::elements<1>; |
90 | auto expected = {2, 4, 6}; |
91 | assert(std::ranges::equal(result, expected)); |
92 | } |
93 | |
94 | // Test `v | views::keys` |
95 | { |
96 | using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 0>; |
97 | std::same_as<Result> decltype(auto) result = buff | std::views::keys; |
98 | auto expected = {1, 3, 5}; |
99 | assert(std::ranges::equal(result, expected)); |
100 | } |
101 | |
102 | // Test `v | views::values` |
103 | { |
104 | using Result = std::ranges::elements_view<std::ranges::ref_view<std::pair<int, int>[3]>, 1>; |
105 | std::same_as<Result> decltype(auto) result = buff | std::views::values; |
106 | auto expected = {2, 4, 6}; |
107 | assert(std::ranges::equal(result, expected)); |
108 | } |
109 | |
110 | // Test views::elements<0> | views::elements<0> |
111 | { |
112 | std::pair<std::tuple<int>, std::tuple<int>> nested[] = {{{1}, {2}}, {{3}, {4}}, {{5}, {6}}}; |
113 | using Result = std::ranges::elements_view< |
114 | std::ranges::elements_view<std::ranges::ref_view<std::pair<std::tuple<int>, std::tuple<int>>[3]>, 0>, |
115 | 0>; |
116 | auto const partial = std::views::elements<0> | std::views::elements<0>; |
117 | std::same_as<Result> decltype(auto) result = nested | partial; |
118 | auto expected = {1, 3, 5}; |
119 | assert(std::ranges::equal(result, expected)); |
120 | } |
121 | |
122 | // Test views::keys | views::keys |
123 | { |
124 | std::pair<std::tuple<int>, std::tuple<int>> nested[] = {{{1}, {2}}, {{3}, {4}}, {{5}, {6}}}; |
125 | using Result = std::ranges::elements_view< |
126 | std::ranges::elements_view<std::ranges::ref_view<std::pair<std::tuple<int>, std::tuple<int>>[3]>, 0>, |
127 | 0>; |
128 | auto const partial = std::views::keys | std::views::keys; |
129 | std::same_as<Result> decltype(auto) result = nested | partial; |
130 | auto expected = {1, 3, 5}; |
131 | assert(std::ranges::equal(result, expected)); |
132 | } |
133 | |
134 | // Test views::values | views::values |
135 | { |
136 | std::pair<std::tuple<int>, std::tuple<int, int>> nested[] = {{{1}, {2, 3}}, {{4}, {5, 6}}, {{7}, {8, 9}}}; |
137 | using Result = std::ranges::elements_view< |
138 | std::ranges::elements_view<std::ranges::ref_view<std::pair<std::tuple<int>, std::tuple<int, int>>[3]>, 1>, |
139 | 1>; |
140 | auto const partial = std::views::values | std::views::values; |
141 | std::same_as<Result> decltype(auto) result = nested | partial; |
142 | auto expected = {3, 6, 9}; |
143 | assert(std::ranges::equal(result, expected)); |
144 | } |
145 | |
146 | // Test views::keys | views::values |
147 | { |
148 | std::pair<std::tuple<int, int>, std::tuple<int>> nested[] = {{{1, 2}, {3}}, {{4, 5}, {6}}, {{7, 8}, {9}}}; |
149 | using Result = std::ranges::elements_view< |
150 | std::ranges::elements_view<std::ranges::ref_view<std::pair<std::tuple<int, int>, std::tuple<int>>[3]>, 0>, |
151 | 1>; |
152 | auto const partial = std::views::keys | std::views::values; |
153 | std::same_as<Result> decltype(auto) result = nested | partial; |
154 | auto expected = {2, 5, 8}; |
155 | assert(std::ranges::equal(result, expected)); |
156 | } |
157 | |
158 | // Test views::values | views::keys |
159 | { |
160 | std::pair<std::tuple<int>, std::tuple<int, int>> nested[] = {{{1}, {2, 3}}, {{4}, {5, 6}}, {{7}, {8, 9}}}; |
161 | using Result = std::ranges::elements_view< |
162 | std::ranges::elements_view<std::ranges::ref_view<std::pair<std::tuple<int>, std::tuple<int, int>>[3]>, 1>, |
163 | 0>; |
164 | auto const partial = std::views::values | std::views::keys; |
165 | std::same_as<Result> decltype(auto) result = nested | partial; |
166 | auto expected = {2, 5, 8}; |
167 | assert(std::ranges::equal(result, expected)); |
168 | } |
169 | |
170 | return true; |
171 | } |
172 | |
173 | int main(int, char**) { |
174 | test(); |
175 | static_assert(test()); |
176 | |
177 | return 0; |
178 | } |
179 | |