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/adaptor/filtered.hpp>
13 #include <boost/test/test_tools.hpp>
14 #include <boost/test/unit_test.hpp>
16 #include <boost/assign.hpp>
17 #include <boost/range/algorithm_ext.hpp>
30 struct always_false_pred
33 bool operator()(T1
) const { return false; }
36 struct always_true_pred
39 bool operator()(T1
) const { return true; }
44 template< class IntegerT
>
45 bool operator()( IntegerT x
) const { return x
% 2 == 0; }
50 template< class IntegerT
>
51 bool operator()( IntegerT x
) const { return x
% 2 != 0; }
60 lambda(const lambda_init
& init
) {}
61 lambda(const lambda
& rhs
) {}
64 bool operator()(T1
) const { return false; }
68 lambda
& operator=(const lambda
& rhs
) { return *this; }
71 template< class Container
, class Pred
>
72 void filtered_test_impl( Container
& c
, Pred pred
)
74 using namespace boost::adaptors
;
76 typedef BOOST_DEDUCED_TYPENAME
Container::value_type value_t
;
78 // This is my preferred syntax using the | operator.
79 std::vector
< value_t
> test_result1
;
80 boost::push_back(test_result1
, c
| filtered(pred
));
82 // This is an alternative syntax preferred by some.
83 std::vector
< value_t
> test_result2
;
84 boost::push_back(test_result2
, adaptors::filter(c
, pred
));
86 // Calculate the reference result.
87 std::vector
< value_t
> reference_result
;
88 typedef BOOST_DEDUCED_TYPENAME
Container::const_iterator iter_t
;
89 for (iter_t it
= c
.begin(); it
!= c
.end(); ++it
)
92 reference_result
.push_back(*it
);
95 BOOST_CHECK_EQUAL_COLLECTIONS( reference_result
.begin(),
96 reference_result
.end(),
100 BOOST_CHECK_EQUAL_COLLECTIONS( reference_result
.begin(),
101 reference_result
.end(),
102 test_result2
.begin(),
103 test_result2
.end() );
106 template< class Rng
>
107 void check_copy_assign(Rng r
)
113 template< class Container
, class Pred
>
114 void filtered_range_copy_assign(Container
& c
, Pred pred
)
116 using namespace boost::adaptors
;
117 check_copy_assign(c
| filtered(pred
));
118 check_copy_assign(adaptors::filter(c
, pred
));
121 template< class Container
, class Pred
, class PredInit
>
122 void filtered_test_impl()
124 using namespace boost::assign
;
130 // test empty container
131 filtered_test_impl(c
, pred
);
135 filtered_test_impl(c
, pred
);
137 // test many elements
138 c
+= 1,2,2,2,3,4,4,4,4,5,6,7,8,9,9;
139 filtered_test_impl(c
, pred
);
141 // test the range and iterator are copy assignable
142 filtered_range_copy_assign(c
, pred
);
145 template< class Container
>
146 void filtered_test_all_predicates()
148 filtered_test_impl
< Container
, always_false_pred
, always_false_pred
>();
149 filtered_test_impl
< Container
, always_true_pred
, always_true_pred
>();
150 filtered_test_impl
< Container
, is_odd
, is_odd
>();
151 filtered_test_impl
< Container
, is_even
, is_even
>();
152 filtered_test_impl
< Container
, lambda
, lambda_init
>();
155 void ticket_10988_single_pass()
158 std::string
str("0 1 2 3 4 5");
159 std::istringstream
in(str
);
162 boost::make_iterator_range(
163 std::istream_iterator
<int>(in
),
164 std::istream_iterator
<int>())
165 | boost::adaptors::filtered(is_even()));
167 std::vector
<int> reference
;
168 for (int i
= 0; i
< 6; i
+= 2)
170 reference
.push_back(i
);
172 BOOST_CHECK_EQUAL_COLLECTIONS(
173 reference
.begin(), reference
.end(),
179 filtered_test_all_predicates
< std::vector
< int > >();
180 filtered_test_all_predicates
< std::list
< int > >();
181 filtered_test_all_predicates
< std::set
< int > >();
182 filtered_test_all_predicates
< std::multiset
< int > >();
183 ticket_10988_single_pass();
188 boost::unit_test::test_suite
*
189 init_unit_test_suite(int argc
, char* argv
[])
191 boost::unit_test::test_suite
* test
192 = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.filtered" );
194 test
->add( BOOST_TEST_CASE( &boost::filtered_test
) );