• 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/adaptor/transformed.hpp>
12 
13 #include <boost/test/test_tools.hpp>
14 #include <boost/test/unit_test.hpp>
15 
16 #include <boost/assign.hpp>
17 #include <boost/bind/bind.hpp>
18 #include <boost/range/algorithm_ext.hpp>
19 
20 #include <algorithm>
21 #include <list>
22 #include <set>
23 #include <vector>
24 
25 namespace boost
26 {
27     namespace
28     {
29         struct double_x
30         {
31             typedef int result_type;
operator ()boost::__anon010aac4d0111::double_x32             int operator()(int x) const { return x * 2; }
33         };
34 
35         struct halve_x
36         {
37             typedef int result_type;
operator ()boost::__anon010aac4d0111::halve_x38             int operator()(int x) const { return x / 2; }
39         };
40 
41         struct lambda_init
42         {
43         };
44 
45         struct lambda
46         {
47             typedef int result_type;
48 
lambdaboost::__anon010aac4d0111::lambda49             lambda(const lambda_init& init) {}
lambdaboost::__anon010aac4d0111::lambda50             lambda(const lambda& rhs) {}
51 
operator ()boost::__anon010aac4d0111::lambda52             int operator()(int x) const { return x + 1; }
53 
54         private:
lambdaboost::__anon010aac4d0111::lambda55             lambda() {}
operator =boost::__anon010aac4d0111::lambda56             lambda& operator=(const lambda& rhs) { return *this; }
57         };
58 
59         template< class Container, class TransformFn >
transformed_test_impl_core(Container & c,TransformFn fn)60         void transformed_test_impl_core( Container& c, TransformFn fn )
61         {
62             using namespace boost::adaptors;
63 
64             std::vector< int > test_result1;
65             boost::push_back(test_result1, c | transformed(fn));
66 
67             std::vector< int > test_result2;
68             boost::push_back(test_result2, adaptors::transform(c, fn));
69 
70             std::vector< int > reference;
71             std::transform(c.begin(), c.end(), std::back_inserter(reference), fn);
72 
73             BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
74                                            test_result1.begin(), test_result1.end() );
75 
76             BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
77                                            test_result2.begin(), test_result2.end() );
78         }
79 
80         template< class Rng >
check_copy_assign(Rng r)81         void check_copy_assign(Rng r)
82         {
83             Rng r2 = r;
84             r2 = r;
85         }
86 
87         template< class Container, class TransformFn >
transformed_range_copy_assign(Container & c,TransformFn fn)88         void transformed_range_copy_assign(Container& c, TransformFn fn)
89         {
90             using namespace boost::adaptors;
91             check_copy_assign(c | transformed(fn));
92             check_copy_assign(adaptors::transform(c, fn));
93         }
94 
95         template< class Container, class TransformFn, class TransformFnInit >
transformed_test_fn_impl()96         void transformed_test_fn_impl()
97         {
98             using namespace boost::assign;
99 
100             Container c;
101             TransformFnInit init;
102             TransformFn fn( init );
103 
104             // Test empty
105             transformed_test_impl_core(c, fn);
106 
107             // Test one element
108             c += 1;
109             transformed_test_impl_core(c, fn);
110 
111             // Test many elements
112             c += 1,1,1,2,2,2,2,2,3,4,5,6,7,8,9;
113             transformed_test_impl_core(c, fn);
114 
115             // test the range and iterator are copy assignable
116             transformed_range_copy_assign(c, fn);
117         }
118 
119         template< class Container >
transformed_test_impl()120         void transformed_test_impl()
121         {
122             transformed_test_fn_impl< Container, double_x, double_x >();
123             transformed_test_fn_impl< Container, halve_x, halve_x >();
124             transformed_test_fn_impl< Container, lambda, lambda_init >();
125         }
126 
transformed_test()127         void transformed_test()
128         {
129             transformed_test_impl< std::vector< int > >();
130             transformed_test_impl< std::list< int > >();
131             transformed_test_impl< std::set< int > >();
132             transformed_test_impl< std::multiset< int > >();
133         }
134 
135         struct foo_bind
136         {
fooboost::__anon010aac4d0111::foo_bind137             int foo() const { return 7; }
138         };
139 
transformed_bind()140         void transformed_bind()
141         {
142             using namespace boost::adaptors;
143             using namespace boost::placeholders;
144 
145             std::vector<foo_bind> input(5);
146             std::vector<int> output;
147             boost::range::push_back(
148                     output,
149                     input | transformed(boost::bind(&foo_bind::foo, _1)));
150 
151             BOOST_CHECK_EQUAL(output.size(), input.size());
152 
153             std::vector<int> reference_output(5, 7);
154             BOOST_CHECK_EQUAL_COLLECTIONS(
155                         output.begin(), output.end(),
156                         reference_output.begin(), reference_output.end());
157         }
158     }
159 }
160 
161 boost::unit_test::test_suite*
init_unit_test_suite(int argc,char * argv[])162 init_unit_test_suite(int argc, char* argv[])
163 {
164     boost::unit_test::test_suite* test
165         = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.transformed" );
166 
167     test->add(BOOST_TEST_CASE(&boost::transformed_test));
168     test->add(BOOST_TEST_CASE(&boost::transformed_bind));
169 
170     return test;
171 }
172