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/config.hpp>
39 #include <boost/array.hpp>
40 #include <boost/bind.hpp>
41 #include <boost/range/numeric.hpp>
42 #include <boost/range/algorithm.hpp>
43 #include <boost/range/value_type.hpp>
44 #include <boost/range/size_type.hpp>
45 #include <boost/range/size.hpp>
47 #include <boost/test/test_tools.hpp>
48 #include <boost/test/unit_test.hpp>
50 #include <boost/iterator/iterator_traits.hpp>
59 ///////////////////////////////////////////////////////////////////////////////
60 // dummy function object, used with algorithms
65 void operator()(T
const &t
) const
70 ///////////////////////////////////////////////////////////////////////////////
71 // dummy predicate, used with algorithms
76 bool operator()(T
const &t
) const
82 ///////////////////////////////////////////////////////////////////////////////
83 // dummy unary op, used with algorithms
88 T
const & operator()(T
const & t
) const
94 ///////////////////////////////////////////////////////////////////////////////
95 // dummy binary op, used with algorithms
99 template<typename T
,typename U
>
100 T
const & operator()(T
const & t
, U
const & u
) const
106 template<typename Rng
>
107 void test_random_algorithms(Rng
& rng
, std::random_access_iterator_tag
)
109 typedef BOOST_DEDUCED_TYPENAME
boost::range_iterator
<Rng
>::type iterator
;
111 typedef BOOST_DEDUCED_TYPENAME
boost::range_value
<Rng
>::type value_type
;
113 typedef BOOST_DEDUCED_TYPENAME
boost::range_size
<Rng
>::type
114 size_type BOOST_RANGE_UNUSED
;
116 typedef BOOST_DEDUCED_TYPENAME
boost::iterator_category
<iterator
>::type
117 iterator_category BOOST_RANGE_UNUSED
;
119 // just make sure these compile (for now)
122 boost::random_shuffle(rng
);
124 // Must be a value since random_shuffle must take the generator by
125 // reference to match the standard.
126 null_op1 rng_generator
;
127 boost::random_shuffle(rng
, rng_generator
);
130 boost::sort(rng
, std::less
<value_type
>());
132 boost::stable_sort(rng
);
133 boost::stable_sort(rng
, std::less
<value_type
>());
135 boost::partial_sort(rng
, boost::begin(rng
));
136 boost::partial_sort(rng
, boost::begin(rng
), std::less
<value_type
>());
138 boost::nth_element(rng
, boost::begin(rng
));
139 boost::nth_element(rng
, boost::begin(rng
), std::less
<value_type
>());
141 boost::push_heap(rng
);
142 boost::push_heap(rng
, std::less
<value_type
>());
144 boost::pop_heap(rng
);
145 boost::pop_heap(rng
, std::less
<value_type
>());
147 boost::make_heap(rng
);
148 boost::make_heap(rng
, std::less
<value_type
>());
150 boost::sort_heap(rng
);
151 boost::sort_heap(rng
, std::less
<value_type
>());
155 template<typename Rng
>
156 void test_random_algorithms(Rng
& rng
, std::input_iterator_tag
)
161 template<typename Rng
>
162 void test_algorithms(Rng
& rng
)
164 typedef BOOST_DEDUCED_TYPENAME
boost::range_iterator
<Rng
>::type iterator
;
165 typedef BOOST_DEDUCED_TYPENAME
boost::range_value
<Rng
>::type value_type
;
166 typedef BOOST_DEDUCED_TYPENAME
boost::range_size
<Rng
>::type size_type
;
167 typedef BOOST_DEDUCED_TYPENAME
boost::iterator_category
<iterator
>::type iterator_category
;
169 // just make sure these compile (for now)
172 value_type val
= value_type();
174 value_type rng2
[] = {value_type(),value_type(),value_type()};
175 typedef value_type
* iterator2
;
177 value_type out
[100] = {};
178 typedef value_type
* out_iterator
;
180 null_fun f
= null_fun();
181 iterator i
= iterator();
183 out_iterator o
= out_iterator();
184 size_type s
= size_type();
186 f
= boost::for_each(rng
, null_fun());
188 i
= boost::find(rng
, val
);
189 i
= boost::find_if(rng
, null_pred());
191 i
= boost::find_end(rng
, rng2
);
192 i
= boost::find_end(rng
, rng2
, std::equal_to
<value_type
>());
194 i
= boost::find_first_of(rng
, rng2
);
195 i
= boost::find_first_of(rng
, rng2
, std::equal_to
<value_type
>());
197 i
= boost::adjacent_find(rng
);
198 i
= boost::adjacent_find(rng
, std::equal_to
<value_type
>());
200 s
= boost::count(rng
, val
);
201 s
= boost::count_if(rng
, null_pred());
203 std::pair
<iterator
,iterator2
> p1
;
204 p1
= boost::mismatch(rng
, rng2
);
205 p1
= boost::mismatch(rng
, rng2
, std::equal_to
<value_type
>());
207 b
= boost::equal(rng
, rng2
);
208 b
= boost::equal(rng
, rng2
, std::equal_to
<value_type
>());
210 i
= boost::search(rng
, rng2
);
211 i
= boost::search(rng
, rng2
, std::equal_to
<value_type
>());
213 o
= boost::copy(rng
, boost::begin(out
));
214 o
= boost::copy_backward(rng
, boost::end(out
));
216 o
= boost::transform(rng
, boost::begin(out
), null_op1());
217 o
= boost::transform(rng
, rng2
, boost::begin(out
), null_op2());
219 boost::replace(rng
, val
, val
);
220 boost::replace_if(rng
, null_pred(), val
);
223 o = boost::replace_copy(rng, boost::begin(out), val, val);
224 o = boost::replace_copy_if(rng, boost::begin(out), null_pred(), val);
227 boost::fill(rng
, val
);
229 // size requires RandomAccess
231 //boost::fill_n(rng, boost::size(rng), val);
232 //boost::fill_n(rng, std::distance(boost::begin(rng),boost::end(rng)),val);
234 boost::generate(rng
, &std::rand
);
236 // size requires RandomAccess
238 //boost::generate_n(rng, boost::size(rng), &std::rand);
239 //boost::generate_n(rng,std::distance(boost::begin(rng),boost::end(rng)), &std::rand);
241 i
= boost::remove(rng
, val
);
242 i
= boost::remove_if(rng
, null_pred());
245 o = boost::remove_copy(rng, boost::begin(out), val);
246 o = boost::remove_copy_if(rng, boost::begin(out), null_pred());
249 typename
boost::range_return
<Rng
, boost::return_begin_found
>::type rrng
= boost::unique(rng
);
250 rrng
= boost::unique(rng
, std::equal_to
<value_type
>());
253 o = boost::unique_copy(rng, boost::begin(out));
254 o = boost::unique_copy(rng, boost::begin(out), std::equal_to<value_type>());
260 o = boost::reverse_copy(rng, boost::begin(out));
263 boost::rotate(rng
, boost::begin(rng
));
266 o = boost::rotate_copy(rng, boost::begin(rng), boost::begin(out));
269 i
= boost::partition(rng
, null_pred());
270 i
= boost::stable_partition(rng
, null_pred());
273 o = boost::partial_sort_copy(rng, out);
274 o = boost::partial_sort_copy(rng, out, std::less<value_type>());
277 i
= boost::lower_bound(rng
, val
);
278 i
= boost::lower_bound(rng
, val
, std::less
<value_type
>());
280 i
= boost::upper_bound(rng
, val
);
281 i
= boost::upper_bound(rng
, val
, std::less
<value_type
>());
283 std::pair
<iterator
,iterator
> p2
;
284 p2
= boost::equal_range(rng
, val
);
285 p2
= boost::equal_range(rng
, val
, std::less
<value_type
>());
287 b
= boost::binary_search(rng
, val
);
288 b
= boost::binary_search(rng
, val
, std::less
<value_type
>());
290 boost::inplace_merge(rng
, boost::begin(rng
));
291 boost::inplace_merge(rng
, boost::begin(rng
), std::less
<value_type
>());
293 b
= boost::includes(rng
, rng2
);
294 b
= boost::includes(rng
, rng2
, std::equal_to
<value_type
>());
296 o
= boost::set_union(rng
, rng2
, boost::begin(out
));
297 o
= boost::set_union(rng
, rng2
, boost::begin(out
), std::equal_to
<value_type
>());
299 o
= boost::set_intersection(rng
, rng2
, boost::begin(out
));
300 o
= boost::set_intersection(rng
, rng2
, boost::begin(out
), std::equal_to
<value_type
>());
302 o
= boost::set_difference(rng
, rng2
, boost::begin(out
));
303 o
= boost::set_difference(rng
, rng2
, boost::begin(out
), std::equal_to
<value_type
>());
305 o
= boost::set_symmetric_difference(rng
, rng2
, boost::begin(out
));
306 o
= boost::set_symmetric_difference(rng
, rng2
, boost::begin(out
), std::equal_to
<value_type
>());
308 i
= boost::min_element(rng
);
309 i
= boost::min_element(rng
, std::less
<value_type
>());
311 i
= boost::max_element(rng
);
312 i
= boost::max_element(rng
, std::less
<value_type
>());
314 b
= boost::lexicographical_compare(rng
, rng
);
315 b
= boost::lexicographical_compare(rng
, rng
, std::equal_to
<value_type
>());
317 b
= boost::next_permutation(rng
);
318 b
= boost::next_permutation(rng
, std::less
<value_type
>());
320 b
= boost::prev_permutation(rng
);
321 b
= boost::prev_permutation(rng
, std::less
<value_type
>());
323 /////////////////////////////////////////////////////////////////////
324 // numeric algorithms
325 /////////////////////////////////////////////////////////////////////
327 val
= boost::accumulate( rng
, val
);
328 val
= boost::accumulate( rng
, val
, null_op2() );
329 val
= boost::inner_product( rng
, rng
, val
);
330 val
= boost::inner_product( rng
, rng
, val
,
331 null_op2(), null_op2() );
332 o
= boost::partial_sum( rng
, boost::begin(out
) );
333 o
= boost::partial_sum( rng
, boost::begin(out
), null_op2() );
334 o
= boost::adjacent_difference( rng
, boost::begin(out
) );
335 o
= boost::adjacent_difference( rng
, boost::begin(out
),
338 boost::ignore_unused_variable_warning(b
);
342 // test the algorithms that require a random-access range
343 test_random_algorithms(rng
, iterator_category());
346 int* addr(int &i
) { return &i
; }
347 bool true_(int) { return true; }
349 ///////////////////////////////////////////////////////////////////////////////
352 void simple_compile_test()
355 typedef ::boost::counting_iterator
<int> int_iterator
;
357 // define come containers
358 std::list
<int> my_list(int_iterator(1),int_iterator(6));
361 std::vector
<int> my_vector(int_iterator(1),int_iterator(6));
363 std::pair
<std::vector
<int>::iterator
,std::vector
<int>::iterator
> my_pair(my_vector
.begin(),my_vector
.end());
365 // test the algorithms with list and const list
366 test_algorithms(my_list
);
367 test_algorithms(my_vector
);
368 test_algorithms(my_pair
);
372 std::vector
<int>& cv
= v
;
374 using namespace boost
;
376 #define BOOST_RANGE_RETURNS_TEST( function_name, cont ) \
377 function_name (cont); \
378 function_name <return_found> (cont); \
379 function_name <return_next> (cont); \
380 function_name <return_prior> (cont); \
381 function_name <return_begin_found> (cont); \
382 function_name <return_begin_next> (cont); \
383 function_name <return_begin_prior> (cont); \
384 function_name <return_found_end> (cont); \
385 function_name <return_next_end>(cont); \
386 function_name <return_prior_end>(cont);
388 BOOST_RANGE_RETURNS_TEST( adjacent_find
, cv
);
389 BOOST_RANGE_RETURNS_TEST( adjacent_find
, v
);
390 BOOST_RANGE_RETURNS_TEST( max_element
, cv
);
391 BOOST_RANGE_RETURNS_TEST( max_element
, v
);
392 BOOST_RANGE_RETURNS_TEST( min_element
, cv
);
393 BOOST_RANGE_RETURNS_TEST( min_element
, v
);
394 BOOST_RANGE_RETURNS_TEST( unique
, v
);
395 #undef BOOST_RANGE_RETURNS_TEST
397 #define BOOST_RANGE_RETURNS_TEST1( function_name, cont, arg1 ) \
398 function_name (cont, arg1); \
399 function_name <return_found> (cont, arg1); \
400 function_name <return_next> (cont, arg1); \
401 function_name <return_prior> (cont, arg1); \
402 function_name <return_begin_found> (cont, arg1); \
403 function_name <return_begin_next> (cont, arg1); \
404 function_name <return_begin_prior> (cont, arg1); \
405 function_name <return_found_end> (cont, arg1); \
406 function_name <return_next_end>(cont, arg1); \
407 function_name <return_prior_end>(cont, arg1);
409 BOOST_RANGE_RETURNS_TEST1( adjacent_find
, cv
, std::less
<int>() );
410 BOOST_RANGE_RETURNS_TEST1( adjacent_find
, v
, std::less
<int>() );
411 BOOST_RANGE_RETURNS_TEST1( find
, cv
, 0 );
412 BOOST_RANGE_RETURNS_TEST1( find
, v
, 0 );
413 BOOST_RANGE_RETURNS_TEST1( find_end
, cv
, cv
);
414 BOOST_RANGE_RETURNS_TEST1( find_end
, cv
, v
);
415 BOOST_RANGE_RETURNS_TEST1( find_end
, v
, cv
);
416 BOOST_RANGE_RETURNS_TEST1( find_end
, v
, v
);
417 BOOST_RANGE_RETURNS_TEST1( find_first_of
, cv
, cv
);
418 BOOST_RANGE_RETURNS_TEST1( find_first_of
, cv
, v
);
419 BOOST_RANGE_RETURNS_TEST1( find_first_of
, v
, cv
);
420 BOOST_RANGE_RETURNS_TEST1( find_first_of
, v
, v
);
421 BOOST_RANGE_RETURNS_TEST1( find_if
, cv
, std::negate
<int>() );
422 BOOST_RANGE_RETURNS_TEST1( find_if
, v
, std::negate
<int>() );
423 BOOST_RANGE_RETURNS_TEST1( search
, cv
, cv
);
424 BOOST_RANGE_RETURNS_TEST1( search
, cv
, v
);
425 BOOST_RANGE_RETURNS_TEST1( search
, v
, cv
);
426 BOOST_RANGE_RETURNS_TEST1( search
, v
, v
);
428 BOOST_RANGE_RETURNS_TEST1( remove
, v
, 0 );
429 BOOST_RANGE_RETURNS_TEST1( remove_if
, v
, std::negate
<int>() );
431 BOOST_RANGE_RETURNS_TEST1( lower_bound
, cv
, 0 );
432 BOOST_RANGE_RETURNS_TEST1( lower_bound
, v
, 0 );
433 BOOST_RANGE_RETURNS_TEST1( max_element
, cv
, std::less
<int>() );
434 BOOST_RANGE_RETURNS_TEST1( max_element
, v
, std::less
<int>() );
435 BOOST_RANGE_RETURNS_TEST1( min_element
, cv
, std::less
<int>() );
436 BOOST_RANGE_RETURNS_TEST1( min_element
, v
, std::less
<int>() );
437 BOOST_RANGE_RETURNS_TEST1( upper_bound
, cv
, 0 );
438 BOOST_RANGE_RETURNS_TEST1( upper_bound
, v
, 0 );
439 BOOST_RANGE_RETURNS_TEST1( partition
, cv
, std::negate
<int>() );
440 BOOST_RANGE_RETURNS_TEST1( partition
, v
, std::negate
<int>() );
441 BOOST_RANGE_RETURNS_TEST1( stable_partition
, cv
, std::negate
<int>() );
442 BOOST_RANGE_RETURNS_TEST1( stable_partition
, v
, std::negate
<int>() );
444 #undef BOOST_RANGE_RETURNS_TEST1
446 #define BOOST_RANGE_RETURNS_TEST2( function_name, arg1, arg2 ) \
447 function_name (v, arg1, arg2); \
448 function_name <return_found> (v, arg1, arg2); \
449 function_name <return_next> (v, arg1, arg2); \
450 function_name <return_prior> (v, arg1, arg2); \
451 function_name <return_begin_found> (v, arg1, arg2); \
452 function_name <return_begin_next> (v, arg1, arg2); \
453 function_name <return_begin_prior> (v, arg1, arg2); \
454 function_name <return_found_end> (v, arg1, arg2); \
455 function_name <return_next_end>(v, arg1, arg2); \
456 function_name <return_prior_end>(v, arg1, arg2);
458 BOOST_RANGE_RETURNS_TEST2( find_end
, v
, std::less
<int>() );
459 BOOST_RANGE_RETURNS_TEST2( find_first_of
, v
, std::less
<int>() );
460 BOOST_RANGE_RETURNS_TEST2( boost::search
, v
, std::less
<int>() );
461 BOOST_RANGE_RETURNS_TEST2( lower_bound
, 0, std::less
<int>() );
462 BOOST_RANGE_RETURNS_TEST2( upper_bound
, 0, std::less
<int>() );
464 #undef BOOST_RANGE_RETURNS_TEST2
467 using boost::unit_test::test_suite
;
469 test_suite
* init_unit_test_suite( int argc
, char* argv
[] )
471 using namespace boost
;
473 test_suite
* test
= BOOST_TEST_SUITE( "Range Test Suite - Algorithm" );
475 test
->add( BOOST_TEST_CASE( &simple_compile_test
) );