1 // Copyright (C) 2020-2021 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 namespace ranges = std::ranges;
27 namespace views = std::ranges::views;
28 
29 void
test01()30 test01()
31 {
32   int x[] = {1,2,3,4,5};
33   auto v = views::all(x);
34 
35   static_assert(ranges::view<decltype(v)>);
36   static_assert(ranges::random_access_range<decltype(v)>);
37 
38   VERIFY( ranges::size(v) == 5 );
39   VERIFY( ranges::size(x | views::all) == 5 );
40   VERIFY( ranges::size(v | views::all | views::all) == 5 );
41   VERIFY( ranges::size(v | (views::all | views::all)) == 5 );
42 
43   ranges::reverse(v);
44   VERIFY( ranges::equal(v, (int[]){5,4,3,2,1}) );
45 }
46 
47 void
test02()48 test02()
49 {
50   int x[5] = { 0 };
51   int k = 0;
52   for (auto&& i : ranges::ref_view{x})
53     i += ++k;
54   VERIFY( ranges::equal(x, (int[]){1,2,3,4,5}) );
55 }
56 
57 constexpr bool
test03()58 test03()
59 {
60   std::array ints{0,1,2,3,4,5};
61   auto even = [] (int i) { return i%2==0; };
62   auto odd = [] (int i) { return i%2==1; };
63   auto square = [] (int i) { return i*i; };
64   int sum = 0;
65   for (auto v : (ints
66 		 | (views::all
67 		    | (views::filter(even)
68 		    | (views::filter(odd) | views::all)))
69 		 | views::transform(square)))
70     sum += v;
71   return sum == 0;
72 }
73 
74 constexpr bool
test04()75 test04()
76 {
77   auto odd = [] (int i) { return i%2==1; };
78   auto square = [] (int i) { return i*i; };
79   auto increment = [] (int i) { return i+1; };
80   auto small = [] (int i) { return i<30; };
81   auto non_negative = [] (int i) { return i>=0; };
82   auto negative = [] (int i) { return i<0; };
83   return ranges::equal(views::iota(-5)
84 		       | views::drop_while(negative)
85 		       | views::take_while(non_negative)
86 		       | views::transform(increment)
87 		       | views::filter(odd)
88 		       | views::take(3)
89 		       | views::all
90 		       | views::transform(square),
91 		       views::iota(-5)
92 		       | views::drop_while(negative)
93 		       | views::drop(1)
94 		       | views::filter(odd)
95 		       | views::transform(square)
96 		       | views::take_while(small)
97 		       | views::take_while(small));
98 }
99 
100 static_assert(std::is_empty_v<decltype(views::common
101 				       | views::join
102 				       | views::all
103 				       | views::common
104 				       | views::keys
105 				       | views::reverse)>);
106 #if 0
107 // Adding empty range adaptor closure objects to a pipeline used to not
108 // increase the size of the pipeline, but now that our range adaptor closure
109 // objects derive from a common empty base class, [[no_unique_address]] can no
110 // longer make two empty adjacent range adaptor closure objects occupy the same
111 // data member address.
112 static_assert(sizeof(decltype(views::take(5) | views::drop(5)))
113 	      == sizeof(decltype(views::take(5)
114 				 | views::join
115 				 | views::common
116 				 | views::all
117 				 | views::keys
118 				 | views::drop(5)
119 				 | views::reverse)));
120 #endif
121 
122 template<auto all = views::all>
123 void
test05()124 test05()
125 {
126   // Verify SFINAE behavior.
127   static_assert(!requires { all(); });
128   static_assert(!requires { all(0, 0); });
129   static_assert(!requires { all(0); });
130   static_assert(!requires { 0 | all; });
131 }
132 
133 int
main()134 main()
135 {
136   test01();
137   test02();
138   static_assert(test03());
139   static_assert(test04());
140   test05();
141 }
142