]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/25_algorithms/for_each/constrained.cc
7814299accb52aa5de0389577ad252c41ede32b9
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 25_algorithms / for_each / constrained.cc
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 <testsuite_hooks.h>
23 #include <testsuite_iterators.h>
24
25 using __gnu_test::test_container;
26 using __gnu_test::test_range;
27 using __gnu_test::input_iterator_wrapper;
28 using __gnu_test::forward_iterator_wrapper;
29 using __gnu_test::random_access_iterator_wrapper;
30
31 namespace ranges = std::ranges;
32
33 struct X { int i; };
34
35 static int a;
36
37 void
38 f(int& i)
39 {
40 a += i;
41 }
42
43 void
44 test01()
45 {
46 X x[] = { {2}, {4}, {6}, {8}, {10}, {11} };
47
48 auto res = ranges::for_each(x, x+6, f, &X::i);
49 VERIFY( res.in == x+6 );
50 VERIFY( res.fun == &f );
51 VERIFY( a == 41 );
52
53 test_container<X, forward_iterator_wrapper> c(x);
54 int p = 0;
55 ranges::for_each(c, [&p](int i) { ++p; }, &X::i);
56 VERIFY( p == 6 );
57
58 test_range<X, input_iterator_wrapper> r(x);
59 int q = 0;
60 ranges::for_each(r, [&q](X&) { ++q; });
61 VERIFY( q == 6 );
62 }
63
64 struct Y { int i; int j; };
65
66 void
67 test02()
68 {
69 auto f = []
70 {
71 Y y[] = { {1,2}, {2,4}, {3,6} };
72 int a = 0;
73 ranges::for_each(y, [&a](int i) { a += i; }, &Y::i);
74 return a;
75 };
76 static_assert(f() == 6);
77 }
78
79 template<template<typename> typename wrapper>
80 void
81 test03()
82 {
83 int x[] = {1,2,3,4,5};
84 test_range<int, wrapper> rx(x);
85 int s = 0;
86 auto func = [&s](int i){ s += i; };
87 auto [i,f] = ranges::for_each_n(rx.begin(), 3, func);
88 VERIFY( i.ptr = x+3 );
89 VERIFY( s == 1+2+3 );
90 f(1);
91 VERIFY( s == 1+2+3+1 );
92
93 s = 0;
94 rx.bounds.first = x;
95 auto [j,g] = ranges::for_each_n(rx.begin(), -1, func);
96 VERIFY( j.ptr == x );
97 VERIFY( s == 0 );
98 g(1);
99 VERIFY( s == 1 );
100
101 s = 0;
102 rx.bounds.first = x;
103 auto [k,h] = ranges::for_each_n(rx.begin(), 5, func, std::negate<>{});
104 VERIFY( k.ptr == x+5 );
105 VERIFY( s == -(1+2+3+4+5) );
106 h(-6);
107 VERIFY( s == -(1+2+3+4+5+6) );
108 }
109
110 constexpr bool
111 test04()
112 {
113 int x[] = {1,2,3,4,5};
114 int p = 1;
115 ranges::for_each_n(x+1, 4, [&p](int i){ p*=i; }, [](int i){ return i+1; });
116 return p == 3*4*5*6;
117 }
118
119 int
120 main()
121 {
122 test01();
123 test02();
124 test03<input_iterator_wrapper>();
125 test03<random_access_iterator_wrapper>();
126 static_assert(test04());
127 }