1 // Copyright (C) 2020-2022 Free Software Foundation, Inc.
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)
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.
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/>.
18 // { dg-options "-std=gnu++2a" }
19 // { dg-do run { target c++2a } }
23 #include <testsuite_hooks.h>
24 #include <testsuite_iterators.h>
26 using __gnu_test::test_range
;
27 using __gnu_test::bidirectional_iterator_wrapper
;
28 using __gnu_test::forward_iterator_wrapper
;
29 using __gnu_test::random_access_iterator_wrapper
;
31 namespace ranges
= std::ranges
;
32 namespace views
= std::ranges::views
;
37 int x
[] = {1,2,3,4,5,6};
38 auto is_odd
= [] (int i
) { return i
%2==1; };
39 auto v
= x
| views::filter(is_odd
);
40 using R
= decltype(v
);
41 static_assert(std::same_as
<int&, decltype(*v
.begin())>);
42 static_assert(ranges::view
<R
>);
43 static_assert(ranges::input_range
<R
>);
44 static_assert(ranges::common_range
<R
>);
45 static_assert(!ranges::sized_range
<R
>);
46 static_assert(ranges::bidirectional_range
<R
>);
47 static_assert(!ranges::random_access_range
<R
>);
48 static_assert(ranges::range
<views::all_t
<R
>>);
49 VERIFY( ranges::equal(v
, (int[]){1,3,5}) );
50 VERIFY( ranges::equal(v
| views::reverse
, (int[]){5,3,1}) );
51 VERIFY( v
.pred()(3) == true );
52 VERIFY( v
.pred()(4) == false );
58 int x
[] = {1,2,3,4,5,6};
59 auto f
= [flag
=false] (int) mutable { return flag
= !flag
; };
60 auto v
= views::filter(f
)(x
);
61 using R
= decltype(v
);
62 static_assert(std::same_as
<int&, decltype(*v
.begin())>);
63 static_assert(ranges::range
<R
>);
64 static_assert(std::copyable
<R
>);
65 static_assert(!ranges::view
<const R
>);
66 VERIFY( ranges::equal(v
, (int[]){1,3,5}) );
77 X x
[] = {{1,3}, {2,5}, {3,7}, {4,9}};
78 test_range
<X
, bidirectional_iterator_wrapper
> rx(x
);
79 auto v
= rx
| views::filter([] (auto&& p
) { return p
.i
%2==0; });
81 for (auto i
= v
.begin(); i
!= v
.end(); ++i
)
89 auto yes
= [] (int) { return true; };
90 VERIFY( ranges::equal(views::iota(0) | views::filter(yes
) | views::take(1),
94 // The following tests that filter_view::begin caches its result.
96 template<template<typename
> typename wrapper
>
97 struct test_view
: ranges::view_base
99 bool begin_already_called
= false;
100 static inline int x
[] = {1,2,3,4,5};
101 test_range
<int, wrapper
> rx
{x
};
106 if (begin_already_called
)
108 begin_already_called
= true;
117 template<template<typename
> typename wrapper
>
121 auto v
= test_view
<wrapper
>{} | views::filter([] (int i
) { return i
%2 == 0; });
122 VERIFY( ranges::equal(v
, (int[]){2,4}) );
123 VERIFY( ranges::equal(v
, (int[]){2,4}) );
126 template<auto filter
= views::filter
>
130 // Verify SFINAE behavior.
132 auto p
= [] (int*) { return true; };
133 static_assert(!requires
{ filter(); });
134 static_assert(!requires
{ filter(x
, p
, p
); });
135 static_assert(!requires
{ filter(x
, p
); });
136 static_assert(!requires
{ filter(p
)(x
); });
137 static_assert(!requires
{ x
| (filter(p
) | views::all
); });
138 static_assert(!requires
{ (filter(p
) | views::all
)(x
); });
139 static_assert(!requires
{ filter
| views::all
; });
140 static_assert(!requires
{ views::all
| filter
; });
149 constexpr Pred(const Pred
&) { }
150 constexpr Pred(Pred
&&) { }
151 // These make it non-copyable, so non-copyable-box<Pred> will provide
153 Pred
& operator=(const Pred
&) = delete;
154 Pred
& operator=(Pred
&&) = delete;
156 bool operator()(int i
) const { return i
< 10; }
160 ranges::filter_view
v(views::single(i
), Pred
{});
161 // LWG 3572. copyable-box should be fully constexpr
168 static_assert( test07() );
177 test05
<forward_iterator_wrapper
>();
178 test05
<random_access_iterator_wrapper
>();