3 // Copyright Thorsten Ottosen 2006. Use, modification and
4 // distribution is subject to the Boost Software License, Version
5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
8 // For more information, see http://www.boost.org/libs/range/
10 // (C) Copyright Eric Niebler 2004.
11 // Use, modification and distribution are subject to the
12 // Boost Software License, Version 1.0. (See accompanying file
13 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
17 13 December 2004 : Initial version.
21 // The 'secure' library warnings produce so much noise that it makes it
22 // impossible to see more useful warnings.
23 #define _SCL_SECURE_NO_WARNINGS
27 // counting_iterator generates a warning about truncating an integer
29 #pragma warning(disable : 4244)
31 #include <boost/iterator/counting_iterator.hpp>
33 template ::boost::counting_iterator<int>;
37 #include <boost/assign.hpp>
38 #include <boost/array.hpp>
39 #include <boost/bind.hpp>
40 #include <boost/range/numeric.hpp>
41 #include <boost/range/algorithm.hpp>
42 #include <boost/range/value_type.hpp>
43 #include <boost/range/size_type.hpp>
44 #include <boost/range/size.hpp>
46 #include <boost/test/test_tools.hpp>
47 #include <boost/test/unit_test.hpp>
49 #include <boost/iterator/iterator_traits.hpp>
58 ///////////////////////////////////////////////////////////////////////////////
59 // dummy function object, used with algorithms
64 void operator()(T const &t) const
69 ///////////////////////////////////////////////////////////////////////////////
70 // dummy predicate, used with algorithms
75 bool operator()(T const &t) const
81 ///////////////////////////////////////////////////////////////////////////////
82 // dummy unary op, used with algorithms
87 T const & operator()(T const & t) const
93 ///////////////////////////////////////////////////////////////////////////////
94 // dummy binary op, used with algorithms
98 template<typename T,typename U>
99 T const & operator()(T const & t, U const & u) const
105 template<typename Rng>
106 void test_random_algorithms(Rng & rng, std::random_access_iterator_tag)
108 typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Rng>::type iterator;
109 typedef BOOST_DEDUCED_TYPENAME boost::range_value<Rng>::type value_type;
110 typedef BOOST_DEDUCED_TYPENAME boost::range_size<Rng>::type size_type;
111 typedef BOOST_DEDUCED_TYPENAME boost::iterator_category<iterator>::type iterator_category;
113 // just make sure these compile (for now)
116 boost::random_shuffle(rng);
118 // Must be a value since random_shuffle must take the generator by
119 // reference to match the standard.
120 null_op1 rng_generator;
121 boost::random_shuffle(rng, rng_generator);
124 boost::sort(rng, std::less<value_type>());
126 boost::stable_sort(rng);
127 boost::stable_sort(rng, std::less<value_type>());
129 boost::partial_sort(rng, boost::begin(rng));
130 boost::partial_sort(rng, boost::begin(rng), std::less<value_type>());
132 boost::nth_element(rng, boost::begin(rng));
133 boost::nth_element(rng, boost::begin(rng), std::less<value_type>());
135 boost::push_heap(rng);
136 boost::push_heap(rng, std::less<value_type>());
138 boost::pop_heap(rng);
139 boost::pop_heap(rng, std::less<value_type>());
141 boost::make_heap(rng);
142 boost::make_heap(rng, std::less<value_type>());
144 boost::sort_heap(rng);
145 boost::sort_heap(rng, std::less<value_type>());
149 template<typename Rng>
150 void test_random_algorithms(Rng & rng, std::input_iterator_tag)
155 template<typename Rng>
156 void test_algorithms(Rng & rng)
158 typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Rng>::type iterator;
159 typedef BOOST_DEDUCED_TYPENAME boost::range_value<Rng>::type value_type;
160 typedef BOOST_DEDUCED_TYPENAME boost::range_size<Rng>::type size_type;
161 typedef BOOST_DEDUCED_TYPENAME boost::iterator_category<iterator>::type iterator_category;
163 // just make sure these compile (for now)
166 value_type val = value_type();
168 value_type rng2[] = {value_type(),value_type(),value_type()};
169 typedef value_type* iterator2;
171 value_type out[100] = {};
172 typedef value_type* out_iterator;
174 null_fun f = null_fun();
175 iterator i = iterator();
177 out_iterator o = out_iterator();
178 size_type s = size_type();
180 f = boost::for_each(rng, null_fun());
182 i = boost::find(rng, val);
183 i = boost::find_if(rng, null_pred());
185 i = boost::find_end(rng, rng2);
186 i = boost::find_end(rng, rng2, std::equal_to<value_type>());
188 i = boost::find_first_of(rng, rng2);
189 i = boost::find_first_of(rng, rng2, std::equal_to<value_type>());
191 i = boost::adjacent_find(rng);
192 i = boost::adjacent_find(rng, std::equal_to<value_type>());
194 s = boost::count(rng, val);
195 s = boost::count_if(rng, null_pred());
197 std::pair<iterator,iterator2> p1;
198 p1 = boost::mismatch(rng, rng2);
199 p1 = boost::mismatch(rng, rng2, std::equal_to<value_type>());
201 b = boost::equal(rng, rng2);
202 b = boost::equal(rng, rng2, std::equal_to<value_type>());
204 i = boost::search(rng, rng2);
205 i = boost::search(rng, rng2, std::equal_to<value_type>());
207 o = boost::copy(rng, boost::begin(out));
208 o = boost::copy_backward(rng, boost::end(out));
210 o = boost::transform(rng, boost::begin(out), null_op1());
211 o = boost::transform(rng, rng2, boost::begin(out), null_op2());
213 boost::replace(rng, val, val);
214 boost::replace_if(rng, null_pred(), val);
217 o = boost::replace_copy(rng, boost::begin(out), val, val);
218 o = boost::replace_copy_if(rng, boost::begin(out), null_pred(), val);
221 boost::fill(rng, val);
223 // size requires RandomAccess
225 //boost::fill_n(rng, boost::size(rng), val);
226 //boost::fill_n(rng, std::distance(boost::begin(rng),boost::end(rng)),val);
228 boost::generate(rng, &std::rand);
230 // size requires RandomAccess
232 //boost::generate_n(rng, boost::size(rng), &std::rand);
233 //boost::generate_n(rng,std::distance(boost::begin(rng),boost::end(rng)), &std::rand);
235 i = boost::remove(rng, val);
236 i = boost::remove_if(rng, null_pred());
239 o = boost::remove_copy(rng, boost::begin(out), val);
240 o = boost::remove_copy_if(rng, boost::begin(out), null_pred());
243 typename boost::range_return<Rng, boost::return_begin_found>::type rrng = boost::unique(rng);
244 rrng = boost::unique(rng, std::equal_to<value_type>());
247 o = boost::unique_copy(rng, boost::begin(out));
248 o = boost::unique_copy(rng, boost::begin(out), std::equal_to<value_type>());
254 o = boost::reverse_copy(rng, boost::begin(out));
257 boost::rotate(rng, boost::begin(rng));
260 o = boost::rotate_copy(rng, boost::begin(rng), boost::begin(out));
263 i = boost::partition(rng, null_pred());
264 i = boost::stable_partition(rng, null_pred());
267 o = boost::partial_sort_copy(rng, out);
268 o = boost::partial_sort_copy(rng, out, std::less<value_type>());
271 i = boost::lower_bound(rng, val);
272 i = boost::lower_bound(rng, val, std::less<value_type>());
274 i = boost::upper_bound(rng, val);
275 i = boost::upper_bound(rng, val, std::less<value_type>());
277 std::pair<iterator,iterator> p2;
278 p2 = boost::equal_range(rng, val);
279 p2 = boost::equal_range(rng, val, std::less<value_type>());
281 b = boost::binary_search(rng, val);
282 b = boost::binary_search(rng, val, std::less<value_type>());
284 boost::inplace_merge(rng, boost::begin(rng));
285 boost::inplace_merge(rng, boost::begin(rng), std::less<value_type>());
287 b = boost::includes(rng, rng2);
288 b = boost::includes(rng, rng2, std::equal_to<value_type>());
290 o = boost::set_union(rng, rng2, boost::begin(out));
291 o = boost::set_union(rng, rng2, boost::begin(out), std::equal_to<value_type>());
293 o = boost::set_intersection(rng, rng2, boost::begin(out));
294 o = boost::set_intersection(rng, rng2, boost::begin(out), std::equal_to<value_type>());
296 o = boost::set_difference(rng, rng2, boost::begin(out));
297 o = boost::set_difference(rng, rng2, boost::begin(out), std::equal_to<value_type>());
299 o = boost::set_symmetric_difference(rng, rng2, boost::begin(out));
300 o = boost::set_symmetric_difference(rng, rng2, boost::begin(out), std::equal_to<value_type>());
302 i = boost::min_element(rng);
303 i = boost::min_element(rng, std::less<value_type>());
305 i = boost::max_element(rng);
306 i = boost::max_element(rng, std::less<value_type>());
308 b = boost::lexicographical_compare(rng, rng);
309 b = boost::lexicographical_compare(rng, rng, std::equal_to<value_type>());
311 b = boost::next_permutation(rng);
312 b = boost::next_permutation(rng, std::less<value_type>());
314 b = boost::prev_permutation(rng);
315 b = boost::prev_permutation(rng, std::less<value_type>());
317 /////////////////////////////////////////////////////////////////////
318 // numeric algorithms
319 /////////////////////////////////////////////////////////////////////
321 val = boost::accumulate( rng, val );
322 val = boost::accumulate( rng, val, null_op2() );
323 val = boost::inner_product( rng, rng, val );
324 val = boost::inner_product( rng, rng, val,
325 null_op2(), null_op2() );
326 o = boost::partial_sum( rng, boost::begin(out) );
327 o = boost::partial_sum( rng, boost::begin(out), null_op2() );
328 o = boost::adjacent_difference( rng, boost::begin(out) );
329 o = boost::adjacent_difference( rng, boost::begin(out),
334 // test the algorithms that require a random-access range
335 test_random_algorithms(rng, iterator_category());
338 int* addr(int &i) { return &i; }
339 bool true_(int) { return true; }
341 ///////////////////////////////////////////////////////////////////////////////
344 void simple_compile_test()
347 typedef ::boost::counting_iterator<int> int_iterator;
349 // define come containers
350 std::list<int> my_list(int_iterator(1),int_iterator(6));
353 std::vector<int> my_vector(int_iterator(1),int_iterator(6));
355 std::pair<std::vector<int>::iterator,std::vector<int>::iterator> my_pair(my_vector.begin(),my_vector.end());
357 // test the algorithms with list and const list
358 test_algorithms(my_list);
359 test_algorithms(my_vector);
360 test_algorithms(my_pair);
364 std::vector<int>& cv = v;
366 using namespace boost;
368 #define BOOST_RANGE_RETURNS_TEST( function_name, cont ) \
369 function_name (cont); \
370 function_name <return_found> (cont); \
371 function_name <return_next> (cont); \
372 function_name <return_prior> (cont); \
373 function_name <return_begin_found> (cont); \
374 function_name <return_begin_next> (cont); \
375 function_name <return_begin_prior> (cont); \
376 function_name <return_found_end> (cont); \
377 function_name <return_next_end>(cont); \
378 function_name <return_prior_end>(cont);
380 BOOST_RANGE_RETURNS_TEST( adjacent_find, cv );
381 BOOST_RANGE_RETURNS_TEST( adjacent_find, v );
382 BOOST_RANGE_RETURNS_TEST( max_element, cv );
383 BOOST_RANGE_RETURNS_TEST( max_element, v );
384 BOOST_RANGE_RETURNS_TEST( min_element, cv );
385 BOOST_RANGE_RETURNS_TEST( min_element, v );
386 BOOST_RANGE_RETURNS_TEST( unique, v );
387 #undef BOOST_RANGE_RETURNS_TEST
389 #define BOOST_RANGE_RETURNS_TEST1( function_name, cont, arg1 ) \
390 function_name (cont, arg1); \
391 function_name <return_found> (cont, arg1); \
392 function_name <return_next> (cont, arg1); \
393 function_name <return_prior> (cont, arg1); \
394 function_name <return_begin_found> (cont, arg1); \
395 function_name <return_begin_next> (cont, arg1); \
396 function_name <return_begin_prior> (cont, arg1); \
397 function_name <return_found_end> (cont, arg1); \
398 function_name <return_next_end>(cont, arg1); \
399 function_name <return_prior_end>(cont, arg1);
401 BOOST_RANGE_RETURNS_TEST1( adjacent_find, cv, std::less<int>() );
402 BOOST_RANGE_RETURNS_TEST1( adjacent_find, v, std::less<int>() );
403 BOOST_RANGE_RETURNS_TEST1( find, cv, 0 );
404 BOOST_RANGE_RETURNS_TEST1( find, v, 0 );
405 BOOST_RANGE_RETURNS_TEST1( find_end, cv, cv );
406 BOOST_RANGE_RETURNS_TEST1( find_end, cv, v );
407 BOOST_RANGE_RETURNS_TEST1( find_end, v, cv );
408 BOOST_RANGE_RETURNS_TEST1( find_end, v, v );
409 BOOST_RANGE_RETURNS_TEST1( find_first_of, cv, cv );
410 BOOST_RANGE_RETURNS_TEST1( find_first_of, cv, v );
411 BOOST_RANGE_RETURNS_TEST1( find_first_of, v, cv );
412 BOOST_RANGE_RETURNS_TEST1( find_first_of, v, v );
413 BOOST_RANGE_RETURNS_TEST1( find_if, cv, std::negate<int>() );
414 BOOST_RANGE_RETURNS_TEST1( find_if, v, std::negate<int>() );
415 BOOST_RANGE_RETURNS_TEST1( search, cv, cv );
416 BOOST_RANGE_RETURNS_TEST1( search, cv, v );
417 BOOST_RANGE_RETURNS_TEST1( search, v, cv );
418 BOOST_RANGE_RETURNS_TEST1( search, v, v );
420 BOOST_RANGE_RETURNS_TEST1( remove, v, 0 );
421 BOOST_RANGE_RETURNS_TEST1( remove_if, v, std::negate<int>() );
423 BOOST_RANGE_RETURNS_TEST1( lower_bound, cv, 0 );
424 BOOST_RANGE_RETURNS_TEST1( lower_bound, v, 0 );
425 BOOST_RANGE_RETURNS_TEST1( max_element, cv, std::less<int>() );
426 BOOST_RANGE_RETURNS_TEST1( max_element, v, std::less<int>() );
427 BOOST_RANGE_RETURNS_TEST1( min_element, cv, std::less<int>() );
428 BOOST_RANGE_RETURNS_TEST1( min_element, v, std::less<int>() );
429 BOOST_RANGE_RETURNS_TEST1( upper_bound, cv, 0 );
430 BOOST_RANGE_RETURNS_TEST1( upper_bound, v, 0 );
431 BOOST_RANGE_RETURNS_TEST1( partition, cv, std::negate<int>() );
432 BOOST_RANGE_RETURNS_TEST1( partition, v, std::negate<int>() );
433 BOOST_RANGE_RETURNS_TEST1( stable_partition, cv, std::negate<int>() );
434 BOOST_RANGE_RETURNS_TEST1( stable_partition, v, std::negate<int>() );
436 #undef BOOST_RANGE_RETURNS_TEST1
438 #define BOOST_RANGE_RETURNS_TEST2( function_name, arg1, arg2 ) \
439 function_name (v, arg1, arg2); \
440 function_name <return_found> (v, arg1, arg2); \
441 function_name <return_next> (v, arg1, arg2); \
442 function_name <return_prior> (v, arg1, arg2); \
443 function_name <return_begin_found> (v, arg1, arg2); \
444 function_name <return_begin_next> (v, arg1, arg2); \
445 function_name <return_begin_prior> (v, arg1, arg2); \
446 function_name <return_found_end> (v, arg1, arg2); \
447 function_name <return_next_end>(v, arg1, arg2); \
448 function_name <return_prior_end>(v, arg1, arg2);
450 BOOST_RANGE_RETURNS_TEST2( find_end, v, std::less<int>() );
451 BOOST_RANGE_RETURNS_TEST2( find_first_of, v, std::less<int>() );
452 BOOST_RANGE_RETURNS_TEST2( search, v, std::less<int>() );
453 BOOST_RANGE_RETURNS_TEST2( lower_bound, 0, std::less<int>() );
454 BOOST_RANGE_RETURNS_TEST2( upper_bound, 0, std::less<int>() );
456 #undef BOOST_RANGE_RETURNS_TEST2
459 using boost::unit_test::test_suite;
461 test_suite* init_unit_test_suite( int argc, char* argv[] )
463 using namespace boost;
465 test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - Algorithm" );
467 test->add( BOOST_TEST_CASE( &simple_compile_test ) );