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
28namespace ba = boost::algorithm;
29// namespace ba = boost;
30
31BOOST_CXX14_CONSTEXPR bool is_true ( int ) { return true; }
32BOOST_CXX14_CONSTEXPR bool is_false ( int ) { return false; }
33BOOST_CXX14_CONSTEXPR bool is_even ( int v ) { return v % 2 == 0; }
34BOOST_CXX14_CONSTEXPR bool is_odd ( int v ) { return v % 2 == 1; }
35BOOST_CXX14_CONSTEXPR bool is_zero ( int v ) { return v == 0; }
36
37BOOST_CXX14_CONSTEXPR bool less_than_ten ( int v ) { return v < 10; }
38BOOST_CXX14_CONSTEXPR bool greater_than_ten ( int v ) { return v > 10; }
39
40template <typename Container>
41void test_copy_if ( Container const &c ) {
42
43 typedef typename Container::value_type value_type;
44 std::vector<value_type> v;
45
46// None of the elements
47 v.clear ();
48 ba::copy_if ( c.begin (), c.end (), back_inserter ( v ), is_false);
49 BOOST_CHECK ( v.size () == 0 );
50
51 v.clear ();
52 ba::copy_if ( c, back_inserter ( v ), is_false);
53 BOOST_CHECK ( v.size () == 0 );
54
55// All the elements
56 v.clear ();
57 ba::copy_if ( c.begin (), c.end (), back_inserter ( v ), is_true);
58 BOOST_CHECK ( v.size () == c.size ());
59 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
60
61 v.clear ();
62 ba::copy_if ( c, back_inserter ( v ), is_true);
63 BOOST_CHECK ( v.size () == c.size ());
64 BOOST_CHECK ( v.size () == c.size ());
65 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
66
67// Some of the elements
68 v.clear ();
69 ba::copy_if ( c.begin (), c.end (), back_inserter ( v ), is_even );
70 BOOST_CHECK ( v.size () == (size_t) std::count_if ( c.begin (), c.end (), is_even ));
71 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
72
73 v.clear ();
74 ba::copy_if ( c, back_inserter ( v ), is_even );
75 BOOST_CHECK ( v.size () == (size_t) std::count_if ( c.begin (), c.end (), is_even ));
76 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
77 }
78
79
80template <typename Container>
81void test_copy_while ( Container const &c ) {
82
83 typedef typename Container::value_type value_type;
84 typename Container::const_iterator it;
85 std::vector<value_type> v;
86
87// None of the elements
88 v.clear ();
89 ba::copy_while ( c.begin (), c.end (), back_inserter ( v ), is_false);
90 BOOST_CHECK ( v.size () == 0 );
91
92 v.clear ();
93 ba::copy_while ( c, back_inserter ( v ), is_false);
94 BOOST_CHECK ( v.size () == 0 );
95
96// All the elements
97 v.clear ();
98 ba::copy_while ( c.begin (), c.end (), back_inserter ( v ), is_true);
99 BOOST_CHECK ( v.size () == c.size ());
100 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
101
102 v.clear ();
103 ba::copy_while ( c, back_inserter ( v ), is_true);
104 BOOST_CHECK ( v.size () == c.size ());
105 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
106
107// Some of the elements
108 v.clear ();
109 it = ba::copy_while ( c.begin (), c.end (), back_inserter ( v ), is_even ).first;
110 BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it ));
111 BOOST_CHECK ( it == c.end () || !is_even ( *it ));
112 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
113 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
114
115 v.clear ();
116 it = ba::copy_while ( c, back_inserter ( v ), is_even ).first;
117 BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it ));
118 BOOST_CHECK ( it == c.end () || !is_even ( *it ));
119 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
120 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
121 }
122
123template <typename Container>
124void test_copy_if_while ( Container const &c ) {
125
126 typedef typename Container::value_type value_type;
127 typename Container::const_iterator it;
128
129// Terminate immediately
130 {
131 std::vector<value_type> v;
132 ba::copy_if_while ( c.begin (), c.end (), back_inserter ( v ), is_true, is_false);
133 BOOST_CHECK ( v.size () == 0 );
134 }
135 {
136 std::vector<value_type> v;
137 ba::copy_if_while ( c, back_inserter ( v ), is_true, is_false);
138 BOOST_CHECK ( v.size () == 0 );
139 }
140
141// Copy nothing - never terminate
142 {
143 std::vector<value_type> v;
144 ba::copy_if_while ( c.begin (), c.end (), back_inserter ( v ), is_false, is_true);
145 BOOST_CHECK ( v.size () == 0 );
146 }
147 {
148 std::vector<value_type> v;
149 ba::copy_if_while ( c, back_inserter ( v ), is_false, is_true);
150 BOOST_CHECK ( v.size () == 0 );
151 }
152
153// Copy everything
154 {
155 std::vector<value_type> v;
156 ba::copy_if_while ( c.begin (), c.end (), back_inserter ( v ), is_true, is_true);
157 BOOST_CHECK ( v.size () == c.size() );
158 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
159 }
160 {
161 std::vector<value_type> v;
162 ba::copy_if_while ( c, back_inserter ( v ), is_true, is_true);
163 BOOST_CHECK ( v.size () == c.size() );
164 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
165 }
166
167// Copy all evens
168 {
169 std::vector<value_type> v;
170 ba::copy_if_while ( c.begin (), c.end (), back_inserter ( v ), is_even, is_true);
171 BOOST_CHECK ( v.size () == (size_t) std::count_if ( c.begin (), c.end (), is_even ));
172 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
173 }
174 {
175 std::vector<value_type> v;
176 ba::copy_if_while ( c, back_inserter ( v ), is_even, is_true);
177 BOOST_CHECK ( v.size () == (size_t) std::count_if ( c.begin (), c.end (), is_even ));
178 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
179 }
180
181// Copy some until termination
182 {
183 std::vector<value_type> v;
184 typename Container::const_iterator it = ba::copy_if_while (
185 c.begin (), c.end (), back_inserter ( v ), is_even, less_than_ten).first;
186 BOOST_CHECK ( it == std::find_if ( c.begin(), c.end(), greater_than_ten ));
187 BOOST_CHECK ( v.size () == std::count_if ( c.begin(), it, is_even ));
188 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
189 }
190 {
191 std::vector<value_type> v;
192 typename Container::const_iterator it = ba::copy_if_while (
193 c, back_inserter ( v ), is_even, less_than_ten).first;
194 BOOST_CHECK ( it == std::find_if ( c.begin(), c.end(), greater_than_ten ));
195 BOOST_CHECK ( v.size () == std::count_if ( c.begin(), it, is_even ));
196 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
197 }
198 }
199
200template <typename Container>
201void test_copy_if_until ( Container const &c ) {
202
203 typedef typename Container::value_type value_type;
204 typename Container::const_iterator it;
205
206// Terminate immediately
207 {
208 std::vector<value_type> v;
209 ba::copy_if_until ( c.begin (), c.end (), back_inserter ( v ), is_true, is_true);
210 BOOST_CHECK ( v.size () == 0 );
211 }
212 {
213 std::vector<value_type> v;
214 ba::copy_if_until ( c, back_inserter ( v ), is_true, is_true);
215 BOOST_CHECK ( v.size () == 0 );
216 }
217
218// Copy nothing - never terminate
219 {
220 std::vector<value_type> v;
221 ba::copy_if_until ( c.begin (), c.end (), back_inserter ( v ), is_false, is_false);
222 BOOST_CHECK ( v.size () == 0 );
223 }
224 {
225 std::vector<value_type> v;
226 ba::copy_if_until ( c, back_inserter ( v ), is_false, is_false);
227 BOOST_CHECK ( v.size () == 0 );
228 }
229
230// Copy everything
231 {
232 std::vector<value_type> v;
233 ba::copy_if_until ( c.begin (), c.end (), back_inserter ( v ), is_true, is_false);
234 BOOST_CHECK ( v.size () == c.size() );
235 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
236 }
237 {
238 std::vector<value_type> v;
239 ba::copy_if_until ( c, back_inserter ( v ), is_true, is_false);
240 BOOST_CHECK ( v.size () == c.size() );
241 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
242 }
243
244// Copy all evens
245 {
246 std::vector<value_type> v;
247 ba::copy_if_until ( c.begin (), c.end (), back_inserter ( v ), is_even, is_false);
248 BOOST_CHECK ( v.size () == (size_t) std::count_if ( c.begin (), c.end (), is_even ));
249 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
250 }
251 {
252 std::vector<value_type> v;
253 ba::copy_if_until ( c, back_inserter ( v ), is_even, is_false);
254 BOOST_CHECK ( v.size () == (size_t) std::count_if ( c.begin (), c.end (), is_even ));
255 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
256 }
257
258// Copy some until termination
259 {
260 std::vector<value_type> v;
261 typename Container::const_iterator it = ba::copy_if_until (
262 c.begin (), c.end (), back_inserter ( v ), is_even, greater_than_ten).first;
263 BOOST_CHECK ( it == std::find_if ( c.begin(), c.end(), greater_than_ten ));
264 BOOST_CHECK ( v.size () == std::count_if ( c.begin(), it, is_even ));
265 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
266 }
267 {
268 std::vector<value_type> v;
269 typename Container::const_iterator it = ba::copy_if_until (
270 c, back_inserter ( v ), is_even, greater_than_ten).first;
271 BOOST_CHECK ( it == std::find_if ( c.begin(), c.end(), greater_than_ten ));
272 BOOST_CHECK ( v.size () == std::count_if ( c.begin(), it, is_even ));
273 BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
274 }
275 }
276
277template <typename Container>
278void test_copy_until ( Container const &c ) {
279
280 typedef typename Container::value_type value_type;
281 typename Container::const_iterator it;
282 std::vector<value_type> v;
283
284// None of the elements
285 v.clear ();
286 ba::copy_until ( c.begin (), c.end (), back_inserter ( v ), is_true);
287 BOOST_CHECK ( v.size () == 0 );
288
289 v.clear ();
290 ba::copy_until ( c, back_inserter ( v ), is_true);
291 BOOST_CHECK ( v.size () == 0 );
292
293// All the elements
294 v.clear ();
295 ba::copy_until ( c.begin (), c.end (), back_inserter ( v ), is_false);
296 BOOST_CHECK ( v.size () == c.size ());
297 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
298
299 v.clear ();
300 ba::copy_until ( c, back_inserter ( v ), is_false);
301 BOOST_CHECK ( v.size () == c.size ());
302 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
303
304// Some of the elements
305 v.clear ();
306 it = ba::copy_until ( c.begin (), c.end (), back_inserter ( v ), is_even ).first;
307 BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it ));
308 BOOST_CHECK ( it == c.end () || is_even ( *it ));
309 BOOST_CHECK ( ba::none_of ( v.begin (), v.end (), is_even ));
310 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
311
312 v.clear ();
313 it = ba::copy_until ( c, back_inserter ( v ), is_even ).first;
314 BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it ));
315 BOOST_CHECK ( it == c.end () || is_even ( *it ));
316 BOOST_CHECK ( ba::none_of ( v.begin (), v.end (), is_even ));
317 BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
318 }
319
320
321BOOST_CXX14_CONSTEXPR inline bool constexpr_test_copy_if() {
322 const int sz = 64;
323 int in_data[sz] = {0};
324 bool res = true;
325
326 const int* from = in_data;
327 const int* to = in_data + sz;
328
329 int out_data[sz] = {0};
330 int* out = out_data;
331 out = ba::copy_if ( first: from, last: to, result: out, p: is_false ); // copy none
332 res = (res && out == out_data);
333
334 out = ba::copy_if ( first: from, last: to, result: out, p: is_true ); // copy all
335 res = (res && out == out_data + sz
336 && ba::equal( first1: input_iterator<const int *>(out_data), last1: input_iterator<const int *>(out_data + sz),
337 first2: input_iterator<const int *>(from), last2: input_iterator<const int *>(to)));
338
339 return res;
340 }
341
342BOOST_CXX14_CONSTEXPR inline bool constexpr_test_copy_while() {
343 const int sz = 64;
344 int in_data[sz] = {0};
345 bool res = true;
346
347 const int* from = in_data;
348 const int* to = in_data + sz;
349
350 int out_data[sz] = {0};
351 int* out = out_data;
352 out = ba::copy_while ( first: from, last: to, result: out, p: is_false ).second; // copy none
353 res = (res && out == out_data && ba::all_of(first: out, last: out + sz, p: is_zero));
354
355 out = ba::copy_while ( first: from, last: to, result: out, p: is_true ).second; // copy all
356 res = (res && out == out_data + sz
357 && ba::equal( first1: input_iterator<const int *>(out_data), last1: input_iterator<const int *>(out_data + sz),
358 first2: input_iterator<const int *>(from), last2: input_iterator<const int *>(to)));
359
360 return res;
361 }
362
363BOOST_CXX14_CONSTEXPR inline bool constexpr_test_copy_until() {
364 const int sz = 64;
365 int in_data[sz] = {0};
366 bool res = true;
367
368 const int* from = in_data;
369 const int* to = in_data + sz;
370
371 int out_data[sz] = {0};
372 int* out = out_data;
373 out = ba::copy_until ( first: from, last: to, result: out, p: is_true ).second; // copy none
374 res = (res && out == out_data && ba::all_of(first: out, last: out + sz, p: is_zero));
375
376 out = ba::copy_until ( first: from, last: to, result: out, p: is_false ).second; // copy all
377 res = (res && out == out_data + sz
378 && ba::equal( first1: input_iterator<const int *>(out_data), last1: input_iterator<const int *>(out_data + sz),
379 first2: input_iterator<const int *>(from), last2: input_iterator<const int *>(to)));
380
381 return res;
382 }
383
384BOOST_CXX14_CONSTEXPR inline bool constexpr_test_copy_if_while() {
385 const int sz = 64;
386 int in_data[sz] = {0};
387 bool res = true;
388
389 const int* from = in_data;
390 const int* to = in_data + sz;
391
392// Terminate immediately
393 {
394 int out_data[sz] = {0};
395 int* out = out_data;
396 out = ba::copy_if_while ( first: from, last: to, result: out, copy_pred: is_true, term_pred: is_false ).second;
397 res = (res && out == out_data && ba::all_of(first: out, last: out + sz, p: is_zero));
398 }
399// Copy nothing
400 {
401 int out_data[sz] = {0};
402 int* out = out_data;
403 out = ba::copy_if_while ( first: from, last: to, result: out, copy_pred: is_false, term_pred: is_true ).second;
404 res = (res && out == out_data && ba::all_of(first: out, last: out + sz, p: is_zero));
405 }
406// Copy everything
407 {
408 int out_data[sz] = {0};
409 int* out = out_data;
410 out = ba::copy_if_while ( first: from, last: to, result: out, copy_pred: is_true, term_pred: is_true ).second;
411 res = (res && out == out_data + sz
412 && ba::equal( first1: input_iterator<const int *>(out_data), last1: input_iterator<const int *>(out_data + sz),
413 first2: input_iterator<const int *>(from), last2: input_iterator<const int *>(to)));
414 }
415
416 return res;
417 }
418
419BOOST_CXX14_CONSTEXPR inline bool constexpr_test_copy_if_until() {
420 const int sz = 64;
421 int in_data[sz] = {0};
422 bool res = true;
423
424 const int* from = in_data;
425 const int* to = in_data + sz;
426
427// Terminate immediately
428 {
429 int out_data[sz] = {0};
430 int* out = out_data;
431 out = ba::copy_if_until ( first: from, last: to, result: out, copy_pred: is_true, term_pred: is_true ).second;
432 res = (res && out == out_data && ba::all_of(first: out, last: out + sz, p: is_zero));
433 }
434// Copy nothing
435 {
436 int out_data[sz] = {0};
437 int* out = out_data;
438 out = ba::copy_if_until ( first: from, last: to, result: out, copy_pred: is_false, term_pred: is_false ).second;
439 res = (res && out == out_data && ba::all_of(first: out, last: out + sz, p: is_zero));
440 }
441// Copy everything
442 {
443 int out_data[sz] = {0};
444 int* out = out_data;
445 out = ba::copy_if_until ( first: from, last: to, result: out, copy_pred: is_true, term_pred: is_false ).second;
446 res = (res && out == out_data + sz
447 && ba::equal( first1: input_iterator<const int *>(out_data), last1: input_iterator<const int *>(out_data + sz),
448 first2: input_iterator<const int *>(from), last2: input_iterator<const int *>(to)));
449 }
450
451 return res;
452 }
453
454void test_sequence1 () {
455 std::vector<int> v;
456 for ( int i = 5; i < 15; ++i )
457 v.push_back ( x: i );
458 test_copy_if ( c: v );
459 test_copy_while ( c: v );
460 test_copy_until ( c: v );
461
462 BOOST_CXX14_CONSTEXPR bool constexpr_res_if = constexpr_test_copy_if();
463 BOOST_CHECK ( constexpr_res_if );
464 BOOST_CXX14_CONSTEXPR bool constexpr_res_while = constexpr_test_copy_while();
465 BOOST_CHECK ( constexpr_res_while );
466 BOOST_CXX14_CONSTEXPR bool constexpr_res_until = constexpr_test_copy_until();
467 BOOST_CHECK ( constexpr_res_until );
468 BOOST_CXX14_CONSTEXPR bool constexpr_res_if_while = constexpr_test_copy_if_while();
469 BOOST_CHECK ( constexpr_res_if_while );
470 BOOST_CXX14_CONSTEXPR bool constexpr_res_if_until = constexpr_test_copy_if_until();
471 BOOST_CHECK ( constexpr_res_if_until );
472
473 std::list<int> l;
474 for ( int i = 25; i > 15; --i )
475 l.push_back ( x: i );
476 test_copy_if ( c: l );
477 test_copy_while ( c: l );
478 test_copy_until ( c: l );
479 test_copy_if_while ( c: l );
480 test_copy_if_until ( c: l );
481 }
482
483
484BOOST_AUTO_TEST_CASE( test_main )
485{
486 test_sequence1 ();
487}
488

source code of boost/libs/algorithm/test/copy_if_test1.cpp