1c0dbc317cf3e5be1ea32d40ff4f2c0827364577
[platform/upstream/boost.git] / libs / range / test / algorithm.cpp
1 // Boost.Range library
2 //
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)
7 //
8 // For more information, see http://www.boost.org/libs/range/
9 //
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)
14
15 /*
16  Revision history:
17    13 December 2004 : Initial version.
18 */
19
20 #ifdef _MSC_VER
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
24 #endif
25
26 #ifdef _MSC_VER
27     // counting_iterator generates a warning about truncating an integer
28     #pragma warning(push)
29     #pragma warning(disable : 4244)
30 #endif
31 #include <boost/iterator/counting_iterator.hpp>
32 #ifdef _MSC_VER
33     template ::boost::counting_iterator<int>;
34     #pragma warning(pop)
35 #endif
36
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>
45
46 #include <boost/test/test_tools.hpp>
47 #include <boost/test/unit_test.hpp>
48
49 #include <boost/iterator/iterator_traits.hpp>
50
51 #include <algorithm>
52 #include <cstdlib>
53 #include <set>
54 #include <list>
55 #include <vector>
56 #include <iterator>
57 #include <functional>
58 ///////////////////////////////////////////////////////////////////////////////
59 // dummy function object, used with algorithms
60 //
61 struct null_fun
62 {
63     template<typename T>
64         void operator()(T const &t) const
65     {
66     }
67 };
68
69 ///////////////////////////////////////////////////////////////////////////////
70 // dummy predicate, used with algorithms
71 //
72 struct null_pred
73 {
74     template<typename T>
75     bool operator()(T const &t) const
76     {
77         return t == T();
78     }
79 };
80
81 ///////////////////////////////////////////////////////////////////////////////
82 // dummy unary op, used with algorithms
83 //
84 struct null_op1
85 {
86     template<typename T>
87     T const & operator()(T const & t) const
88     {
89         return t;
90     }
91 };
92
93 ///////////////////////////////////////////////////////////////////////////////
94 // dummy binary op, used with algorithms
95 //
96 struct null_op2
97 {
98     template<typename T,typename U>
99     T const & operator()(T const & t, U const & u) const
100     {
101         return t;
102     }
103 };
104
105 template<typename Rng>
106 void test_random_algorithms(Rng & rng, std::random_access_iterator_tag)
107 {
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;
112
113     // just make sure these compile (for now)
114     if(0)
115     {
116         boost::random_shuffle(rng);
117
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);
122
123         boost::sort(rng);
124         boost::sort(rng, std::less<value_type>());
125
126         boost::stable_sort(rng);
127         boost::stable_sort(rng, std::less<value_type>());
128
129         boost::partial_sort(rng, boost::begin(rng));
130         boost::partial_sort(rng, boost::begin(rng), std::less<value_type>());
131
132         boost::nth_element(rng, boost::begin(rng));
133         boost::nth_element(rng, boost::begin(rng), std::less<value_type>());
134
135         boost::push_heap(rng);
136         boost::push_heap(rng, std::less<value_type>());
137
138         boost::pop_heap(rng);
139         boost::pop_heap(rng, std::less<value_type>());
140
141         boost::make_heap(rng);
142         boost::make_heap(rng, std::less<value_type>());
143
144         boost::sort_heap(rng);
145         boost::sort_heap(rng, std::less<value_type>());
146     }
147 }
148
149 template<typename Rng>
150 void test_random_algorithms(Rng & rng, std::input_iterator_tag)
151 {
152     // no-op
153 }
154
155 template<typename Rng>
156 void test_algorithms(Rng & rng)
157 {
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;
162
163     // just make sure these compile (for now)
164     if(0)
165     {
166         value_type val = value_type();
167
168         value_type rng2[] = {value_type(),value_type(),value_type()};
169         typedef value_type* iterator2;
170
171         value_type out[100] = {};
172         typedef value_type* out_iterator;
173
174         null_fun f = null_fun();
175         iterator i = iterator();
176         bool b = bool();
177         out_iterator o = out_iterator();
178         size_type s = size_type();
179
180         f = boost::for_each(rng, null_fun());
181
182         i = boost::find(rng, val);
183         i = boost::find_if(rng, null_pred());
184
185         i = boost::find_end(rng, rng2);
186         i = boost::find_end(rng, rng2, std::equal_to<value_type>());
187
188         i = boost::find_first_of(rng, rng2);
189         i = boost::find_first_of(rng, rng2, std::equal_to<value_type>());
190
191         i = boost::adjacent_find(rng);
192         i = boost::adjacent_find(rng, std::equal_to<value_type>());
193
194         s = boost::count(rng, val);
195         s = boost::count_if(rng, null_pred());
196
197         std::pair<iterator,iterator2> p1;
198         p1 = boost::mismatch(rng, rng2);
199         p1 = boost::mismatch(rng, rng2, std::equal_to<value_type>());
200
201         b = boost::equal(rng, rng2);
202         b = boost::equal(rng, rng2, std::equal_to<value_type>());
203
204         i = boost::search(rng, rng2);
205         i = boost::search(rng, rng2, std::equal_to<value_type>());
206
207         o = boost::copy(rng, boost::begin(out));
208         o = boost::copy_backward(rng, boost::end(out));
209
210         o = boost::transform(rng, boost::begin(out), null_op1());
211         o = boost::transform(rng, rng2, boost::begin(out), null_op2());
212
213         boost::replace(rng, val, val);
214         boost::replace_if(rng, null_pred(), val);
215
216 /*
217         o = boost::replace_copy(rng, boost::begin(out), val, val);
218         o = boost::replace_copy_if(rng, boost::begin(out), null_pred(), val);
219 */
220
221         boost::fill(rng, val);
222         //
223         // size requires RandomAccess
224         //
225         //boost::fill_n(rng, boost::size(rng), val);
226         //boost::fill_n(rng, std::distance(boost::begin(rng),boost::end(rng)),val);
227
228         boost::generate(rng, &std::rand);
229         //
230         // size requires RandomAccess   
231         //
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);
234
235         i = boost::remove(rng, val);
236         i = boost::remove_if(rng, null_pred());
237
238 /*
239         o = boost::remove_copy(rng, boost::begin(out), val);
240         o = boost::remove_copy_if(rng, boost::begin(out), null_pred());
241 */
242
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>());
245
246 /*
247         o = boost::unique_copy(rng, boost::begin(out));
248         o = boost::unique_copy(rng, boost::begin(out), std::equal_to<value_type>());
249 */
250
251         boost::reverse(rng);
252
253 /*
254         o = boost::reverse_copy(rng, boost::begin(out));
255 */
256
257         boost::rotate(rng, boost::begin(rng));
258
259 /*
260         o = boost::rotate_copy(rng, boost::begin(rng), boost::begin(out));
261 */
262
263         i = boost::partition(rng, null_pred());
264         i = boost::stable_partition(rng, null_pred());
265
266 /*
267         o = boost::partial_sort_copy(rng, out);
268         o = boost::partial_sort_copy(rng, out, std::less<value_type>());
269 */
270
271         i = boost::lower_bound(rng, val);
272         i = boost::lower_bound(rng, val, std::less<value_type>());
273
274         i = boost::upper_bound(rng, val);
275         i = boost::upper_bound(rng, val, std::less<value_type>());
276
277         std::pair<iterator,iterator> p2;
278         p2 = boost::equal_range(rng, val);
279         p2 = boost::equal_range(rng, val, std::less<value_type>());
280
281         b = boost::binary_search(rng, val);
282         b = boost::binary_search(rng, val, std::less<value_type>());
283
284         boost::inplace_merge(rng, boost::begin(rng));
285         boost::inplace_merge(rng, boost::begin(rng), std::less<value_type>());
286
287         b = boost::includes(rng, rng2);
288         b = boost::includes(rng, rng2, std::equal_to<value_type>());
289
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>());
292
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>());
295
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>());
298
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>());
301
302         i = boost::min_element(rng);
303         i = boost::min_element(rng, std::less<value_type>());
304
305         i = boost::max_element(rng);
306         i = boost::max_element(rng, std::less<value_type>());
307
308         b = boost::lexicographical_compare(rng, rng);
309         b = boost::lexicographical_compare(rng, rng, std::equal_to<value_type>());
310
311         b = boost::next_permutation(rng);
312         b = boost::next_permutation(rng, std::less<value_type>());
313
314         b = boost::prev_permutation(rng);
315         b = boost::prev_permutation(rng, std::less<value_type>());
316
317         /////////////////////////////////////////////////////////////////////
318         // numeric algorithms
319         /////////////////////////////////////////////////////////////////////
320
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), 
330                                           null_op2() );
331          
332     }
333
334     // test the algorithms that require a random-access range
335     test_random_algorithms(rng, iterator_category());
336 }
337
338 int* addr(int &i) { return &i; }
339 bool true_(int) { return true; }
340
341 ///////////////////////////////////////////////////////////////////////////////
342 // test_main
343 //   
344 void simple_compile_test()
345 {
346     // int_iterator
347     typedef ::boost::counting_iterator<int> int_iterator;
348
349     // define come containers
350     std::list<int> my_list(int_iterator(1),int_iterator(6));
351
352
353     std::vector<int> my_vector(int_iterator(1),int_iterator(6));
354
355     std::pair<std::vector<int>::iterator,std::vector<int>::iterator> my_pair(my_vector.begin(),my_vector.end());
356
357     // test the algorithms with list and const list
358     test_algorithms(my_list);
359     test_algorithms(my_vector);
360     test_algorithms(my_pair);
361
362     
363     std::vector<int> v;
364     std::vector<int>& cv = v;
365
366     using namespace boost;
367
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);
379
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
388
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);
400
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 );
419
420     BOOST_RANGE_RETURNS_TEST1( remove, v, 0 );
421     BOOST_RANGE_RETURNS_TEST1( remove_if, v, std::negate<int>() );
422
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>() );
435
436 #undef BOOST_RANGE_RETURNS_TEST1
437
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);
449
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>() );
455
456 #undef BOOST_RANGE_RETURNS_TEST2
457 }
458
459 using boost::unit_test::test_suite;
460
461 test_suite* init_unit_test_suite( int argc, char* argv[] )
462 {
463     using namespace boost;
464
465     test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - Algorithm" );
466
467     test->add( BOOST_TEST_CASE( &simple_compile_test ) );
468
469     return test;
470 }
471