• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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