3 // Copyright (c) 2006-2007 Matias Capeletto
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
9 #ifndef LIBS_BIMAP_TEST_BIMAP_TEST_HPP
10 #define LIBS_BIMAP_TEST_BIMAP_TEST_HPP
16 #include <boost/config.hpp>
23 #include <boost/lambda/lambda.hpp>
24 #include <boost/static_assert.hpp>
25 #include <boost/type_traits/is_same.hpp>
26 #include <boost/utility.hpp>
27 #include <boost/next_prior.hpp>
29 template< class Container, class Data >
30 void test_container(Container & c, const Data & d)
32 assert( d.size() > 2 );
36 BOOST_CHECK( c.size() == 0 );
37 BOOST_CHECK( c.empty() );
39 c.insert( *d.begin() );
41 c.insert( ++d.begin(),d.end() );
43 BOOST_CHECK( c.size() == d.size() );
45 BOOST_CHECK( c.size() <= c.max_size() );
46 BOOST_CHECK( ! c.empty() );
50 BOOST_CHECK( c.size() == d.size() - 1 );
52 c.erase( c.begin(), c.end() );
54 BOOST_CHECK( c.empty() );
56 c.insert( *d.begin() );
58 BOOST_CHECK( c.size() == 1 );
60 c.insert( c.begin(), *(++d.begin()) );
62 BOOST_CHECK( c.size() == 2 );
64 BOOST_CHECK( c.begin() != c.end() );
67 template< class Container, class Data >
68 void test_sequence_container(Container & c, const Data & d)
70 assert( d.size() > 2 );
74 BOOST_CHECK( c.size() == 0 );
75 BOOST_CHECK( c.empty() );
77 c.push_front( * d.begin() );
78 c.push_back ( *(++d.begin()) );
80 BOOST_CHECK( c.front() == * c.begin() );
81 BOOST_CHECK( c.back () == *(++c.begin()) );
83 BOOST_CHECK( c.size() == 2 );
85 BOOST_CHECK( c.size() <= c.max_size() );
86 BOOST_CHECK( ! c.empty() );
90 BOOST_CHECK( c.size() == 1 );
92 c.insert( c.begin(), *(++d.begin()) );
94 c.erase( c.begin(), c.end() );
96 BOOST_CHECK( c.empty() );
98 c.push_front( *d.begin() );
100 BOOST_CHECK( c.size() == 1 );
102 BOOST_CHECK( c.begin() != c.end() );
105 BOOST_CHECK( c.empty() );
109 c.assign(d.begin(),d.end());
110 BOOST_CHECK( c.size() == d.size() );
111 BOOST_CHECK( std::equal( c.begin(), c.end(), d.begin() ) );
113 c.assign(d.size(),*d.begin());
114 BOOST_CHECK( c.size() == d.size() );
115 BOOST_CHECK( *c.begin() == *d.begin() );
117 // Check insert(IterPos,InputIter,InputIter)
120 c.insert( c.begin(), d.begin(), d.end() );
121 c.insert( boost::next(c.begin(),2), d.begin(), d.end() );
123 BOOST_CHECK( std::equal( boost::next(c.begin(),2)
124 , boost::next(c.begin(),2+d.size()) , d.begin() ) );
129 c.resize(4,*d.begin());
130 BOOST_CHECK( c.size() == 4 );
131 BOOST_CHECK( *c.begin() == *d.begin() ) ;
133 BOOST_CHECK( c == c );
134 BOOST_CHECK( ! ( c != c ) );
135 BOOST_CHECK( ! ( c < c ) );
136 BOOST_CHECK( ( c <= c ) );
137 BOOST_CHECK( ! ( c > c ) );
138 BOOST_CHECK( ( c >= c ) );
141 template< class Container, class Data >
142 void test_vector_container(Container & c, const Data & d)
144 assert( d.size() > 2 );
148 BOOST_CHECK( c.capacity() >= 2 ) ;
149 c.assign(d.begin(),d.end());
150 BOOST_CHECK( c.capacity() >= c.size() ) ;
152 BOOST_CHECK( c[0] == *d.begin() ) ;
153 BOOST_CHECK( c.at(1) == *boost::next(d.begin()) );
155 test_sequence_container(c,d) ;
158 template< class Container, class Data >
159 void test_associative_container(Container & c, const Data & d)
161 assert( d.size() > 2 );
164 c.insert(d.begin(),d.end());
166 for( typename Data::const_iterator di = d.begin(), de = d.end();
169 BOOST_CHECK( c.find(*di) != c.end() );
172 typename Data::const_iterator da = d.begin();
173 typename Data::const_iterator db = ++d.begin();
177 BOOST_CHECK( c.size() == d.size()-1 );
179 BOOST_CHECK( c.count(*da) == 0 );
180 BOOST_CHECK( c.count(*db) == 1 );
182 BOOST_CHECK( c.find(*da) == c.end() );
183 BOOST_CHECK( c.find(*db) != c.end() );
185 BOOST_CHECK( c.equal_range(*db).first != c.end() );
189 BOOST_CHECK( c.equal_range(*da).first == c.end() );
193 template< class Container >
194 void test_mapped_container(Container &)
196 typedef BOOST_DEDUCED_TYPENAME Container:: value_type value_type ;
197 typedef BOOST_DEDUCED_TYPENAME Container:: key_type key_type ;
198 typedef BOOST_DEDUCED_TYPENAME Container:: data_type data_type ;
199 typedef BOOST_DEDUCED_TYPENAME Container::mapped_type mapped_type ;
201 typedef BOOST_DEDUCED_TYPENAME
202 boost::is_same< key_type
203 , BOOST_DEDUCED_TYPENAME value_type::first_type
204 >::type test_key_type;
205 BOOST_STATIC_ASSERT(test_key_type::value);
207 typedef BOOST_DEDUCED_TYPENAME
208 boost::is_same< data_type
209 , BOOST_DEDUCED_TYPENAME value_type::second_type
210 >::type test_data_type;
211 BOOST_STATIC_ASSERT(test_data_type::value);
213 typedef BOOST_DEDUCED_TYPENAME
214 boost::is_same< mapped_type
215 , BOOST_DEDUCED_TYPENAME value_type::second_type
216 >::type test_mapped_type;
217 BOOST_STATIC_ASSERT(test_mapped_type::value);
220 template< class Container, class Data >
221 void test_pair_associative_container(Container & c, const Data & d)
223 test_mapped_container(c);
225 assert( d.size() > 2 );
228 c.insert(d.begin(),d.end());
230 for( typename Data::const_iterator di = d.begin(), de = d.end();
233 BOOST_CHECK( c.find(di->first) != c.end() );
236 typename Data::const_iterator da = d.begin();
237 typename Data::const_iterator db = ++d.begin();
241 BOOST_CHECK( c.size() == d.size()-1 );
243 BOOST_CHECK( c.count(da->first) == 0 );
244 BOOST_CHECK( c.count(db->first) == 1 );
246 BOOST_CHECK( c.find(da->first) == c.end() );
247 BOOST_CHECK( c.find(db->first) != c.end() );
249 BOOST_CHECK( c.equal_range(db->first).first != c.end() );
253 BOOST_CHECK( c.equal_range(da->first).first == c.end() );
257 template< class Container, class Data >
258 void test_simple_ordered_associative_container_equality(Container & c, const Data & d)
260 BOOST_CHECK( std::equal( c. begin(), c. end(), d. begin() ) );
261 BOOST_CHECK( std::equal( c.rbegin(), c.rend(), d.rbegin() ) );
263 BOOST_CHECK( c.lower_bound( *d.begin() ) == c.begin() );
264 BOOST_CHECK( c.upper_bound( *d.begin() ) == ++c.begin() );
267 template< class Container, class Data >
268 void test_simple_ordered_associative_container(Container & c, const Data & d)
270 assert( d.size() > 2 );
273 c.insert(d.begin(),d.end());
275 for( typename Data::const_iterator di = d.begin(), de = d.end();
278 typename Container::const_iterator ci = c.find(*di);
279 BOOST_CHECK( ci != c.end() );
281 BOOST_CHECK( ! c.key_comp()(*ci,*di) );
282 BOOST_CHECK( ! c.value_comp()(*ci,*di) );
285 test_simple_ordered_associative_container_equality(c, d);
287 const Container & cr = c;
289 test_simple_ordered_associative_container_equality(cr, d);
291 BOOST_CHECK( c == c );
292 BOOST_CHECK( ! ( c != c ) );
293 BOOST_CHECK( ! ( c < c ) );
294 BOOST_CHECK( ( c <= c ) );
295 BOOST_CHECK( ! ( c > c ) );
296 BOOST_CHECK( ( c >= c ) );
299 BOOST_CHECK( c.range( *c.begin() <= ::boost::lambda::_1,
300 ::boost::lambda::_1 <= *(++c.begin()) ).
306 template< class Container, class Data >
307 void test_simple_unordered_associative_container(Container & c, const Data & d)
310 c.insert( d.begin(), d.end() );
312 BOOST_CHECK( c.bucket_count() * c.max_load_factor() >= d.size() );
313 BOOST_CHECK( c.max_bucket_count() >= c.bucket_count() );
315 for( typename Data::const_iterator di = d.begin(), de = d.end() ;
320 typename Container::size_type nb = c.bucket(*c.find(*di));
322 BOOST_CHECK( c.begin(nb) != c.end(nb) );
327 const Container & const_c = c;
330 const_c.bucket_size(const_c.bucket(*di)) == 1
333 typename Container::size_type nb =
334 const_c.bucket(*const_c.find(*di));
337 const_c.begin(nb) != const_c.end(nb)
343 BOOST_CHECK( c.load_factor() < c.max_load_factor() );
345 c.max_load_factor(0.75);
347 BOOST_CHECK( c.max_load_factor() == 0.75 );
353 template< class Container, class Data >
354 void test_pair_ordered_associative_container_equality(Container & c, const Data & d)
356 BOOST_CHECK( std::equal( c. begin(), c. end(), d. begin() ) );
357 BOOST_CHECK( std::equal( c.rbegin(), c.rend(), d.rbegin() ) );
359 BOOST_CHECK( c.lower_bound( d.begin()->first ) == c.begin() );
360 BOOST_CHECK( c.upper_bound( d.begin()->first ) == ++c.begin() );
363 template< class Container, class Data >
364 void test_pair_ordered_associative_container(Container & c, const Data & d)
366 assert( d.size() > 2 );
369 c.insert(d.begin(),d.end());
371 for( typename Container::const_iterator ci = c.begin(), ce = c.end();
374 typename Data::const_iterator di = d.find(ci->first);
375 BOOST_CHECK( di != d.end() );
376 BOOST_CHECK( ! c.key_comp()(di->first,ci->first) );
377 BOOST_CHECK( ! c.value_comp()(*ci,*di) );
380 test_pair_ordered_associative_container_equality(c, d);
382 const Container & cr = c;
384 test_pair_ordered_associative_container_equality(cr, d);
386 BOOST_CHECK( c.range( c.begin()->first <= ::boost::lambda::_1,
387 ::boost::lambda::_1 <= (++c.begin())->first ).
393 template< class Container, class Data >
394 void test_pair_unordered_associative_container(Container & c, const Data & d)
397 c.insert( d.begin(), d.end() );
399 BOOST_CHECK( c.bucket_count() * c.max_load_factor() >= d.size() );
400 BOOST_CHECK( c.max_bucket_count() >= c.bucket_count() );
402 for( typename Data::const_iterator di = d.begin(), de = d.end() ;
407 typename Container::size_type nb =
408 c.bucket(c.find(di->first)->first);
410 BOOST_CHECK( c.begin(nb) != c.end(nb) );
415 const Container & const_c = c;
417 BOOST_CHECK( const_c.bucket_size(const_c.bucket(di->first)) == 1 );
419 typename Container::size_type nb =
420 const_c.bucket(const_c.find(di->first)->first);
422 BOOST_CHECK( const_c.begin(nb) != const_c.end(nb) );
427 BOOST_CHECK( c.load_factor() < c.max_load_factor() );
429 c.max_load_factor(0.75);
431 BOOST_CHECK( c.max_load_factor() == 0.75 );
437 template< class Container, class Data >
438 void test_unique_container(Container & c, Data & d)
441 c.insert(d.begin(),d.end());
442 c.insert(*d.begin());
443 BOOST_CHECK( c.size() == d.size() );
446 template< class Container, class Data >
447 void test_non_unique_container(Container & c, Data & d)
450 c.insert(d.begin(),d.end());
451 c.insert(*d.begin());
452 BOOST_CHECK( c.size() == (d.size()+1) );
457 template< class Bimap, class Data, class LeftData, class RightData >
458 void test_basic_bimap( Bimap & b,
460 const LeftData & ld, const RightData & rd)
462 using namespace boost::bimaps;
466 BOOST_CHECK( & b.left == & b.template by<member_at::left >() );
467 BOOST_CHECK( & b.right == & b.template by<member_at::right>() );
469 test_container(b.left , ld);
470 test_container(b.right, rd);
473 template< class LeftTag, class RightTag, class Bimap, class Data >
474 void test_tagged_bimap(Bimap & b,
477 using namespace boost::bimaps;
479 BOOST_CHECK( &b.left == & b.template by<LeftTag >() );
480 BOOST_CHECK( &b.right == & b.template by<RightTag>() );
483 b.insert( *d.begin() );
486 b.begin()->template get<LeftTag>() ==
487 b.template by<RightTag>().begin()->template get<LeftTag>()
491 b.begin()->template get<RightTag>() ==
492 b.template by<LeftTag>().begin()->template get<RightTag>()
498 const Bimap & bc = b;
500 BOOST_CHECK( &bc.left == & bc.template by<LeftTag>() );
501 BOOST_CHECK( &bc.right == & bc.template by<RightTag>() );
503 BOOST_CHECK( bc.begin()->template get<LeftTag>() ==
504 bc.template by<RightTag>().begin()->template get<LeftTag>() );
506 BOOST_CHECK( bc.begin()->template get<RightTag>() ==
507 bc.template by<LeftTag>().begin()->template get<RightTag>() );
512 template< class Bimap, class Data, class LeftData, class RightData >
513 void test_set_set_bimap(Bimap & b,
515 const LeftData & ld, const RightData & rd)
517 using namespace boost::bimaps;
519 test_basic_bimap(b,d,ld,rd);
521 test_associative_container(b,d);
522 test_simple_ordered_associative_container(b,d);
524 test_pair_associative_container(b.left, ld);
525 test_pair_ordered_associative_container(b.left, ld);
526 test_unique_container(b.left, ld);
528 test_pair_associative_container(b.right, rd);
529 test_pair_ordered_associative_container(b.right, rd);
530 test_unique_container(b.right, rd);
535 template< class Bimap, class Data, class LeftData, class RightData >
536 void test_multiset_multiset_bimap(Bimap & b,
538 const LeftData & ld, const RightData & rd)
540 using namespace boost::bimaps;
542 test_basic_bimap(b,d,ld,rd);
543 test_associative_container(b,d);
544 test_simple_ordered_associative_container(b,d);
546 test_pair_associative_container(b.left, ld);
547 test_pair_ordered_associative_container(b.left, ld);
548 test_non_unique_container(b.left, ld);
550 test_pair_associative_container(b.right, rd);
551 test_pair_ordered_associative_container(b.right, rd);
552 test_non_unique_container(b.right, rd);
555 template< class Bimap, class Data, class LeftData, class RightData >
556 void test_unordered_set_unordered_multiset_bimap(Bimap & b,
559 const RightData & rd)
561 using namespace boost::bimaps;
563 test_basic_bimap(b,d,ld,rd);
564 test_associative_container(b,d);
565 test_simple_unordered_associative_container(b,d);
567 test_pair_associative_container(b.left, ld);
568 test_pair_unordered_associative_container(b.left, ld);
569 test_unique_container(b.left, ld);
571 test_pair_associative_container(b.right, rd);
572 test_pair_unordered_associative_container(b.right, rd);
574 // Caution, this side is a non unique container, but the other side is a
575 // unique container so, the overall bimap is a unique one.
576 test_unique_container(b.right, rd);
579 template< class Bimap, class Data>
580 void test_bimap_init_copy_swap(const Data&d)
582 Bimap b1(d.begin(),d.end());
584 BOOST_CHECK( b1 == b2 );
588 BOOST_CHECK( b2 == b1 );
592 BOOST_CHECK( b2 == b1 );
596 BOOST_CHECK( b2 == b1 );
600 BOOST_CHECK( b2.empty() && !b1.empty() );
602 b1.left.swap( b2.left );
603 BOOST_CHECK( b1.empty() && !b2.empty() );
605 b1.right.swap( b2.right );
606 BOOST_CHECK( b2.empty() && !b1.empty() );
609 #endif // LIBS_BIMAP_TEST_BIMAP_TEST_HPP