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
24template <class T>
25struct View : std::ranges::view_base {
26 T* begin() const;
27 T* end() const;
28};
29
30static_assert(!std::is_invocable_v<decltype((std::views::elements<0>))>);
31static_assert(!std::is_invocable_v<decltype((std::views::elements<0>)), View<int>>);
32static_assert(std::is_invocable_v<decltype((std::views::elements<0>)), View<std::pair<int, int>>>);
33static_assert(std::is_invocable_v<decltype((std::views::elements<0>)), View<std::tuple<int>>>);
34static_assert(!std::is_invocable_v<decltype((std::views::elements<5>)), View<std::tuple<int>>>);
35
36static_assert(!std::is_invocable_v<decltype((std::views::keys))>);
37static_assert(!std::is_invocable_v<decltype((std::views::keys)), View<int>>);
38static_assert(std::is_invocable_v<decltype((std::views::keys)), View<std::pair<int, int>>>);
39static_assert(std::is_invocable_v<decltype((std::views::keys)), View<std::tuple<int>>>);
40
41static_assert(!std::is_invocable_v<decltype((std::views::values))>);
42static_assert(!std::is_invocable_v<decltype((std::views::values)), View<int>>);
43static_assert(std::is_invocable_v<decltype((std::views::values)), View<std::pair<int, int>>>);
44static_assert(!std::is_invocable_v<decltype((std::views::values)), View<std::tuple<int>>>);
45
46static_assert(!CanBePiped<View<int>, decltype((std::views::elements<0>))>);
47static_assert(CanBePiped<View<std::pair<int, int>>, decltype((std::views::elements<0>))>);
48static_assert(CanBePiped<View<std::tuple<int>>, decltype((std::views::elements<0>))>);
49static_assert(!CanBePiped<View<std::tuple<int>>, decltype((std::views::elements<5>))>);
50
51static_assert(!CanBePiped<View<int>, decltype((std::views::keys))>);
52static_assert(CanBePiped<View<std::pair<int, int>>, decltype((std::views::keys))>);
53static_assert(CanBePiped<View<std::tuple<int>>, decltype((std::views::keys))>);
54
55static_assert(!CanBePiped<View<int>, decltype((std::views::values))>);
56static_assert(CanBePiped<View<std::pair<int, int>>, decltype((std::views::values))>);
57static_assert(!CanBePiped<View<std::tuple<int>>, decltype((std::views::values))>);
58
59constexpr 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
173int main(int, char**) {
174 test();
175 static_assert(test());
176
177 return 0;
178}
179

source code of libcxx/test/std/ranges/range.adaptors/range.elements/adaptor.pass.cpp