1 | /* |
2 | Copyright (c) Marshall Clow 2011-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 <iostream> |
11 | |
12 | #include <boost/config.hpp> |
13 | #include <boost/algorithm/gather.hpp> |
14 | |
15 | #define BOOST_TEST_MAIN |
16 | #include <boost/test/unit_test.hpp> |
17 | |
18 | #include <string> |
19 | #include <vector> |
20 | #include <list> |
21 | |
22 | #include "iterator_test.hpp" |
23 | |
24 | namespace ba = boost::algorithm; |
25 | |
26 | template <typename Container> |
27 | void print ( const char *prompt, const Container &c ) { |
28 | std::cout << prompt << " { " ; |
29 | std::copy ( c.begin (), c.end (), std::ostream_iterator<typename Container::value_type>(std::cout, " " )); |
30 | std::cout << std::endl; |
31 | } |
32 | |
33 | template <typename Iterator, typename Predicate> |
34 | void test_iterators ( Iterator first, Iterator last, Predicate comp, std::size_t offset ) { |
35 | // Create the pivot point |
36 | Iterator off = first; |
37 | std::advance(off, offset); |
38 | |
39 | // Gather the elements |
40 | std::pair<Iterator, Iterator> res = ba::gather ( first, last, off, comp ); |
41 | |
42 | // We should now have three sequences, any of which may be empty: |
43 | // * [begin .. result.first) - items that do not satisfy the predicate |
44 | // * [result.first .. result.second) - items that do satisfy the predicate |
45 | // * [result.second .. end) - items that do not satisfy the predicate |
46 | Iterator iter = first; |
47 | for ( ; iter != res.first; ++iter ) |
48 | BOOST_CHECK ( !comp ( *iter )); |
49 | for ( ; iter != res.second; ++iter) |
50 | BOOST_CHECK ( comp ( *iter )); |
51 | for ( ; iter != last; ++iter ) |
52 | BOOST_CHECK ( !comp ( *iter )); |
53 | } |
54 | |
55 | template <typename Container, typename Predicate> |
56 | void test_iterator_types ( const Container &c, Predicate comp, std::size_t offset ) { |
57 | typedef std::vector<typename Container::value_type> vec; |
58 | |
59 | typedef bidirectional_iterator<typename vec::iterator> BDI; |
60 | typedef random_access_iterator<typename vec::iterator> RAI; |
61 | |
62 | vec v; |
63 | v.assign ( c.begin (), c.end ()); |
64 | test_iterators ( BDI ( v.begin ()), BDI ( v.end ()), comp, offset ); |
65 | v.assign ( c.begin (), c.end ()); |
66 | test_iterators ( RAI ( v.begin ()), RAI ( v.end ()), comp, offset ); |
67 | } |
68 | |
69 | |
70 | template <typename T> |
71 | struct less_than { |
72 | public: |
73 | // typedef T argument_type; |
74 | // typedef bool result_type; |
75 | |
76 | less_than ( T foo ) : val ( foo ) {} |
77 | less_than ( const less_than &rhs ) : val ( rhs.val ) {} |
78 | |
79 | bool operator () ( const T &v ) const { return v < val; } |
80 | private: |
81 | less_than (); |
82 | less_than operator = ( const less_than &rhs ); |
83 | T val; |
84 | }; |
85 | |
86 | bool is_even ( int i ) { return i % 2 == 0; } |
87 | bool is_ten ( int i ) { return i == 10; } |
88 | |
89 | void test_sequence1 () { |
90 | std::vector<int> v; |
91 | |
92 | for ( int i = 5; i < 15; ++i ) |
93 | v.push_back ( x: i ); |
94 | test_iterator_types ( c: v, comp: less_than<int>(10), offset: 0 ); // at beginning |
95 | test_iterator_types ( c: v, comp: less_than<int>(10), offset: 5 ); |
96 | test_iterator_types ( c: v, comp: less_than<int>(10), offset: v.size () - 1 ); // at end |
97 | |
98 | test_iterator_types ( c: v, comp: is_even, offset: 0 ); |
99 | test_iterator_types ( c: v, comp: is_even, offset: 5 ); |
100 | test_iterator_types ( c: v, comp: is_even, offset: v.size () - 1 ); |
101 | |
102 | // Exactly one element in the sequence matches |
103 | test_iterator_types ( c: v, comp: is_ten, offset: 0 ); |
104 | test_iterator_types ( c: v, comp: is_ten, offset: 5 ); |
105 | test_iterator_types ( c: v, comp: is_ten, offset: v.size () - 1 ); |
106 | |
107 | // Everything in the sequence matches |
108 | test_iterator_types ( c: v, comp: less_than<int>(99), offset: 0 ); |
109 | test_iterator_types ( c: v, comp: less_than<int>(99), offset: 5 ); |
110 | test_iterator_types ( c: v, comp: less_than<int>(99), offset: v.size () - 1 ); |
111 | |
112 | // Nothing in the sequence matches |
113 | test_iterator_types ( c: v, comp: less_than<int>(0), offset: 0 ); |
114 | test_iterator_types ( c: v, comp: less_than<int>(0), offset: 5 ); |
115 | test_iterator_types ( c: v, comp: less_than<int>(0), offset: v.size () - 1 ); |
116 | |
117 | // All the elements in the sequence are the same |
118 | v.clear (); |
119 | for ( int i = 0; i < 11; ++i ) |
120 | v.push_back ( x: 10 ); |
121 | |
122 | // Everything in the sequence matches |
123 | test_iterator_types ( c: v, comp: is_ten, offset: 0 ); |
124 | test_iterator_types ( c: v, comp: is_ten, offset: 5 ); |
125 | test_iterator_types ( c: v, comp: is_ten, offset: v.size () - 1 ); |
126 | |
127 | // Nothing in the sequence matches |
128 | test_iterator_types ( c: v, comp: less_than<int>(5), offset: 0 ); |
129 | test_iterator_types ( c: v, comp: less_than<int>(5), offset: 5 ); |
130 | test_iterator_types ( c: v, comp: less_than<int>(5), offset: v.size () - 1 ); |
131 | |
132 | } |
133 | |
134 | |
135 | BOOST_AUTO_TEST_CASE( test_main ) |
136 | { |
137 | test_sequence1 (); |
138 | } |
139 | |