]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/std/ranges/adaptors/reverse.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / std / ranges / adaptors / reverse.cc
1 // Copyright (C) 2020-2022 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 <ranges>
23 #include <testsuite_hooks.h>
24 #include <testsuite_iterators.h>
25
26 using __gnu_test::test_range;
27 using __gnu_test::bidirectional_iterator_wrapper;
28
29 namespace ranges = std::ranges;
30 namespace views = ranges::views;
31
32 void
33 test01()
34 {
35 int x[] = {1,2,3,4,5};
36 auto v = x | views::reverse;
37 VERIFY( ranges::equal(v, (int[]){5,4,3,2,1}) );
38 VERIFY( ranges::equal(v | views::reverse, x) );
39 static_assert(ranges::view<decltype(v)>);
40 static_assert(ranges::sized_range<decltype(v)>);
41 static_assert(ranges::common_range<decltype(v)>);
42 static_assert(ranges::random_access_range<decltype(v)>);
43 }
44
45 void
46 test02()
47 {
48 int x[] = {1,2,3,4,5};
49 test_range<int, bidirectional_iterator_wrapper> rx(x);
50 auto v = views::reverse(rx);
51 VERIFY( ranges::equal(v, (int[]){5,4,3,2,1}) );
52 VERIFY( ranges::equal(v | views::reverse, rx) );
53 static_assert(ranges::view<decltype(v)>);
54 static_assert(!ranges::sized_range<decltype(v)>);
55 static_assert(ranges::common_range<decltype(v)>);
56 static_assert(!ranges::random_access_range<decltype(v)>);
57 static_assert(ranges::bidirectional_range<decltype(v)>);
58 }
59
60 void
61 test03()
62 {
63 int x[] = {1,7,3,6,5,2,4,8};
64 auto is_even = [] (int i) { return i%2==0; };
65 int sum = 0;
66 for (auto i : x | views::reverse | views::filter(is_even))
67 sum += i;
68 VERIFY( sum == 20 );
69 }
70
71 void
72 test04()
73 {
74 int x[] = {1,2,3,4,5};
75 VERIFY( ranges::equal(x | views::reverse | (views::reverse | views::reverse),
76 (int[]){5,4,3,2,1}) );
77 }
78
79 // The following tests that reverse_view::begin caches its result.
80
81 template<typename T>
82 struct test_wrapper : bidirectional_iterator_wrapper<T>
83 {
84 static inline int increment_count = 0;
85
86 using bidirectional_iterator_wrapper<T>::bidirectional_iterator_wrapper;
87
88 test_wrapper() : bidirectional_iterator_wrapper<T>()
89 { }
90
91 test_wrapper
92 operator++(int)
93 {
94 auto tmp = *this;
95 ++*this;
96 return tmp;
97 }
98
99 test_wrapper&
100 operator++()
101 {
102 ++increment_count;
103 bidirectional_iterator_wrapper<T>::operator++();
104 return *this;
105 }
106
107 test_wrapper
108 operator--(int)
109 {
110 auto tmp = *this;
111 --*this;
112 return tmp;
113 }
114
115 test_wrapper&
116 operator--()
117 {
118 bidirectional_iterator_wrapper<T>::operator--();
119 return *this;
120 }
121 };
122
123 void
124 test05()
125 {
126 int x[] = {1,2,3,4,5};
127 test_range<int, test_wrapper> rx(x);
128 auto v = rx | views::reverse;
129 VERIFY( ranges::equal(v, (int[]){5,4,3,2,1}) );
130 VERIFY( ranges::equal(v, (int[]){5,4,3,2,1}) );
131 VERIFY( test_wrapper<int>::increment_count == 5 );
132 }
133
134 namespace test_ns
135 {
136 struct A {};
137 template <typename T>
138 void make_reverse_iterator(T&&) {}
139 } // namespace test_ns
140
141 void
142 test06()
143 {
144 // Check that views::reverse works and does not use ADL which could lead
145 // to accidentally finding test_ns::make_reverse_iterator(A*).
146 test_ns::A as[] = {{}, {}};
147 auto v = as | std::views::reverse;
148 using V = decltype(v);
149 static_assert( std::ranges::view<V> );
150 static_assert( std::ranges::range<const V> );
151 }
152
153 template<auto reverse = views::reverse>
154 void
155 test07()
156 {
157 // Verify SFINAE behavior.
158 static_assert(!requires { reverse(); });
159 static_assert(!requires { reverse(0, 0); });
160 static_assert(!requires { reverse(0); });
161 static_assert(!requires { 0 | reverse; });
162 }
163
164 void
165 test08()
166 {
167 // PR libstdc++/100639
168 auto v = views::iota(1701ll, 3000ll) | views::reverse | views::take(5);
169 for (auto x : v)
170 ;
171 }
172
173 int
174 main()
175 {
176 test01();
177 test02();
178 test03();
179 test04();
180 test05();
181 test06();
182 test07();
183 test08();
184 }