• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
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>
check_result(Container1 & reference,Iterator reference_result,Container2 & test_cont,Iterator test_result)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>
test(Container1 & cont1,Container2 & cont2)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>
sort_container(Container & cont,BinaryPredicate pred)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>
test_pred(Container1 cont1,Container2 cont2,BinaryPredicate pred)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>
test_set_intersection_impl(Container1 & cont1,Container2 & cont2)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>
test_set_intersection_impl()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 
test_set_intersection()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*
init_unit_test_suite(int argc,char * argv[])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 }
214