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)
9 // For more information, see http://www.boost.org/libs/range/
11 #include <boost/range/algorithm/search_n.hpp>
13 #include <boost/test/test_tools.hpp>
14 #include <boost/test/unit_test.hpp>
16 #include <boost/assign.hpp>
24 template<typename ForwardIterator
, typename Integer
, typename Value
>
25 inline ForwardIterator
26 reference_search_n(ForwardIterator first
, ForwardIterator last
,
27 Integer count
, const Value
& value
)
32 return std::find(first
, last
, value
);
35 first
= std::find(first
, last
, value
);
38 typename
std::iterator_traits
<ForwardIterator
>::difference_type n
= count
;
39 ForwardIterator i
= first
;
41 while (i
!= last
&& n
!= 1 && *i
==value
)
50 first
= std::find(++i
, last
, value
);
56 template<typename ForwardIterator
, typename Integer
, typename Value
,
57 typename BinaryPredicate
>
58 inline ForwardIterator
59 reference_search_n(ForwardIterator first
, ForwardIterator last
,
60 Integer count
, const Value
& value
,
63 typedef typename
std::iterator_traits
<
65 >::iterator_category cat_t BOOST_RANGE_UNUSED
;
71 while (first
!= last
&& !static_cast<bool>(pred(*first
, value
)))
77 typedef typename
std::iterator_traits
<ForwardIterator
>::difference_type difference_t
;
79 while (first
!= last
&& !static_cast<bool>(pred(*first
, value
)))
84 difference_t n
= count
;
85 ForwardIterator i
= first
;
87 while (i
!= last
&& n
!= 1 && static_cast<bool>(pred(*i
, value
)))
97 while (first
!= last
&& !static_cast<bool>(pred(*first
, value
)))
104 template< class Container1
, class Value
, class Pred
>
105 void test_search_n_pred_impl(Container1
& cont1
, Value value
, Pred pred
)
107 typedef BOOST_DEDUCED_TYPENAME
Container1::const_iterator const_iterator1_t
;
108 typedef BOOST_DEDUCED_TYPENAME
Container1::iterator iterator1_t
;
110 const Container1
& ccont1
= cont1
;
112 for (std::size_t n
= 0; n
< cont1
.size(); ++n
)
114 iterator1_t it
= boost::search_n(cont1
, n
, value
, pred
);
115 BOOST_CHECK( it
== boost::search_n(boost::make_iterator_range(cont1
), n
, value
, pred
) );
116 BOOST_CHECK( it
== reference_search_n(cont1
.begin(), cont1
.end(), n
, value
, pred
) );
118 const_iterator1_t cit
= boost::search_n(ccont1
, n
, value
, pred
);
119 BOOST_CHECK( cit
== boost::search_n(boost::make_iterator_range(ccont1
), n
, value
, pred
) );
120 BOOST_CHECK( cit
== reference_search_n(ccont1
.begin(), ccont1
.end(), n
, value
, pred
) );
124 template< class Container1
, class Value
>
125 void test_search_n_impl(Container1
& cont1
, Value value
)
127 typedef BOOST_DEDUCED_TYPENAME
Container1::const_iterator const_iterator1_t
;
128 typedef BOOST_DEDUCED_TYPENAME
Container1::iterator iterator1_t
;
130 const Container1
& ccont1
= cont1
;
132 for (std::size_t n
= 0; n
< cont1
.size(); ++n
)
134 iterator1_t it
= boost::search_n(cont1
, n
, value
);
135 BOOST_CHECK( it
== boost::search_n(boost::make_iterator_range(cont1
), n
, value
) );
136 BOOST_CHECK( it
== reference_search_n(cont1
.begin(), cont1
.end(), n
, value
) );
138 const_iterator1_t cit
= boost::search_n(ccont1
, n
, value
);
139 BOOST_CHECK( cit
== boost::search_n(boost::make_iterator_range(ccont1
), n
, value
) );
140 BOOST_CHECK( cit
== reference_search_n(ccont1
.begin(), ccont1
.end(), n
, value
) );
143 test_search_n_pred_impl(cont1
, value
, std::less
<int>());
144 test_search_n_pred_impl(cont1
, value
, std::greater
<int>());
145 test_search_n_pred_impl(cont1
, value
, std::equal_to
<int>());
146 test_search_n_pred_impl(cont1
, value
, std::not_equal_to
<int>());
149 template< class Container1
, class Container2
>
150 void test_search_n_impl()
152 using namespace boost::assign
;
156 test_search_n_impl(cont1
, 1);
159 test_search_n_impl(cont1
, 1);
160 test_search_n_impl(cont1
, 0);
164 test_search_n_impl(cont1
, 1);
165 test_search_n_impl(cont1
, 0);
168 test_search_n_impl(cont1
, 1);
169 test_search_n_impl(cont1
, 0);
172 cont1
+= 1,2,3,4,5,6,7,8,9;
173 test_search_n_impl(cont1
, 1);
174 test_search_n_impl(cont1
, 2);
175 test_search_n_impl(cont1
, 5);
176 test_search_n_impl(cont1
, 9);
181 test_search_n_impl
< std::list
<int>, std::list
<int> >();
182 test_search_n_impl
< std::vector
<int>, std::vector
<int> >();
183 test_search_n_impl
< std::set
<int>, std::set
<int> >();
184 test_search_n_impl
< std::list
<int>, std::vector
<int> >();
185 test_search_n_impl
< std::vector
<int>, std::list
<int> >();
189 boost::unit_test::test_suite
*
190 init_unit_test_suite(int argc
, char* argv
[])
192 boost::unit_test::test_suite
* test
193 = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.search_n" );
195 test
->add( BOOST_TEST_CASE( &test_search_n
) );