1 /*
2 Copyright (c) Marshall Clow 2012.
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 For more information, see http://www.boost.org
8 */
9
10 #include <boost/config.hpp>
11 #include <boost/algorithm/cxx11/copy_if.hpp>
12
13 #include "iterator_test.hpp"
14
15 #define BOOST_TEST_MAIN
16 #include <boost/test/unit_test.hpp>
17
18 #include <algorithm>
19 #include <string>
20 #include <iostream>
21 #include <vector>
22 #include <list>
23
24 #include <boost/algorithm/cxx11/all_of.hpp>
25 #include <boost/algorithm/cxx14/equal.hpp>
26 #include <boost/algorithm/cxx11/none_of.hpp>
27
28 namespace ba = boost::algorithm;
29 // namespace ba = boost;
30
is_true(int v)31 BOOST_CXX14_CONSTEXPR bool is_true ( int v ) { return true; }
is_false(int v)32 BOOST_CXX14_CONSTEXPR bool is_false ( int v ) { return false; }
is_even(int v)33 BOOST_CXX14_CONSTEXPR bool is_even ( int v ) { return v % 2 == 0; }
is_odd(int v)34 BOOST_CXX14_CONSTEXPR bool is_odd ( int v ) { return v % 2 == 1; }
is_zero(int v)35 BOOST_CXX14_CONSTEXPR bool is_zero ( int v ) { return v == 0; }
36
37
38 template <typename Container>
test_copy_if(Container const & c)39 void test_copy_if ( Container const &c ) {
40
41 typedef typename Container::value_type value_type;
42 std::vector<value_type> v;
43
44 // None of the elements
45 v.clear ();
46 ba::copy_if ( c.begin (), c.end (), back_inserter ( v ), is_false);
47 BOOST_CHECK ( v.size () == 0 );
48
49 v.clear ();
50 ba::copy_if ( c, back_inserter ( v ), is_false);
51 BOOST_CHECK ( v.size () == 0 );
52
53 // All the elements
54 v.clear ();
55 ba::copy_if ( c.begin (), c.end (), back_inserter ( v ), is_true);
56 BOOST_CHECK ( v.size () == c.size ());
57 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
58
59 v.clear ();
60 ba::copy_if ( c, back_inserter ( v ), is_true);
61 BOOST_CHECK ( v.size () == c.size ());
62 BOOST_CHECK ( v.size () == c.size ());
63 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
64
65 // Some of the elements
66 v.clear ();
67 ba::copy_if ( c.begin (), c.end (), back_inserter ( v ), is_even );
68 BOOST_CHECK ( v.size () == (size_t) std::count_if ( c.begin (), c.end (), is_even ));
69 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
70
71 v.clear ();
72 ba::copy_if ( c, back_inserter ( v ), is_even );
73 BOOST_CHECK ( v.size () == (size_t) std::count_if ( c.begin (), c.end (), is_even ));
74 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
75 }
76
77
78 template <typename Container>
test_copy_while(Container const & c)79 void test_copy_while ( Container const &c ) {
80
81 typedef typename Container::value_type value_type;
82 typename Container::const_iterator it;
83 std::vector<value_type> v;
84
85 // None of the elements
86 v.clear ();
87 ba::copy_while ( c.begin (), c.end (), back_inserter ( v ), is_false);
88 BOOST_CHECK ( v.size () == 0 );
89
90 v.clear ();
91 ba::copy_while ( c, back_inserter ( v ), is_false);
92 BOOST_CHECK ( v.size () == 0 );
93
94 // All the elements
95 v.clear ();
96 ba::copy_while ( c.begin (), c.end (), back_inserter ( v ), is_true);
97 BOOST_CHECK ( v.size () == c.size ());
98 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
99
100 v.clear ();
101 ba::copy_while ( c, back_inserter ( v ), is_true);
102 BOOST_CHECK ( v.size () == c.size ());
103 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
104
105 // Some of the elements
106 v.clear ();
107 it = ba::copy_while ( c.begin (), c.end (), back_inserter ( v ), is_even ).first;
108 BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it ));
109 BOOST_CHECK ( it == c.end () || !is_even ( *it ));
110 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
111 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
112
113 v.clear ();
114 it = ba::copy_while ( c, back_inserter ( v ), is_even ).first;
115 BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it ));
116 BOOST_CHECK ( it == c.end () || !is_even ( *it ));
117 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
118 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
119 }
120
121 template <typename Container>
test_copy_until(Container const & c)122 void test_copy_until ( Container const &c ) {
123
124 typedef typename Container::value_type value_type;
125 typename Container::const_iterator it;
126 std::vector<value_type> v;
127
128 // None of the elements
129 v.clear ();
130 ba::copy_until ( c.begin (), c.end (), back_inserter ( v ), is_true);
131 BOOST_CHECK ( v.size () == 0 );
132
133 v.clear ();
134 ba::copy_until ( c, back_inserter ( v ), is_true);
135 BOOST_CHECK ( v.size () == 0 );
136
137 // All the elements
138 v.clear ();
139 ba::copy_until ( c.begin (), c.end (), back_inserter ( v ), is_false);
140 BOOST_CHECK ( v.size () == c.size ());
141 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
142
143 v.clear ();
144 ba::copy_until ( c, back_inserter ( v ), is_false);
145 BOOST_CHECK ( v.size () == c.size ());
146 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
147
148 // Some of the elements
149 v.clear ();
150 it = ba::copy_until ( c.begin (), c.end (), back_inserter ( v ), is_even ).first;
151 BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it ));
152 BOOST_CHECK ( it == c.end () || is_even ( *it ));
153 BOOST_CHECK ( ba::none_of ( v.begin (), v.end (), is_even ));
154 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
155
156 v.clear ();
157 it = ba::copy_until ( c, back_inserter ( v ), is_even ).first;
158 BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it ));
159 BOOST_CHECK ( it == c.end () || is_even ( *it ));
160 BOOST_CHECK ( ba::none_of ( v.begin (), v.end (), is_even ));
161 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
162 }
163
164
constexpr_test_copy_if()165 BOOST_CXX14_CONSTEXPR inline bool constexpr_test_copy_if() {
166 const int sz = 64;
167 int in_data[sz] = {0};
168 bool res = true;
169
170 const int* from = in_data;
171 const int* to = in_data + sz;
172
173 int out_data[sz] = {0};
174 int* out = out_data;
175 out = ba::copy_if ( from, to, out, is_false ); // copy none
176 res = (res && out == out_data);
177
178 out = ba::copy_if ( from, to, out, is_true ); // copy all
179 res = (res && out == out_data + sz
180 && ba::equal( input_iterator<const int *>(out_data), input_iterator<const int *>(out_data + sz),
181 input_iterator<const int *>(from), input_iterator<const int *>(to)));
182
183 return res;
184 }
185
constexpr_test_copy_while()186 BOOST_CXX14_CONSTEXPR inline bool constexpr_test_copy_while() {
187 const int sz = 64;
188 int in_data[sz] = {0};
189 bool res = true;
190
191 const int* from = in_data;
192 const int* to = in_data + sz;
193
194 int out_data[sz] = {0};
195 int* out = out_data;
196 out = ba::copy_while ( from, to, out, is_false ).second; // copy none
197 res = (res && out == out_data && ba::all_of(out, out + sz, is_zero));
198
199 out = ba::copy_while ( from, to, out, is_true ).second; // copy all
200 res = (res && out == out_data + sz
201 && ba::equal( input_iterator<const int *>(out_data), input_iterator<const int *>(out_data + sz),
202 input_iterator<const int *>(from), input_iterator<const int *>(to)));
203
204 return res;
205 }
206
constexpr_test_copy_until()207 BOOST_CXX14_CONSTEXPR inline bool constexpr_test_copy_until() {
208 const int sz = 64;
209 int in_data[sz] = {0};
210 bool res = true;
211
212 const int* from = in_data;
213 const int* to = in_data + sz;
214
215 int out_data[sz] = {0};
216 int* out = out_data;
217 out = ba::copy_until ( from, to, out, is_true ).second; // copy none
218 res = (res && out == out_data && ba::all_of(out, out + sz, is_zero));
219
220 out = ba::copy_until ( from, to, out, is_false ).second; // copy all
221 res = (res && out == out_data + sz
222 && ba::equal( input_iterator<const int *>(out_data), input_iterator<const int *>(out_data + sz),
223 input_iterator<const int *>(from), input_iterator<const int *>(to)));
224
225 return res;
226 }
227
228
test_sequence1()229 void test_sequence1 () {
230 std::vector<int> v;
231 for ( int i = 5; i < 15; ++i )
232 v.push_back ( i );
233 test_copy_if ( v );
234 test_copy_while ( v );
235 test_copy_until ( v );
236
237 BOOST_CXX14_CONSTEXPR bool constexpr_res_if = constexpr_test_copy_if();
238 BOOST_CHECK ( constexpr_res_if );
239 BOOST_CXX14_CONSTEXPR bool constexpr_res_while = constexpr_test_copy_while();
240 BOOST_CHECK ( constexpr_res_while );
241 BOOST_CXX14_CONSTEXPR bool constexpr_res_until = constexpr_test_copy_until();
242 BOOST_CHECK ( constexpr_res_until );
243
244 std::list<int> l;
245 for ( int i = 25; i > 15; --i )
246 l.push_back ( i );
247 test_copy_if ( l );
248 test_copy_while ( l );
249 test_copy_until ( l );
250 }
251
252
BOOST_AUTO_TEST_CASE(test_main)253 BOOST_AUTO_TEST_CASE( test_main )
254 {
255 test_sequence1 ();
256 }
257