]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/ptr_container/test/ptr_map.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / ptr_container / test / ptr_map.cpp
1 //
2 // Boost.Pointer Container
3 //
4 // Copyright Thorsten Ottosen 2003-2005. Use, modification and
5 // distribution is subject to the Boost Software License, Version
6 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // For more information, see http://www.boost.org/libs/ptr_container/
10 //
11
12 #include "test_data.hpp"
13 #include <boost/test/unit_test.hpp>
14 #include <boost/ptr_container/exception.hpp>
15 #include <boost/range/sub_range.hpp>
16 #include <boost/cast.hpp>
17 #include <cstdlib>
18 #include <iostream>
19 #include <memory>
20 #include <string>
21
22 //
23 // abstract base class definition
24 //
25 struct abstract_base
26 {
27 virtual ~abstract_base() {}
28 virtual void foo() = 0;
29 virtual abstract_base* clone() const = 0;
30 };
31
32 struct implementation : abstract_base
33 {
34 implementation()
35 { }
36
37 implementation( const implementation& )
38 { }
39
40 implementation( int, std::string, int, std::string )
41 { }
42
43 virtual void foo() {}
44 virtual abstract_base* clone() const
45 {
46 return new implementation( *this );
47 }
48 };
49
50 inline std::ostream& operator<<( std::ostream& out, const abstract_base& r )
51 {
52 return out;
53 }
54
55 inline abstract_base* new_clone( const abstract_base& r )
56 {
57 return r.clone();
58 }
59
60 //
61 // ptr_map test
62 //
63
64 template< typename C, typename B, typename T >
65 void ptr_map_test();
66
67 template< class Key >
68 Key get_next_key( const Key& k );
69
70 template<>
71 int get_next_key<int>( const int& )
72 {
73 return rand();
74 }
75
76 template<>
77 std::string get_next_key<std::string>( const std::string& )
78 {
79 return boost::lexical_cast<std::string>( rand() );
80 }
81
82
83 template< typename C, typename B, typename T >
84 void ptr_map_test()
85 {
86 using namespace boost;
87
88 BOOST_TEST_MESSAGE( "starting associative container test" );
89 enum { max_cnt = 10, size = 100 };
90 C c;
91 BOOST_CHECK( c.size() == 0 );
92
93 const C c2( c.begin(), c.end() );
94 BOOST_CHECK( c.size() == c2.size() );
95
96 C c3;
97
98 BOOST_TEST_MESSAGE( "finished construction test" );
99
100 BOOST_DEDUCED_TYPENAME C::allocator_type alloc = c.get_allocator();
101 BOOST_DEDUCED_TYPENAME C::iterator i = c.begin();
102 BOOST_DEDUCED_TYPENAME C::const_iterator ci = c2.begin();
103 BOOST_DEDUCED_TYPENAME C::iterator i2 = c.end();
104 BOOST_DEDUCED_TYPENAME C::const_iterator ci2 = c2.begin();
105 BOOST_DEDUCED_TYPENAME C::reverse_iterator ri = c.rbegin();
106 BOOST_DEDUCED_TYPENAME C::const_reverse_iterator cri = c2.rbegin();
107 BOOST_DEDUCED_TYPENAME C::reverse_iterator rv2 = c.rend();
108 BOOST_DEDUCED_TYPENAME C::const_reverse_iterator cvr2 = c2.rend();
109
110 BOOST_DEDUCED_TYPENAME C::key_type a_key;
111
112 BOOST_TEST_MESSAGE( "finished iterator test" );
113
114 BOOST_DEDUCED_TYPENAME C::size_type s = c.size();
115 BOOST_DEDUCED_TYPENAME C::size_type s2 = c.max_size();
116 hide_warning(s2);
117 BOOST_CHECK_EQUAL( c.size(), s );
118 bool b = c.empty();
119 hide_warning(b);
120 BOOST_TEST_MESSAGE( "finished accessors test" );
121
122 a_key = get_next_key( a_key );
123 c.insert( a_key, new T );
124 a_key = get_next_key( a_key );
125 c.insert( a_key, new T );
126 c3.insert( c.begin(), c.end() );
127 c.insert( c3 );
128 c.erase( c.begin() );
129 BOOST_CHECK( c3.end() == c3.erase( boost::make_iterator_range(c3) ) );
130 c3.erase( a_key );
131
132 BOOST_CHECK( c3.empty() );
133 c.swap( c3 );
134 swap(c,c3);
135 swap(c3,c);
136 BOOST_CHECK( !c3.empty() );
137 c3.clear();
138 BOOST_CHECK( c3.empty() );
139 BOOST_TEST_MESSAGE( "finished modifiers test" );
140
141
142 a_key = get_next_key( a_key );
143 c.insert( a_key, new T );
144 a_key = get_next_key( a_key );
145 c.insert( a_key, std::auto_ptr<T>( new T ) );
146 typename C::auto_type ptr2 = c.release( c.begin() );
147 std::auto_ptr<C> ap = c.release();
148 c = c2.clone();
149 BOOST_TEST_MESSAGE( "finished release/clone test" );
150
151
152 a_key = get_next_key( a_key );
153 c3.insert( a_key, new T );
154 a_key = get_next_key( a_key );
155 c3.insert( a_key, new T );
156
157 c. BOOST_NESTED_TEMPLATE transfer<C>( c3.begin(), c3 );
158 c. BOOST_NESTED_TEMPLATE transfer<C>( c3.begin(), c3.end(), c3 );
159 BOOST_CHECK( c3.empty() );
160 BOOST_CHECK( !c.empty() );
161 c3. BOOST_NESTED_TEMPLATE transfer<C>( c );
162 BOOST_CHECK( !c3.empty() );
163 BOOST_CHECK( c.empty() );
164 #ifdef BOOST_NO_SFINAE
165 #else
166 c. BOOST_NESTED_TEMPLATE transfer<C>( make_iterator_range(c3), c3 );
167 BOOST_CHECK( !c.empty() );
168 BOOST_CHECK( c3.empty() );
169 c3. BOOST_NESTED_TEMPLATE transfer<C>(c);
170 #endif
171 BOOST_TEST_MESSAGE( "finished transfer test" );
172
173 BOOST_CHECK( !c3.empty() );
174 c3.replace( c3.begin(), new T );
175 c3.replace( c3.begin(), std::auto_ptr<T>( new T ) );
176 BOOST_TEST_MESSAGE( "finished set/map interface test" );
177
178 // @todo: make macro with algorithms so that the right erase() is called.
179 // c.unique();
180 // c.unique( std::not_equal_to<T>() );
181 // c.remove( T() );
182 // c.remove_if( std::binder1st< std::equal_to<T> >( T() ) );
183
184 sub_range<C> sub;
185 sub_range<const C> csub;
186
187 i = c.find( get_next_key( a_key ) );
188 ci = c2.find( get_next_key( a_key ) );
189 c2.count( get_next_key( a_key ) );
190 i = c.lower_bound( get_next_key( a_key ) );
191 ci = c2.lower_bound( get_next_key( a_key ) );
192 i = c.upper_bound( get_next_key( a_key ) );
193 ci = c2.upper_bound( get_next_key( a_key ) );
194 sub = c.equal_range( get_next_key( a_key ) );
195 csub = c2.equal_range( get_next_key( a_key ) );
196
197 try
198 {
199 c.at( get_next_key( a_key ) );
200 }
201 catch( const bad_ptr_container_operation& )
202 { }
203
204 try
205 {
206 c2.at( get_next_key( a_key ) );
207 }
208 catch( const bad_ptr_container_operation& )
209 { }
210
211 BOOST_TEST_MESSAGE( "finished algorithms interface test" );
212
213 typename C::iterator it = c.begin(), e = c.end();
214 for( ; it != e; ++it )
215 {
216 std::cout << "\n mapped value = " << *it->second << " key = " << it->first;
217 //std::cout << "\n mapped value = " << it.value() << " key = " << it.key();
218 }
219
220 typename C::reverse_iterator rit = c.rbegin(), re = c.rend();
221 for( ; rit != re; ++rit )
222 {
223 std::cout << "\n mapped value = " << *rit->second << " key = " << rit->first;
224 //std::cout << "\n mapped value = " << rit.value() << " key = " << rit.key();
225 //std::cout << "\n mapped value (base) = "
226 // << rit.base().value() << " key = " << rit.base().key();
227 }
228
229 typename C::const_reverse_iterator crit = c2.rbegin(), cre = c2.rend();
230 for( ; crit != cre; ++crit )
231 {
232 std::cout << "\n mapped value = " << *(*crit).second << " key = " << (*crit).first;
233 //std::cout << "\n mapped value = " << crit.value() << " key = " << crit.key();
234 //std::cout << "\n mapped value (base) = "
235 // << crit.base().value() << " key = " << crit.base().key();
236 }
237
238 BOOST_TEST_MESSAGE( "finished iterator test" );
239
240 a_key = get_next_key( a_key );
241 c.insert( a_key, new T );
242 c.erase( a_key );
243 c.erase( a_key );
244
245 }
246
247
248
249 template< class CDerived, class CBase, class T >
250 void test_transfer()
251 {
252 CDerived from;
253 CBase to;
254
255 int key = get_next_key( key );
256 from.insert( key, new T );
257 key = get_next_key( key );
258 from.insert( key, new T );
259 transfer_test( from, to );
260 }
261
262
263
264 template< class BaseContainer, class DerivedContainer, class Derived >
265 void map_container_assignment_test()
266 {
267 DerivedContainer derived;
268 std::string foo( "foo" );
269 std::string bar( "foo" );
270 derived.insert( foo, new Derived );
271 derived.insert( bar, new Derived );
272
273 BaseContainer base_container( derived );
274 BOOST_CHECK_EQUAL( derived.size(), base_container.size() );
275 base_container.clear();
276 base_container = derived;
277 BOOST_CHECK_EQUAL( derived.size(), base_container.size() );
278
279 BaseContainer base2( base_container );
280 BOOST_CHECK_EQUAL( base2.size(), base_container.size() );
281 base2 = base_container;
282 BOOST_CHECK_EQUAL( base2.size(), base_container.size() );
283 base_container = base_container;
284 }
285
286
287
288 #include <boost/ptr_container/ptr_map.hpp>
289
290 using namespace std;
291
292 void test_map()
293 {
294 ptr_map_test< ptr_map<int, Base>, Base, Derived_class >();
295 ptr_map_test< ptr_map<int, Value>, Value, Value >();
296 ptr_map_test< ptr_map<int, nullable<Base> >, Base, Derived_class >();
297 ptr_map_test< ptr_map<int, nullable<Value> >, Value, Value >();
298 ptr_map_test< ptr_map<int, abstract_base>, abstract_base, implementation >();
299
300 ptr_map_test< ptr_multimap<int,Base>, Base, Derived_class >();
301 ptr_map_test< ptr_multimap<int,Value>, Value, Value >();
302 ptr_map_test< ptr_multimap<int, nullable<Base> >, Base, Derived_class >();
303 ptr_map_test< ptr_multimap<int, nullable<Value> >, Value, Value >();
304
305 map_container_assignment_test< ptr_map<std::string,Base>,
306 ptr_map<std::string,Derived_class>,
307 Derived_class>();
308 map_container_assignment_test< ptr_map<std::string, nullable<Base> >,
309 ptr_map<std::string,Derived_class>,
310 Derived_class>();
311 map_container_assignment_test< ptr_map<std::string, nullable<Base> >,
312 ptr_map<std::string, nullable<Derived_class> >,
313 Derived_class>();
314 map_container_assignment_test< ptr_multimap<std::string,Base>,
315 ptr_multimap<std::string,Derived_class>,
316 Derived_class>();
317 map_container_assignment_test< ptr_multimap<std::string, nullable<Base> >,
318 ptr_multimap<std::string,Derived_class>,
319 Derived_class>();
320 map_container_assignment_test< ptr_multimap<std::string, nullable<Base> >,
321 ptr_multimap<std::string, nullable<Derived_class> >,
322 Derived_class>();
323
324
325 test_transfer< ptr_map<int,Derived_class>, ptr_map<int,Base>, Derived_class >();
326 test_transfer< ptr_multimap<int,Derived_class>, ptr_multimap<int,Base>, Derived_class >();
327
328 string joe = "joe";
329 string brian = "brian";
330 string kenny = "kenny";
331
332 ptr_map<string,int> m;
333 m.insert( joe, new int( 4 ) );
334 m.insert( brian, new int( 6 ) );
335 BOOST_CHECK( m[ "foo" ] == 0 );
336 m[ "bar" ] += 5;
337 BOOST_CHECK( m[ "bar" ] == 5 );
338 m[ joe ] += 56;
339 m[ brian ] += 10;
340
341 BOOST_CHECK_THROW( (m.insert(kenny, 0 )), bad_ptr_container_operation );
342 BOOST_CHECK_THROW( (m.replace(m.begin(), 0 )), bad_ptr_container_operation );
343 BOOST_CHECK_THROW( (m.at("not there")), bad_ptr_container_operation );
344
345 for( ptr_map<string,int>::iterator i = m.begin();
346 i != m.end(); ++i )
347 {
348 if( is_null(i) )
349 BOOST_CHECK( false );
350 const string& ref = i->first;
351 hide_warning(ref);
352 int& ref2 = *(*i).second;
353 ref2++;
354 }
355
356 typedef ptr_map<string,Derived_class> map_type;
357 map_type m2;
358 m2.insert( joe, new Derived_class );
359 //
360 // This works fine since 'm2' is not const
361 //
362 m2.begin()->second->foo();
363
364 //
365 // These all return an implementation-defined proxy
366 // with two public members: 'first' and 'second'
367 //
368 map_type::value_type a_value = *m2.begin();
369 a_value.second->foo();
370 map_type::reference a_reference = *m2.begin();
371 a_reference.second->foo();
372 map_type::const_reference a_creference = *const_begin(m2);
373
374 //
375 //
376 // These will fail as iterators propagate constness
377 //
378 //a_creference.second->foo();
379 //a_cpointer->second->foo();
380 //const_begin(m2)->second->foo();
381
382 }
383
384 #include <boost/tuple/tuple.hpp>
385 #include <boost/iterator/zip_iterator.hpp>
386 #include <map>
387 #include <boost/ptr_container/ptr_map.hpp>
388
389 void test_map_iterators()
390 {
391 using boost::zip_iterator;
392 using boost::tuple;
393 using boost::make_tuple;
394 using boost::ptr_map;
395 using std::map;
396
397 //typedef map<int, int> theMapType;
398 /*
399 @remark: the following will not compile
400 because of the proxy (non-reference) returned by operator*()
401 of the ptr_map's iterator type.
402
403 typedef boost::ptr_map<int, int> theMapType;
404 typedef zip_iterator
405 <tuple<theMapType::iterator, theMapType::iterator> > zipIter;
406 theMapType map1;
407 theMapType map2;
408 zipIter zip(make_tuple(map1.begin(), map2.begin()));
409 */
410 }
411
412
413
414 using boost::unit_test::test_suite;
415
416 test_suite* init_unit_test_suite( int argc, char* argv[] )
417 {
418 test_suite* test = BOOST_TEST_SUITE( "Pointer Container Test Suite" );
419
420 test->add( BOOST_TEST_CASE( &test_map ) );
421 test->add( BOOST_TEST_CASE( &test_map_iterators ) );
422
423 return test;
424 }
425
426
427
428
429
430
431