• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Range library
2 //
3 //  Copyright Neil Groves 2009. 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 //
9 // For more information, see http://www.boost.org/libs/range/
10 //
11 #include <boost/range/algorithm/find_first_of.hpp>
12 
13 #include <boost/test/test_tools.hpp>
14 #include <boost/test/unit_test.hpp>
15 
16 #include <boost/assign.hpp>
17 #include "../test_driver/range_return_test_driver.hpp"
18 #include <algorithm>
19 #include <functional>
20 #include <vector>
21 #include <set>
22 #include <list>
23 
24 namespace boost_range_test_algorithm_find_first_of
25 {
26     template<class Container2>
27     class find_first_of_test_policy
28     {
29         typedef Container2 container2_t;
30     public:
find_first_of_test_policy(const Container2 & cont)31         explicit find_first_of_test_policy(const Container2& cont)
32             :   m_cont(cont)
33         {
34         }
35 
cont()36         container2_t& cont() { return m_cont; }
37 
38         template<class Container>
39         BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
test_iter(Container & cont)40         test_iter(Container& cont)
41         {
42             typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
43             iter_t result = boost::find_first_of(cont, m_cont);
44             BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), m_cont) );
45             BOOST_CHECK( result == boost::find_first_of(cont, boost::make_iterator_range(m_cont)) );
46             BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont)) );
47             return result;
48         }
49 
50         template<boost::range_return_value return_type>
51         struct test_range
52         {
53             template<class Container, class Policy>
54             BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
operator ()boost_range_test_algorithm_find_first_of::find_first_of_test_policy::test_range55             operator()(Policy& policy, Container& cont)
56             {
57                 typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
58                 result_t result = boost::find_first_of<return_type>(cont, policy.cont());
59                 BOOST_CHECK( result == boost::find_first_of<return_type>(boost::make_iterator_range(cont), policy.cont()) );
60                 BOOST_CHECK( result == boost::find_first_of<return_type>(cont, boost::make_iterator_range(policy.cont())) );
61                 BOOST_CHECK( result == boost::find_first_of<return_type>(boost::make_iterator_range(cont), boost::make_iterator_range(policy.cont())) );
62                 return result;
63             }
64         };
65 
66         template<class Container>
67         BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
reference(Container & cont)68         reference(Container& cont)
69         {
70             return std::find_first_of(cont.begin(), cont.end(),
71                                  m_cont.begin(), m_cont.end());
72         }
73 
74     private:
75         Container2 m_cont;
76     };
77 
78     template<class Container2, class BinaryPredicate>
79     class find_first_of_pred_test_policy
80     {
81         typedef Container2 container2_t;
82     public:
find_first_of_pred_test_policy(const Container2 & cont)83         explicit find_first_of_pred_test_policy(const Container2& cont)
84             :   m_cont(cont)
85         {
86         }
87 
cont()88         container2_t& cont() { return m_cont; }
pred()89         BinaryPredicate& pred() { return m_pred; }
90 
91         template<class Container>
92         BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
test_iter(Container & cont)93         test_iter(Container& cont)
94         {
95             typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
96             iter_t result = boost::find_first_of(cont, m_cont, m_pred);
97             BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), m_cont, m_pred) );
98             BOOST_CHECK( result == boost::find_first_of(cont, boost::make_iterator_range(m_cont), m_pred) );
99             BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont), m_pred) );
100             return result;
101         }
102 
103         template<boost::range_return_value return_type>
104         struct test_range
105         {
106             template<class Container, class Policy>
107             BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
operator ()boost_range_test_algorithm_find_first_of::find_first_of_pred_test_policy::test_range108             operator()(Policy& policy, Container& cont)
109             {
110                 typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
111                 result_t result = boost::find_first_of<return_type>(cont, policy.cont(), policy.pred());
112                 BOOST_CHECK( result == boost::find_first_of<return_type>(boost::make_iterator_range(cont), policy.cont(), policy.pred()) );
113                 BOOST_CHECK( result == boost::find_first_of<return_type>(cont, boost::make_iterator_range(policy.cont()), policy.pred()) );
114                 BOOST_CHECK( result == boost::find_first_of<return_type>(boost::make_iterator_range(cont), boost::make_iterator_range(policy.cont()), policy.pred()) );
115                 return result;
116             }
117         };
118 
119         template<class Container>
120         BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
reference(Container & cont)121         reference(Container& cont)
122         {
123             return std::find_first_of(cont.begin(), cont.end(),
124                                       m_cont.begin(), m_cont.end(),
125                                       m_pred);
126         }
127 
128     private:
129         Container2      m_cont;
130         BinaryPredicate m_pred;
131     };
132 
133     template<class Container1, class Container2>
run_tests(Container1 & cont1,Container2 & cont2)134     void run_tests(Container1& cont1, Container2& cont2)
135     {
136         boost::range_test::range_return_test_driver test_driver;
137         test_driver(cont1, find_first_of_test_policy<Container2>(cont2));
138         test_driver(cont1, find_first_of_pred_test_policy<Container2, std::less<int> >(cont2));
139         test_driver(cont2, find_first_of_pred_test_policy<Container2, std::greater<int> >(cont2));
140     }
141 
142     template<class Container1, class Container2>
test_find_first_of_impl()143     void test_find_first_of_impl()
144     {
145         using namespace boost::assign;
146 
147         typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container1>::type container1_t;
148         typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container2>::type container2_t;
149 
150         container1_t mcont1;
151         Container1& cont1 = mcont1;
152         container2_t mcont2;
153         Container2& cont2 = mcont2;
154 
155         run_tests(cont1, cont2);
156 
157         mcont1 += 1;
158         run_tests(cont1, cont2);
159 
160         mcont2 += 1;
161         run_tests(cont1, cont2);
162 
163         mcont1 += 2,3,4,5,6,7,8,9;
164         mcont2 += 2,3,4;
165         run_tests(cont1, cont2);
166 
167         mcont2.clear();
168         mcont2 += 7,8,9;
169         run_tests(cont1, cont2);
170     }
171 
test_find_first_of()172     void test_find_first_of()
173     {
174         test_find_first_of_impl< std::vector<int>, std::vector<int> >();
175         test_find_first_of_impl< std::list<int>, std::list<int> >();
176         test_find_first_of_impl< std::deque<int>, std::deque<int> >();
177         test_find_first_of_impl< const std::vector<int>, const std::vector<int> >();
178         test_find_first_of_impl< const std::list<int>, const std::list<int> >();
179         test_find_first_of_impl< const std::deque<int>, const std::deque<int> >();
180         test_find_first_of_impl< const std::vector<int>, const std::list<int> >();
181         test_find_first_of_impl< const std::list<int>, const std::vector<int> >();
182         test_find_first_of_impl< const std::vector<int>, std::list<int> >();
183         test_find_first_of_impl< const std::list<int>, std::vector<int> >();
184         test_find_first_of_impl< std::vector<int>, std::list<int> >();
185         test_find_first_of_impl< std::list<int>, std::vector<int> >();
186     }
187 }
188 
189 boost::unit_test::test_suite*
init_unit_test_suite(int argc,char * argv[])190 init_unit_test_suite(int argc, char* argv[])
191 {
192     boost::unit_test::test_suite* test
193         = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.find_first_of" );
194 
195     test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_find_first_of::test_find_first_of ) );
196 
197     return test;
198 }
199