test_rank_ops.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /* Boost.MultiIndex test for rank operations.
  2. *
  3. * Copyright 2003-2017 Joaquin M Lopez Munoz.
  4. * Distributed under the Boost Software License, Version 1.0.
  5. * (See accompanying file LICENSE_1_0.txt or copy at
  6. * http://www.boost.org/LICENSE_1_0.txt)
  7. *
  8. * See http://www.boost.org/libs/multi_index for library home page.
  9. */
  10. #include "test_rank_ops.hpp"
  11. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  12. #include <algorithm>
  13. #include <iterator>
  14. #include <set>
  15. #include <boost/detail/lightweight_test.hpp>
  16. #include "pre_multi_index.hpp"
  17. #include <boost/multi_index_container.hpp>
  18. #include <boost/multi_index/identity.hpp>
  19. #include <boost/multi_index/ranked_index.hpp>
  20. using namespace boost::multi_index;
  21. template<
  22. typename Sequence1,typename Iterator2,typename Sequence2
  23. >
  24. bool same_position(
  25. std::size_t n1,const Sequence1& s1,Iterator2 it2,const Sequence2& s2)
  26. {
  27. typedef typename Sequence1::const_iterator const_iterator1;
  28. typedef typename Sequence2::const_iterator const_iterator2;
  29. const_iterator1 cit1=s1.begin();
  30. std::advance(cit1,n1);
  31. const_iterator2 cit2=it2;
  32. return std::distance(s1.begin(),cit1)==std::distance(s2.begin(),cit2);
  33. }
  34. struct less_equal_than
  35. {
  36. less_equal_than(int n_):n(n_){}
  37. bool operator()(int x)const{return x<=n;}
  38. int n;
  39. };
  40. struct greater_equal_than
  41. {
  42. greater_equal_than(int n_):n(n_){}
  43. bool operator()(int x)const{return x>=n;}
  44. int n;
  45. };
  46. template<typename Sequence>
  47. static void local_test_rank_ops()
  48. {
  49. int data[]={2,2,1,5,6,7,9,10,9,6,9,6,9};
  50. Sequence s(data,data+sizeof(data)/sizeof(data[0]));
  51. std::multiset<int> ss(s.begin(),s.end());
  52. typedef typename Sequence::iterator iterator;
  53. iterator it=s.begin();
  54. for(std::size_t n=0;n<=s.size()+1;++n){
  55. BOOST_TEST(s.nth(n)==it);
  56. BOOST_TEST(s.rank(it)==(std::min)(s.size(),n));
  57. if(it!=s.end())++it;
  58. }
  59. std::pair<std::size_t,std::size_t> p1;
  60. std::pair<iterator,iterator> p2;
  61. p1=s.range_rank(unbounded,unbounded);
  62. p2=s.range(unbounded,unbounded);
  63. BOOST_TEST(same_position(p1.first,s,p2.first,s));
  64. BOOST_TEST(same_position(p1.second,s,p2.second,s));
  65. for(int i=0;i<12;++i){
  66. std::size_t pos=s.find_rank(i);
  67. BOOST_TEST((pos==s.size()&&ss.find(i)==ss.end())||(*s.nth(pos)==i));
  68. BOOST_TEST(same_position(s.lower_bound_rank(i),s,ss.lower_bound(i),ss));
  69. BOOST_TEST(same_position(s.upper_bound_rank(i),s,ss.upper_bound(i),ss));
  70. std::pair<std::size_t,std::size_t> posp=s.equal_range_rank(i);
  71. BOOST_TEST(same_position(posp.first,s,ss.lower_bound(i),ss));
  72. BOOST_TEST(same_position(posp.second,s,ss.upper_bound(i),ss));
  73. p1=s.range_rank(greater_equal_than(i),unbounded);
  74. p2=s.range(greater_equal_than(i),unbounded);
  75. BOOST_TEST(same_position(p1.first,s,p2.first,s));
  76. BOOST_TEST(same_position(p1.second,s,p2.second,s));
  77. p1=s.range_rank(unbounded,less_equal_than(i));
  78. p2=s.range(unbounded,less_equal_than(i));
  79. BOOST_TEST(same_position(p1.first,s,p2.first,s));
  80. BOOST_TEST(same_position(p1.second,s,p2.second,s));
  81. for(int j=0;j<12;++j){
  82. p1=s.range_rank(greater_equal_than(i),less_equal_than(j));
  83. p2=s.range(greater_equal_than(i),less_equal_than(j));
  84. BOOST_TEST(same_position(p1.first,s,p2.first,s));
  85. BOOST_TEST(same_position(p1.second,s,p2.second,s));
  86. }
  87. }
  88. Sequence se; /* empty */
  89. BOOST_TEST(se.nth(0)==se.end());
  90. BOOST_TEST(se.nth(1)==se.end());
  91. BOOST_TEST(se.rank(se.end())==0);
  92. BOOST_TEST(se.find_rank(0)==0);
  93. BOOST_TEST(se.lower_bound_rank(0)==0);
  94. BOOST_TEST(se.upper_bound_rank(0)==0);
  95. p1=se.equal_range_rank(0);
  96. BOOST_TEST(p1.first==0&&p1.second==0);
  97. p1=se.range_rank(unbounded,unbounded);
  98. BOOST_TEST(p1.first==0&&p1.second==0);
  99. p1=se.range_rank(greater_equal_than(0),unbounded);
  100. BOOST_TEST(p1.first==0&&p1.second==0);
  101. p1=se.range_rank(unbounded,less_equal_than(0));
  102. BOOST_TEST(p1.first==0&&p1.second==0);
  103. p1=se.range_rank(greater_equal_than(0),less_equal_than(0));
  104. BOOST_TEST(p1.first==0&&p1.second==0);
  105. }
  106. void test_rank_ops()
  107. {
  108. typedef multi_index_container<
  109. int,
  110. indexed_by<
  111. ranked_unique<identity<int> >
  112. >
  113. > ranked_set;
  114. local_test_rank_ops<ranked_set>();
  115. typedef multi_index_container<
  116. int,
  117. indexed_by<
  118. ranked_non_unique<identity<int> >
  119. >
  120. > ranked_multiset;
  121. local_test_rank_ops<ranked_multiset>();
  122. /* testcase for https://svn.boost.org/trac/boost/ticket/12955 */
  123. typedef multi_index_container<
  124. int,
  125. indexed_by<
  126. ranked_unique<identity<int> >,
  127. ranked_non_unique<identity<int> >
  128. >
  129. > biranked_set;
  130. local_test_rank_ops<biranked_set>();
  131. }