]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/std/ranges/adaptors/all.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / std / ranges / adaptors / all.cc
1 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
17
18 // { dg-options "-std=gnu++2a" }
19 // { dg-do run { target c++2a } }
20
21 #include <algorithm>
22 #include <array>
23 #include <ranges>
24 #include <vector>
25 #include <testsuite_hooks.h>
26 #include <testsuite_iterators.h>
27
28 namespace ranges = std::ranges;
29 namespace views = std::ranges::views;
30
31 void
32 test01()
33 {
34 int x[] = {1,2,3,4,5};
35 auto v = views::all(x);
36
37 static_assert(ranges::view<decltype(v)>);
38 static_assert(ranges::random_access_range<decltype(v)>);
39
40 VERIFY( ranges::size(v) == 5 );
41 VERIFY( ranges::size(x | views::all) == 5 );
42 VERIFY( ranges::size(v | views::all | views::all) == 5 );
43 VERIFY( ranges::size(v | (views::all | views::all)) == 5 );
44
45 ranges::reverse(v);
46 VERIFY( ranges::equal(v, (int[]){5,4,3,2,1}) );
47 }
48
49 void
50 test02()
51 {
52 int x[5] = { 0 };
53 int k = 0;
54 for (auto&& i : ranges::ref_view{x})
55 i += ++k;
56 VERIFY( ranges::equal(x, (int[]){1,2,3,4,5}) );
57 }
58
59 constexpr bool
60 test03()
61 {
62 std::array ints{0,1,2,3,4,5};
63 auto even = [] (int i) { return i%2==0; };
64 auto odd = [] (int i) { return i%2==1; };
65 auto square = [] (int i) { return i*i; };
66 int sum = 0;
67 for (auto v : (ints
68 | (views::all
69 | (views::filter(even)
70 | (views::filter(odd) | views::all)))
71 | views::transform(square)))
72 sum += v;
73 return sum == 0;
74 }
75
76 constexpr bool
77 test04()
78 {
79 auto odd = [] (int i) { return i%2==1; };
80 auto square = [] (int i) { return i*i; };
81 auto increment = [] (int i) { return i+1; };
82 auto small = [] (int i) { return i<30; };
83 auto non_negative = [] (int i) { return i>=0; };
84 auto negative = [] (int i) { return i<0; };
85 return ranges::equal(views::iota(-5)
86 | views::drop_while(negative)
87 | views::take_while(non_negative)
88 | views::transform(increment)
89 | views::filter(odd)
90 | views::take(3)
91 | views::all
92 | views::transform(square),
93 views::iota(-5)
94 | views::drop_while(negative)
95 | views::drop(1)
96 | views::filter(odd)
97 | views::transform(square)
98 | views::take_while(small)
99 | views::take_while(small));
100 }
101
102 static_assert(std::is_empty_v<decltype(views::common
103 | views::join
104 | views::all
105 | views::common
106 | views::keys
107 | views::reverse)>);
108 #if 0
109 // Adding empty range adaptor closure objects to a pipeline used to not
110 // increase the size of the pipeline, but now that our range adaptor closure
111 // objects derive from a common empty base class, [[no_unique_address]] can no
112 // longer make two empty adjacent range adaptor closure objects occupy the same
113 // data member address.
114 static_assert(sizeof(decltype(views::take(5) | views::drop(5)))
115 == sizeof(decltype(views::take(5)
116 | views::join
117 | views::common
118 | views::all
119 | views::keys
120 | views::drop(5)
121 | views::reverse)));
122 #endif
123
124 template<auto all = views::all>
125 void
126 test05()
127 {
128 // Verify SFINAE behavior.
129 static_assert(!requires { all(); });
130 static_assert(!requires { all(0, 0); });
131 static_assert(!requires { all(0); });
132 static_assert(!requires { 0 | all; });
133 }
134
135 void
136 test06()
137 {
138 int x[] { 1, 2, 3 };
139
140 // Using ref_view:
141 static_assert(noexcept(views::all(x)));
142
143 // Using owning_view:
144 static_assert(noexcept(views::all(std::array<int, 3>{})));
145 struct A { A(); A(const A&); };
146 static_assert(!std::is_nothrow_move_constructible_v<std::array<A, 3>>);
147 static_assert(!noexcept(views::all(std::array<A, 3>{})));
148 }
149
150 void
151 test07()
152 {
153 // LWG 3481
154 struct view_t : ranges::empty_view<int> { // move-only view
155 view_t(const view_t&) = delete;
156 view_t(view_t&&) = default;
157 view_t& operator=(const view_t&) = delete;
158 view_t& operator=(view_t&&) = default;
159 };
160 static_assert(std::movable<view_t> && !std::copyable<view_t>);
161 static_assert(!ranges::viewable_range<view_t&>);
162 }
163
164 constexpr bool
165 test08()
166 {
167 #ifdef _GLIBCXX_DEBUG
168 using std::_GLIBCXX_STD_C::vector;
169 #else
170 using std::vector;
171 #endif
172
173 // Verify P2415R2 "What is a view?" changes.
174 // In particular, rvalue non-view non-borrowed ranges are now viewable.
175 static_assert(ranges::viewable_range<vector<int>&&>);
176 static_assert(!ranges::viewable_range<const vector<int>&&>);
177
178 static_assert(ranges::viewable_range<std::initializer_list<int>&>);
179 static_assert(ranges::viewable_range<const std::initializer_list<int>&>);
180 static_assert(!ranges::viewable_range<std::initializer_list<int>&&>);
181 static_assert(!ranges::viewable_range<const std::initializer_list<int>&&>);
182
183 using type = views::all_t<vector<int>&&>;
184 using type = ranges::owning_view<vector<int>>;
185
186 std::same_as<type> auto v = vector<int>{{1,2,3}} | views::all;
187
188 VERIFY( ranges::equal(v, (int[]){1,2,3}) );
189 VERIFY( ranges::size(v) == 3 );
190 VERIFY( !ranges::empty(v) );
191 VERIFY( ranges::data(v) == &v[0] );
192
193 const auto w = std::move(v);
194 VERIFY( ranges::equal(w, (int[]){1,2,3}) );
195 VERIFY( ranges::size(w) == 3 );
196 VERIFY( !ranges::empty(w) );
197 VERIFY( ranges::data(w) == &w[0] );
198
199 return true;
200 }
201
202 int
203 main()
204 {
205 test01();
206 test02();
207 static_assert(test03());
208 static_assert(test04());
209 test05();
210 test06();
211 test07();
212 static_assert(test08());
213 }