• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Range library
2 //
3 //  Copyright Thorsten Ottosen 2006. 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 // For more information, see http://www.boost.org/libs/range/
9 //
10 
11 #include <boost/range/adaptors.hpp>
12 #include <boost/test/test_tools.hpp>
13 #include <boost/test/unit_test.hpp>
14 #include <boost/foreach.hpp>
15 #include <boost/assign/list_of.hpp>
16 #include <vector>
17 #include <list>
18 #include <string>
19 #include <map>
20 
21 template< class T >
22 struct less_than
23 {
24     T val;
25 
less_thanless_than26     less_than() : val(0)
27     {}
28 
less_thanless_than29     less_than( T t ) : val(t)
30     {}
31 
operator ()less_than32     bool operator()( const T& r ) const
33     {
34         return r < val;
35     }
36 };
37 
38 
39 
40 template< class T >
41 struct multiply
42 {
43     T val;
44 
45     typedef T& result_type;
46 
multiplymultiply47     multiply( T t ) : val(t)
48     { }
49 
operator ()multiply50     T& operator()( T& r ) const
51     {
52         return r *= 2;
53     }
54 };
55 
56 
57 
58 template< class Rng >
check_copy(Rng r)59 void check_copy( Rng r )
60 {
61     //
62     // Make sure the generated iterators
63     // can actually be copied
64     //
65     Rng r2 = r;
66     r2     = r;
67 }
68 
69 
70 template< class Rng >
check_direct()71 void check_direct()
72 {
73     using namespace boost::adaptors;
74 
75     Rng rng = boost::assign::list_of(1)(2)(3)(4)(5).to_container( rng );
76     Rng out;
77 
78     //
79     // test each alphabetically
80     //
81     BOOST_FOREACH( int i, rng | filtered( less_than<int>(4) )
82                               /*| reversed*/
83                               | transformed( multiply<int>(2) ) )
84     {
85       out.push_back( i );
86     }
87 
88     BOOST_CHECK_EQUAL( out.size(), 3u );
89     BOOST_CHECK_EQUAL( *out.begin(), 2 );
90     BOOST_CHECK_EQUAL( *boost::next(out.begin()), 4 );
91     BOOST_CHECK_EQUAL( *boost::next(out.begin(),2), 6 );
92 
93     rng = boost::assign::list_of(1)(1)(2)(2)(3)(3)(4)(5).to_container( rng );
94     out.clear();
95     /*
96     BOOST_FOREACH( int i, rng | adjacent_filtered( std::equal_to<int>() )
97                               | uniqued )
98     {
99 
100         out.push_back( i );
101     }*/
102 
103 }
104 
105 
106 template< class IndirectRng >
check_indirect()107 void check_indirect()
108 {
109     using namespace boost::adaptors;
110 
111     IndirectRng rng;
112 
113     std::vector< boost::shared_ptr< int > > holder;
114 
115     for( unsigned i = 0u; i != 20u; ++i )
116     {
117         boost::shared_ptr<int> v(new int(i));
118         rng.push_back( v.get() );
119     }
120 
121     BOOST_FOREACH( int& i, rng | indirected | reversed
122                                | transformed( multiply<int>(2) ) )
123     {
124         i += 1;
125     }
126 
127 
128 
129 }
130 
131 
132 
133 template< class RandomAccessRng >
check_random_access()134 void check_random_access()
135 {
136     using namespace boost::adaptors;
137 
138     RandomAccessRng rng(1, 20u);
139     RandomAccessRng out;
140 
141     BOOST_FOREACH( int i, rng | reversed
142                               | transformed( multiply<int>(2) )
143                               /* | sliced(0,15) */ )
144     {
145       out.push_back( i );
146     }
147 
148 
149     BOOST_FOREACH( int i, rng | copied(3u,13u) )
150     {
151         out.push_back( i );
152     }
153 }
154 
155 
156 
157 template< class Map >
check_map()158 void check_map()
159 {
160     using namespace boost::adaptors;
161 
162     Map m;
163     m.insert( std::make_pair(1,2) );
164     m.insert( std::make_pair(2,2) );
165     m.insert( std::make_pair(3,2) );
166     m.insert( std::make_pair(4,2) );
167     m.insert( std::make_pair(5,2) );
168     m.insert( std::make_pair(6,2) );
169     m.insert( std::make_pair(7,2) );
170 
171     std::vector<int> keys
172         = boost::copy_range< std::vector<int> >( m | map_keys );
173     std::vector<int> values
174        = boost::copy_range< std::vector<int> >( m | map_values );
175 }
176 
177 
178 
check_regex()179 void check_regex()
180 {
181     using namespace boost::adaptors;
182     std::string s("This is a string of tokens");
183     std::vector<std::string> tokens =
184         boost::copy_range< std::vector<std::string> >( s | tokenized( "\\s+", -1 ) );
185 }
186 
187 
check_adaptors()188 void check_adaptors()
189 {
190     check_direct< std::vector<int> >();
191     check_direct< std::list<int> >();
192     check_indirect< std::vector<int*> >();
193     check_indirect< std::list<int*> >();
194 
195     check_map< std::map<int,int> >();
196 //    check_random_access< std::vector<int> >();
197     check_regex();
198 
199     using namespace boost::adaptors;
200     std::vector<int>  vec(10u,20);
201     std::vector<int*> pvec;
202     std::map<int,int> map;
203 
204     check_copy( vec | adjacent_filtered( std::equal_to<int>() ) );
205   //  check_copy( vec | indexed );
206     check_copy( vec | reversed );
207     check_copy( vec | uniqued );
208     check_copy( pvec | indirected );
209 
210 //    check_copy( vec | sliced(1,5) );
211     //
212     // This does not return an iterator_range<>, so
213     // won't pass this test of implicit conversion
214     //  check_copy( vec | copied(1,5) );
215     //
216     check_copy( map | map_values );
217     check_copy( map | map_keys );
218     check_copy( std::string( "a string" ) | tokenized( "\\s+", -1 ) );
219     check_copy( vec | filtered( less_than<int>(2) ) );
220     check_copy( vec | transformed( multiply<int>(2) ) );
221 }
222 
223 using boost::unit_test::test_suite;
224 
init_unit_test_suite(int argc,char * argv[])225 test_suite* init_unit_test_suite( int argc, char* argv[] )
226 {
227     using namespace boost;
228 
229     test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - Adaptors" );
230 
231     test->add( BOOST_TEST_CASE( &check_adaptors ) );
232 
233     return test;
234 }
235 
236 
237