]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright Neil Groves 2009. Use, modification and |
2 | // distribution is subject to the Boost Software License, Version | |
3 | // 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
4 | // http://www.boost.org/LICENSE_1_0.txt) | |
5 | // | |
6 | // | |
7 | // For more information, see http://www.boost.org/libs/range/ | |
8 | // | |
9 | #include <boost/range/algorithm/set_algorithm.hpp> | |
10 | ||
11 | #include <boost/test/test_tools.hpp> | |
12 | #include <boost/test/unit_test.hpp> | |
13 | ||
14 | #include <boost/assign.hpp> | |
7c673cae FG |
15 | #include <algorithm> |
16 | #include <functional> | |
17 | #include <list> | |
18 | #include <numeric> | |
19 | #include <deque> | |
20 | #include <vector> | |
21 | ||
22 | namespace boost | |
23 | { | |
24 | namespace | |
25 | { | |
26 | template<class Container1, class Iterator, class Container2> | |
27 | void check_result( | |
28 | Container1& reference, | |
29 | Iterator reference_result, | |
30 | Container2& test_cont, | |
31 | Iterator test_result | |
32 | ) | |
33 | { | |
34 | BOOST_CHECK_EQUAL( | |
35 | std::distance<Iterator>(reference.begin(), reference_result), | |
36 | std::distance<Iterator>(test_cont.begin(), test_result) | |
37 | ); | |
38 | ||
39 | BOOST_CHECK_EQUAL_COLLECTIONS( | |
40 | reference.begin(), reference.end(), | |
41 | test_cont.begin(), test_cont.end() | |
42 | ); | |
43 | } | |
44 | ||
45 | template<class Container1, class Container2> | |
46 | void test(Container1& cont1, Container2& cont2) | |
47 | { | |
48 | typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t; | |
49 | typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t; | |
50 | ||
51 | std::vector<value_t> reference(cont1.size() + cont2.size()); | |
52 | std::vector<value_t> test_cont(reference); | |
53 | ||
54 | iterator_t reference_result | |
55 | = std::set_intersection(cont1.begin(), cont1.end(), | |
56 | cont2.begin(), cont2.end(), | |
57 | reference.begin()); | |
58 | ||
59 | iterator_t test_result | |
60 | = boost::set_intersection(cont1, cont2, test_cont.begin()); | |
61 | ||
62 | check_result(reference, reference_result, | |
63 | test_cont, test_result); | |
64 | ||
65 | test_result = boost::set_intersection( | |
66 | boost::make_iterator_range(cont1), cont2, | |
67 | test_cont.begin()); | |
68 | ||
69 | check_result(reference, reference_result, | |
70 | test_cont, test_result); | |
71 | ||
72 | test_result = boost::set_intersection( | |
73 | cont1, boost::make_iterator_range(cont2), | |
74 | test_cont.begin()); | |
75 | ||
76 | check_result(reference, reference_result, | |
77 | test_cont, test_result); | |
78 | ||
79 | test_result = boost::set_intersection( | |
80 | boost::make_iterator_range(cont1), | |
81 | boost::make_iterator_range(cont2), | |
82 | test_cont.begin()); | |
83 | ||
84 | check_result(reference, reference_result, | |
85 | test_cont, test_result); | |
86 | } | |
87 | ||
88 | template<class Container, class BinaryPredicate> | |
89 | void sort_container(Container& cont, BinaryPredicate pred) | |
90 | { | |
91 | typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; | |
92 | ||
93 | std::vector<value_t> temp(cont.begin(), cont.end()); | |
94 | std::sort(temp.begin(), temp.end(), pred); | |
95 | cont.assign(temp.begin(), temp.end()); | |
96 | } | |
97 | ||
98 | template<class Container1, | |
99 | class Container2, | |
100 | class BinaryPredicate> | |
101 | void test_pred(Container1 cont1, Container2 cont2, | |
102 | BinaryPredicate pred) | |
103 | { | |
104 | typedef BOOST_DEDUCED_TYPENAME Container1::value_type value_t; | |
105 | typedef BOOST_DEDUCED_TYPENAME std::vector<value_t>::iterator iterator_t; | |
106 | ||
107 | sort_container(cont1, pred); | |
108 | sort_container(cont2, pred); | |
109 | ||
110 | std::vector<value_t> reference(cont1.size() + cont2.size()); | |
111 | std::vector<value_t> test_cont(reference); | |
112 | ||
113 | iterator_t reference_result | |
114 | = std::set_intersection(cont1.begin(), cont1.end(), | |
115 | cont2.begin(), cont2.end(), | |
116 | reference.begin(), | |
117 | pred); | |
118 | ||
119 | iterator_t test_result | |
120 | = boost::set_intersection(cont1, cont2, test_cont.begin(), pred); | |
121 | ||
122 | check_result(reference, reference_result, | |
123 | test_cont, test_result); | |
124 | ||
125 | test_result = boost::set_intersection( | |
126 | boost::make_iterator_range(cont1), cont2, | |
127 | test_cont.begin(), pred); | |
128 | ||
129 | check_result(reference, reference_result, | |
130 | test_cont, test_result); | |
131 | ||
132 | test_result = boost::set_intersection( | |
133 | cont1, boost::make_iterator_range(cont2), | |
134 | test_cont.begin(), pred); | |
135 | ||
136 | check_result(reference, reference_result, | |
137 | test_cont, test_result); | |
138 | ||
139 | test_result = boost::set_intersection( | |
140 | boost::make_iterator_range(cont1), | |
141 | boost::make_iterator_range(cont2), | |
142 | test_cont.begin(), pred); | |
143 | ||
144 | check_result(reference, reference_result, | |
145 | test_cont, test_result); | |
146 | } | |
147 | ||
148 | template<class Container1, class Container2> | |
149 | void test_set_intersection_impl( | |
150 | Container1& cont1, | |
151 | Container2& cont2 | |
152 | ) | |
153 | { | |
154 | test(cont1, cont2); | |
155 | test_pred(cont1, cont2, std::less<int>()); | |
156 | test_pred(cont1, cont2, std::greater<int>()); | |
157 | } | |
158 | ||
159 | template<class Container1, class Container2> | |
160 | void test_set_intersection_impl() | |
161 | { | |
162 | using namespace boost::assign; | |
163 | ||
164 | Container1 cont1; | |
165 | Container2 cont2; | |
166 | ||
167 | test_set_intersection_impl(cont1, cont2); | |
168 | ||
169 | cont1.clear(); | |
170 | cont2.clear(); | |
171 | cont1 += 1; | |
172 | test_set_intersection_impl(cont1, cont2); | |
173 | ||
174 | cont1.clear(); | |
175 | cont2.clear(); | |
176 | cont2 += 1; | |
177 | test_set_intersection_impl(cont1, cont2); | |
178 | ||
179 | cont1.clear(); | |
180 | cont2.clear(); | |
181 | cont1 += 1,2,3,4,5,6,7,8,9; | |
182 | cont2 += 2,3,4; | |
183 | test_set_intersection_impl(cont1, cont2); | |
184 | ||
185 | cont1.clear(); | |
186 | cont2.clear(); | |
187 | cont1 += 2,3,4; | |
188 | cont2 += 1,2,3,4,5,6,7,8,9; | |
189 | test_set_intersection_impl(cont1, cont2); | |
190 | } | |
191 | ||
192 | void test_set_intersection() | |
193 | { | |
194 | test_set_intersection_impl< std::vector<int>, std::vector<int> >(); | |
195 | test_set_intersection_impl< std::list<int>, std::list<int> >(); | |
196 | test_set_intersection_impl< std::deque<int>, std::deque<int> >(); | |
197 | test_set_intersection_impl< std::vector<int>, std::list<int> >(); | |
198 | test_set_intersection_impl< std::list<int>, std::vector<int> >(); | |
199 | } | |
200 | } | |
201 | } | |
202 | ||
203 | ||
204 | boost::unit_test::test_suite* | |
205 | init_unit_test_suite(int argc, char* argv[]) | |
206 | { | |
207 | boost::unit_test::test_suite* test | |
208 | = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.set_intersection" ); | |
209 | ||
210 | test->add( BOOST_TEST_CASE( &boost::test_set_intersection ) ); | |
211 | ||
212 | return test; | |
213 | } |