test_bimap.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. // Boost.Bimap
  2. //
  3. // Copyright (c) 2006-2007 Matias Capeletto
  4. //
  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)
  8. #ifndef LIBS_BIMAP_TEST_BIMAP_TEST_HPP
  9. #define LIBS_BIMAP_TEST_BIMAP_TEST_HPP
  10. #if defined(_MSC_VER)
  11. #pragma once
  12. #endif
  13. #include <boost/config.hpp>
  14. // std
  15. #include <cassert>
  16. #include <algorithm>
  17. #include <iterator>
  18. #include <boost/lambda/lambda.hpp>
  19. #include <boost/static_assert.hpp>
  20. #include <boost/type_traits/is_same.hpp>
  21. #include <boost/utility.hpp>
  22. #include <boost/next_prior.hpp>
  23. template< class Container, class Data >
  24. void test_container(Container & c, const Data & d)
  25. {
  26. assert( d.size() > 2 );
  27. c.clear();
  28. BOOST_CHECK( c.size() == 0 );
  29. BOOST_CHECK( c.empty() );
  30. c.insert( *d.begin() );
  31. c.insert( ++d.begin(),d.end() );
  32. BOOST_CHECK( c.size() == d.size() );
  33. BOOST_CHECK( c.size() <= c.max_size() );
  34. BOOST_CHECK( ! c.empty() );
  35. c.erase( c.begin() );
  36. BOOST_CHECK( c.size() == d.size() - 1 );
  37. c.erase( c.begin(), c.end() );
  38. BOOST_CHECK( c.empty() );
  39. c.insert( *d.begin() );
  40. BOOST_CHECK( c.size() == 1 );
  41. c.insert( c.begin(), *(++d.begin()) );
  42. BOOST_CHECK( c.size() == 2 );
  43. BOOST_CHECK( c.begin() != c.end() );
  44. }
  45. template< class Container, class Data >
  46. void test_sequence_container(Container & c, const Data & d)
  47. {
  48. assert( d.size() > 2 );
  49. c.clear();
  50. BOOST_CHECK( c.size() == 0 );
  51. BOOST_CHECK( c.empty() );
  52. c.push_front( * d.begin() );
  53. c.push_back ( *(++d.begin()) );
  54. BOOST_CHECK( c.front() == * c.begin() );
  55. BOOST_CHECK( c.back () == *(++c.begin()) );
  56. BOOST_CHECK( c.size() == 2 );
  57. BOOST_CHECK( c.size() <= c.max_size() );
  58. BOOST_CHECK( ! c.empty() );
  59. c.erase( c.begin() );
  60. BOOST_CHECK( c.size() == 1 );
  61. c.insert( c.begin(), *(++d.begin()) );
  62. c.erase( c.begin(), c.end() );
  63. BOOST_CHECK( c.empty() );
  64. c.push_front( *d.begin() );
  65. BOOST_CHECK( c.size() == 1 );
  66. BOOST_CHECK( c.begin() != c.end() );
  67. c.clear();
  68. BOOST_CHECK( c.empty() );
  69. // assign
  70. c.assign(d.begin(),d.end());
  71. BOOST_CHECK( c.size() == d.size() );
  72. BOOST_CHECK( std::equal( c.begin(), c.end(), d.begin() ) );
  73. c.assign(d.size(),*d.begin());
  74. BOOST_CHECK( c.size() == d.size() );
  75. BOOST_CHECK( *c.begin() == *d.begin() );
  76. // Check insert(IterPos,InputIter,InputIter)
  77. c.clear();
  78. c.insert( c.begin(), d.begin(), d.end() );
  79. c.insert( boost::next(c.begin(),2), d.begin(), d.end() );
  80. BOOST_CHECK( std::equal( boost::next(c.begin(),2)
  81. , boost::next(c.begin(),2+d.size()) , d.begin() ) );
  82. // Check resize
  83. c.clear() ;
  84. c.resize(4,*d.begin());
  85. BOOST_CHECK( c.size() == 4 );
  86. BOOST_CHECK( *c.begin() == *d.begin() ) ;
  87. BOOST_CHECK( c == c );
  88. BOOST_CHECK( ! ( c != c ) );
  89. BOOST_CHECK( ! ( c < c ) );
  90. BOOST_CHECK( ( c <= c ) );
  91. BOOST_CHECK( ! ( c > c ) );
  92. BOOST_CHECK( ( c >= c ) );
  93. }
  94. template< class Container, class Data >
  95. void test_vector_container(Container & c, const Data & d)
  96. {
  97. assert( d.size() > 2 );
  98. c.clear() ;
  99. c.reserve(2) ;
  100. BOOST_CHECK( c.capacity() >= 2 ) ;
  101. c.assign(d.begin(),d.end());
  102. BOOST_CHECK( c.capacity() >= c.size() ) ;
  103. BOOST_CHECK( c[0] == *d.begin() ) ;
  104. BOOST_CHECK( c.at(1) == *boost::next(d.begin()) );
  105. test_sequence_container(c,d) ;
  106. }
  107. template< class Container, class Data >
  108. void test_associative_container(Container & c, const Data & d)
  109. {
  110. assert( d.size() > 2 );
  111. c.clear();
  112. c.insert(d.begin(),d.end());
  113. for( typename Data::const_iterator di = d.begin(), de = d.end();
  114. di != de; ++di )
  115. {
  116. BOOST_CHECK( c.find(*di) != c.end() );
  117. }
  118. typename Data::const_iterator da = d.begin();
  119. typename Data::const_iterator db = ++d.begin();
  120. c.erase(*da);
  121. BOOST_CHECK( c.size() == d.size()-1 );
  122. BOOST_CHECK( c.count(*da) == 0 );
  123. BOOST_CHECK( c.count(*db) == 1 );
  124. BOOST_CHECK( c.find(*da) == c.end() );
  125. BOOST_CHECK( c.find(*db) != c.end() );
  126. BOOST_CHECK( c.equal_range(*db).first != c.end() );
  127. c.clear();
  128. BOOST_CHECK( c.equal_range(*da).first == c.end() );
  129. }
  130. template< class Container >
  131. void test_mapped_container(Container &)
  132. {
  133. typedef BOOST_DEDUCED_TYPENAME Container:: value_type value_type ;
  134. typedef BOOST_DEDUCED_TYPENAME Container:: key_type key_type ;
  135. typedef BOOST_DEDUCED_TYPENAME Container:: data_type data_type ;
  136. typedef BOOST_DEDUCED_TYPENAME Container::mapped_type mapped_type ;
  137. typedef BOOST_DEDUCED_TYPENAME
  138. boost::is_same< key_type
  139. , BOOST_DEDUCED_TYPENAME value_type::first_type
  140. >::type test_key_type;
  141. BOOST_STATIC_ASSERT(test_key_type::value);
  142. typedef BOOST_DEDUCED_TYPENAME
  143. boost::is_same< data_type
  144. , BOOST_DEDUCED_TYPENAME value_type::second_type
  145. >::type test_data_type;
  146. BOOST_STATIC_ASSERT(test_data_type::value);
  147. typedef BOOST_DEDUCED_TYPENAME
  148. boost::is_same< mapped_type
  149. , BOOST_DEDUCED_TYPENAME value_type::second_type
  150. >::type test_mapped_type;
  151. BOOST_STATIC_ASSERT(test_mapped_type::value);
  152. }
  153. template< class Container, class Data >
  154. void test_pair_associative_container(Container & c, const Data & d)
  155. {
  156. test_mapped_container(c);
  157. assert( d.size() > 2 );
  158. c.clear();
  159. c.insert(d.begin(),d.end());
  160. for( typename Data::const_iterator di = d.begin(), de = d.end();
  161. di != de; ++di )
  162. {
  163. BOOST_CHECK( c.find(di->first) != c.end() );
  164. }
  165. typename Data::const_iterator da = d.begin();
  166. typename Data::const_iterator db = ++d.begin();
  167. c.erase(da->first);
  168. BOOST_CHECK( c.size() == d.size()-1 );
  169. BOOST_CHECK( c.count(da->first) == 0 );
  170. BOOST_CHECK( c.count(db->first) == 1 );
  171. BOOST_CHECK( c.find(da->first) == c.end() );
  172. BOOST_CHECK( c.find(db->first) != c.end() );
  173. BOOST_CHECK( c.equal_range(db->first).first != c.end() );
  174. c.clear();
  175. BOOST_CHECK( c.equal_range(da->first).first == c.end() );
  176. }
  177. template< class Container, class Data >
  178. void test_simple_ordered_associative_container_equality(Container & c, const Data & d)
  179. {
  180. BOOST_CHECK( std::equal( c. begin(), c. end(), d. begin() ) );
  181. BOOST_CHECK( std::equal( c.rbegin(), c.rend(), d.rbegin() ) );
  182. BOOST_CHECK( c.lower_bound( *d.begin() ) == c.begin() );
  183. BOOST_CHECK( c.upper_bound( *d.begin() ) == ++c.begin() );
  184. }
  185. template< class Container, class Data >
  186. void test_simple_ordered_associative_container(Container & c, const Data & d)
  187. {
  188. assert( d.size() > 2 );
  189. c.clear();
  190. c.insert(d.begin(),d.end());
  191. for( typename Data::const_iterator di = d.begin(), de = d.end();
  192. di != de; ++di )
  193. {
  194. typename Container::const_iterator ci = c.find(*di);
  195. BOOST_CHECK( ci != c.end() );
  196. BOOST_CHECK( ! c.key_comp()(*ci,*di) );
  197. BOOST_CHECK( ! c.value_comp()(*ci,*di) );
  198. }
  199. test_simple_ordered_associative_container_equality(c, d);
  200. const Container & cr = c;
  201. test_simple_ordered_associative_container_equality(cr, d);
  202. BOOST_CHECK( c == c );
  203. BOOST_CHECK( ! ( c != c ) );
  204. BOOST_CHECK( ! ( c < c ) );
  205. BOOST_CHECK( ( c <= c ) );
  206. BOOST_CHECK( ! ( c > c ) );
  207. BOOST_CHECK( ( c >= c ) );
  208. /*
  209. BOOST_CHECK( c.range( *c.begin() <= ::boost::lambda::_1,
  210. ::boost::lambda::_1 <= *(++c.begin()) ).
  211. first == c.begin()
  212. );
  213. */
  214. }
  215. template< class Container, class Data >
  216. void test_simple_unordered_associative_container(Container & c, const Data & d)
  217. {
  218. c.clear();
  219. c.insert( d.begin(), d.end() );
  220. BOOST_CHECK( c.bucket_count() * c.max_load_factor() >= d.size() );
  221. BOOST_CHECK( c.max_bucket_count() >= c.bucket_count() );
  222. for( typename Data::const_iterator di = d.begin(), de = d.end() ;
  223. di != de ; ++di )
  224. {
  225. // non const
  226. {
  227. typename Container::size_type nb = c.bucket(*c.find(*di));
  228. BOOST_CHECK( c.begin(nb) != c.end(nb) );
  229. }
  230. // const
  231. {
  232. const Container & const_c = c;
  233. BOOST_CHECK(
  234. const_c.bucket_size(const_c.bucket(*di)) == 1
  235. );
  236. typename Container::size_type nb =
  237. const_c.bucket(*const_c.find(*di));
  238. BOOST_CHECK(
  239. const_c.begin(nb) != const_c.end(nb)
  240. );
  241. }
  242. }
  243. BOOST_CHECK( c.load_factor() < c.max_load_factor() );
  244. c.max_load_factor(0.75);
  245. BOOST_CHECK( c.max_load_factor() == 0.75 );
  246. c.rehash(10);
  247. }
  248. template< class Container, class Data >
  249. void test_pair_ordered_associative_container_equality(Container & c, const Data & d)
  250. {
  251. BOOST_CHECK( std::equal( c. begin(), c. end(), d. begin() ) );
  252. BOOST_CHECK( std::equal( c.rbegin(), c.rend(), d.rbegin() ) );
  253. BOOST_CHECK( c.lower_bound( d.begin()->first ) == c.begin() );
  254. BOOST_CHECK( c.upper_bound( d.begin()->first ) == ++c.begin() );
  255. }
  256. template< class Container, class Data >
  257. void test_pair_ordered_associative_container(Container & c, const Data & d)
  258. {
  259. assert( d.size() > 2 );
  260. c.clear();
  261. c.insert(d.begin(),d.end());
  262. for( typename Container::const_iterator ci = c.begin(), ce = c.end();
  263. ci != ce; ++ci )
  264. {
  265. typename Data::const_iterator di = d.find(ci->first);
  266. BOOST_CHECK( di != d.end() );
  267. BOOST_CHECK( ! c.key_comp()(di->first,ci->first) );
  268. BOOST_CHECK( ! c.value_comp()(*ci,*di) );
  269. }
  270. test_pair_ordered_associative_container_equality(c, d);
  271. const Container & cr = c;
  272. test_pair_ordered_associative_container_equality(cr, d);
  273. BOOST_CHECK( c.range( c.begin()->first <= ::boost::lambda::_1,
  274. ::boost::lambda::_1 <= (++c.begin())->first ).
  275. first == c.begin()
  276. );
  277. }
  278. template< class Container, class Data >
  279. void test_pair_unordered_associative_container(Container & c, const Data & d)
  280. {
  281. c.clear();
  282. c.insert( d.begin(), d.end() );
  283. BOOST_CHECK( c.bucket_count() * c.max_load_factor() >= d.size() );
  284. BOOST_CHECK( c.max_bucket_count() >= c.bucket_count() );
  285. for( typename Data::const_iterator di = d.begin(), de = d.end() ;
  286. di != de ; ++di )
  287. {
  288. // non const
  289. {
  290. typename Container::size_type nb =
  291. c.bucket(c.find(di->first)->first);
  292. BOOST_CHECK( c.begin(nb) != c.end(nb) );
  293. }
  294. // const
  295. {
  296. const Container & const_c = c;
  297. BOOST_CHECK( const_c.bucket_size(const_c.bucket(di->first)) == 1 );
  298. typename Container::size_type nb =
  299. const_c.bucket(const_c.find(di->first)->first);
  300. BOOST_CHECK( const_c.begin(nb) != const_c.end(nb) );
  301. }
  302. }
  303. BOOST_CHECK( c.load_factor() < c.max_load_factor() );
  304. c.max_load_factor(0.75);
  305. BOOST_CHECK( c.max_load_factor() == 0.75 );
  306. c.rehash(10);
  307. }
  308. template< class Container, class Data >
  309. void test_unique_container(Container & c, Data & d)
  310. {
  311. c.clear();
  312. c.insert(d.begin(),d.end());
  313. c.insert(*d.begin());
  314. BOOST_CHECK( c.size() == d.size() );
  315. }
  316. template< class Container, class Data >
  317. void test_non_unique_container(Container & c, Data & d)
  318. {
  319. c.clear();
  320. c.insert(d.begin(),d.end());
  321. c.insert(*d.begin());
  322. BOOST_CHECK( c.size() == (d.size()+1) );
  323. }
  324. template< class Bimap, class Data, class LeftData, class RightData >
  325. void test_basic_bimap( Bimap & b,
  326. const Data & d,
  327. const LeftData & ld, const RightData & rd)
  328. {
  329. using namespace boost::bimaps;
  330. test_container(b,d);
  331. BOOST_CHECK( & b.left == & b.template by<member_at::left >() );
  332. BOOST_CHECK( & b.right == & b.template by<member_at::right>() );
  333. test_container(b.left , ld);
  334. test_container(b.right, rd);
  335. }
  336. template< class LeftTag, class RightTag, class Bimap, class Data >
  337. void test_tagged_bimap(Bimap & b,
  338. const Data & d)
  339. {
  340. using namespace boost::bimaps;
  341. BOOST_CHECK( &b.left == & b.template by<LeftTag >() );
  342. BOOST_CHECK( &b.right == & b.template by<RightTag>() );
  343. b.clear();
  344. b.insert( *d.begin() );
  345. BOOST_CHECK(
  346. b.begin()->template get<LeftTag>() ==
  347. b.template by<RightTag>().begin()->template get<LeftTag>()
  348. );
  349. BOOST_CHECK(
  350. b.begin()->template get<RightTag>() ==
  351. b.template by<LeftTag>().begin()->template get<RightTag>()
  352. );
  353. // const test
  354. {
  355. const Bimap & bc = b;
  356. BOOST_CHECK( &bc.left == & bc.template by<LeftTag>() );
  357. BOOST_CHECK( &bc.right == & bc.template by<RightTag>() );
  358. BOOST_CHECK( bc.begin()->template get<LeftTag>() ==
  359. bc.template by<RightTag>().begin()->template get<LeftTag>() );
  360. BOOST_CHECK( bc.begin()->template get<RightTag>() ==
  361. bc.template by<LeftTag>().begin()->template get<RightTag>() );
  362. }
  363. }
  364. template< class Bimap, class Data, class LeftData, class RightData >
  365. void test_set_set_bimap(Bimap & b,
  366. const Data & d,
  367. const LeftData & ld, const RightData & rd)
  368. {
  369. using namespace boost::bimaps;
  370. test_basic_bimap(b,d,ld,rd);
  371. test_associative_container(b,d);
  372. test_simple_ordered_associative_container(b,d);
  373. test_pair_associative_container(b.left, ld);
  374. test_pair_ordered_associative_container(b.left, ld);
  375. test_unique_container(b.left, ld);
  376. test_pair_associative_container(b.right, rd);
  377. test_pair_ordered_associative_container(b.right, rd);
  378. test_unique_container(b.right, rd);
  379. }
  380. template< class Bimap, class Data, class LeftData, class RightData >
  381. void test_multiset_multiset_bimap(Bimap & b,
  382. const Data & d,
  383. const LeftData & ld, const RightData & rd)
  384. {
  385. using namespace boost::bimaps;
  386. test_basic_bimap(b,d,ld,rd);
  387. test_associative_container(b,d);
  388. test_simple_ordered_associative_container(b,d);
  389. test_pair_associative_container(b.left, ld);
  390. test_pair_ordered_associative_container(b.left, ld);
  391. test_non_unique_container(b.left, ld);
  392. test_pair_associative_container(b.right, rd);
  393. test_pair_ordered_associative_container(b.right, rd);
  394. test_non_unique_container(b.right, rd);
  395. }
  396. template< class Bimap, class Data, class LeftData, class RightData >
  397. void test_unordered_set_unordered_multiset_bimap(Bimap & b,
  398. const Data & d,
  399. const LeftData & ld,
  400. const RightData & rd)
  401. {
  402. using namespace boost::bimaps;
  403. test_basic_bimap(b,d,ld,rd);
  404. test_associative_container(b,d);
  405. test_simple_unordered_associative_container(b,d);
  406. test_pair_associative_container(b.left, ld);
  407. test_pair_unordered_associative_container(b.left, ld);
  408. test_unique_container(b.left, ld);
  409. test_pair_associative_container(b.right, rd);
  410. test_pair_unordered_associative_container(b.right, rd);
  411. // Caution, this side is a non unique container, but the other side is a
  412. // unique container so, the overall bimap is a unique one.
  413. test_unique_container(b.right, rd);
  414. }
  415. template< class Bimap, class Data>
  416. void test_bimap_init_copy_swap(const Data&d)
  417. {
  418. Bimap b1(d.begin(),d.end());
  419. Bimap b2( b1 );
  420. BOOST_CHECK( b1 == b2 );
  421. b2.clear();
  422. b2 = b1;
  423. BOOST_CHECK( b2 == b1 );
  424. b2.clear();
  425. b2.left = b1.left;
  426. BOOST_CHECK( b2 == b1 );
  427. b2.clear();
  428. b2.right = b1.right;
  429. BOOST_CHECK( b2 == b1 );
  430. b1.clear();
  431. b2.swap(b1);
  432. BOOST_CHECK( b2.empty() && !b1.empty() );
  433. b1.left.swap( b2.left );
  434. BOOST_CHECK( b1.empty() && !b2.empty() );
  435. b1.right.swap( b2.right );
  436. BOOST_CHECK( b2.empty() && !b1.empty() );
  437. }
  438. #endif // LIBS_BIMAP_TEST_BIMAP_TEST_HPP