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/lower_bound.hpp>
10
11#include <boost/test/test_tools.hpp>
12#include <boost/test/unit_test.hpp>
13
14#include <boost/assign.hpp>
15#include <boost/range/algorithm/lower_bound.hpp>
16#include "../test_driver/range_return_test_driver.hpp"
17#include <algorithm>
18#include <functional>
19#include <list>
20#include <numeric>
21#include <deque>
22#include <vector>
23
24namespace boost_range_test_algorithm_lower_bound
25{
26 class lower_bound_policy
27 {
28 public:
29 template< class Container >
30 BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
31 test_iter(Container& cont)
32 {
33 typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
34 iter_t result = boost::lower_bound(cont, 5);
35 BOOST_CHECK( result == boost::lower_bound(boost::make_iterator_range(cont), 5) );
36 return result;
37 }
38
39 template<boost::range_return_value return_type>
40 struct test_range
41 {
42 template<class Container, class Policy>
43 BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
44 operator()(Policy&, Container& cont)
45 {
46 typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
47 result_t result = boost::lower_bound<return_type>(cont, 5);
48 BOOST_CHECK( result == boost::lower_bound<return_type>(boost::make_iterator_range(cont), 5) );
49 return result;
50 }
51 };
52
53 template< class Container >
54 BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
55 reference(Container& cont)
56 {
57 return std::lower_bound(cont.begin(), cont.end(), 5);
58 }
59 };
60
61 template< class BinaryPredicate >
62 struct lower_bound_pred_policy
63 {
64 template< class Container >
65 BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
66 test_iter(Container& cont)
67 {
68 typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type iter_t;
69 iter_t result = boost::lower_bound(cont, 5, m_pred);
70 BOOST_CHECK( result == boost::lower_bound(
71 boost::make_iterator_range(cont), 5, m_pred) );
72 return result;
73 }
74
75 template< boost::range_return_value return_type >
76 struct test_range
77 {
78 template<class Container, class Policy>
79 BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type
80 operator()(Policy& policy, Container& cont)
81 {
82 typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,return_type>::type result_t;
83 result_t result = boost::lower_bound<return_type>(cont, 5, policy.pred());
84 BOOST_CHECK( result == boost::lower_bound<return_type>(
85 boost::make_iterator_range(cont), 5, policy.pred()) );
86 return result;
87 }
88 };
89
90 template<class Container>
91 BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
92 reference(Container& cont)
93 {
94 return std::lower_bound(
95 cont.begin(), cont.end(), 5, m_pred);
96 }
97
98 BinaryPredicate& pred() { return m_pred; }
99
100 private:
101 BinaryPredicate m_pred;
102 };
103
104 template<class Container,
105 class TestPolicy,
106 class BinaryPredicate>
107 void test_lower_bound_impl(TestPolicy policy, BinaryPredicate pred)
108 {
109 using namespace boost::assign;
110
111 typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Container>::type container_t;
112 typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
113
114 boost::range_test::range_return_test_driver test_driver;
115
116 container_t mcont;
117 Container& cont = mcont;
118
119 test_driver(cont, policy);
120
121 mcont.clear();
122 mcont += 1;
123
124 std::vector<value_t> temp(mcont.begin(), mcont.end());
125 std::sort(temp.begin(), temp.end(), pred);
126 mcont.assign(temp.begin(), temp.end());
127
128 test_driver(cont, policy);
129
130 mcont.clear();
131 mcont += 1,2,3,4,5,6,7,8,9;
132
133 temp.assign(mcont.begin(), mcont.end());
134 std::sort(temp.begin(), temp.end(), pred);
135 mcont.assign(temp.begin(), temp.end());
136
137 test_driver(cont, policy);
138 }
139
140 template<class Container>
141 void test_lower_bound_impl()
142 {
143 test_lower_bound_impl<Container>(
144 lower_bound_policy(),
145 std::less<int>()
146 );
147
148 test_lower_bound_impl<Container>(
149 lower_bound_pred_policy<std::less<int> >(),
150 std::less<int>()
151 );
152
153 test_lower_bound_impl<Container>(
154 lower_bound_pred_policy<std::greater<int> >(),
155 std::greater<int>()
156 );
157 }
158
159 void test_lower_bound()
160 {
161 test_lower_bound_impl< std::vector<int> >();
162 test_lower_bound_impl< std::list<int> >();
163 test_lower_bound_impl< std::deque<int> >();
164
165 test_lower_bound_impl< const std::vector<int> >();
166 test_lower_bound_impl< const std::list<int> >();
167 test_lower_bound_impl< const std::deque<int> >();
168 }
169}
170
171boost::unit_test::test_suite*
172init_unit_test_suite(int argc, char* argv[])
173{
174 boost::unit_test::test_suite* test
175 = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.lower_bound" );
176
177 test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_lower_bound::test_lower_bound ) );
178
179 return test;
180}
181

source code of boost/libs/range/test/algorithm_test/lower_bound.cpp