test_list_ops.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /* Boost.MultiIndex test for standard list operations.
  2. *
  3. * Copyright 2003-2013 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_list_ops.hpp"
  11. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  12. #include <algorithm>
  13. #include <vector>
  14. #include <boost/detail/lightweight_test.hpp>
  15. #include "pre_multi_index.hpp"
  16. #include <boost/multi_index_container.hpp>
  17. #include <boost/multi_index/identity.hpp>
  18. #include <boost/multi_index/ordered_index.hpp>
  19. #include <boost/multi_index/sequenced_index.hpp>
  20. #include <boost/multi_index/random_access_index.hpp>
  21. #include <boost/preprocessor/seq/enum.hpp>
  22. using namespace boost::multi_index;
  23. #undef CHECK_EQUAL
  24. #define CHECK_EQUAL(p,check_seq) \
  25. {\
  26. int v[]={BOOST_PP_SEQ_ENUM(check_seq)};\
  27. std::size_t size_v=sizeof(v)/sizeof(int);\
  28. BOOST_TEST(std::size_t(std::distance((p).begin(),(p).end()))==size_v);\
  29. BOOST_TEST(std::equal((p).begin(),(p).end(),&v[0]));\
  30. }
  31. #undef CHECK_VOID_RANGE
  32. #define CHECK_VOID_RANGE(p) BOOST_TEST((p).first==(p).second)
  33. struct is_even
  34. {
  35. bool operator()(int x)const{return x%2==0;}
  36. };
  37. template <int m>
  38. struct same_integral_div
  39. {
  40. bool operator()(int x,int y)const{return (x/m)==(y/m);}
  41. };
  42. template <typename Container,typename Compare>
  43. bool is_sorted(
  44. const Container& c,const Compare& comp=Compare())
  45. {
  46. if(c.empty())return true;
  47. typedef typename Container::const_iterator const_iterator;
  48. for(const_iterator it(c.begin());;){
  49. const_iterator it2=it;
  50. ++it2;
  51. if(it2==c.end())return true;
  52. if(comp(*it2,*it))return false;
  53. it=it2;
  54. }
  55. }
  56. #if BOOST_WORKAROUND(__MWERKS__,<=0x3003)
  57. /* The "ISO C++ Template Parser" option makes CW8.3 incorrectly fail at
  58. * expressions of the form sizeof(x) where x is an array local to a
  59. * template function.
  60. */
  61. #pragma parse_func_templ off
  62. #endif
  63. template<typename Sequence>
  64. static void test_list_ops_unique_seq()
  65. {
  66. typedef typename nth_index<Sequence,1>::type sequenced_index;
  67. Sequence ss,ss2;
  68. sequenced_index &si=get<1>(ss),&si2=get<1>(ss2);
  69. si.push_front(0); /* 0 */
  70. si.push_front(4); /* 40 */
  71. ss.insert(2); /* 402 */
  72. ss.insert(5); /* 4025 */
  73. si.push_front(3); /* 34025 */
  74. si.push_back(6); /* 340256 */
  75. si.push_back(1); /* 3402561 */
  76. si.insert(project<1>(ss,ss.find(2)),8); /* 34082561 */
  77. si2=si;
  78. CHECK_EQUAL(si,(3)(4)(0)(8)(2)(5)(6)(1));
  79. si.remove(8);
  80. CHECK_EQUAL(si,(3)(4)(0)(2)(5)(6)(1));
  81. si.remove_if(is_even());
  82. CHECK_EQUAL(si,(3)(5)(1));
  83. si.splice(si.end(),si2);
  84. CHECK_EQUAL(si,(3)(5)(1)(4)(0)(8)(2)(6));
  85. CHECK_EQUAL(si2,(3)(5)(1));
  86. si.splice(project<1>(ss,ss.find(4)),si,project<1>(ss,ss.find(8)));
  87. CHECK_EQUAL(si,(3)(5)(1)(8)(4)(0)(2)(6));
  88. si2.clear();
  89. si2.splice(si2.begin(),si,si.begin());
  90. si.splice(si.end(),si2,si2.begin());
  91. CHECK_EQUAL(si,(5)(1)(8)(4)(0)(2)(6)(3));
  92. BOOST_TEST(si2.empty());
  93. si2.splice(si2.end(),si,project<1>(ss,ss.find(0)),project<1>(ss,ss.find(6)));
  94. CHECK_EQUAL(si,(5)(1)(8)(4)(6)(3));
  95. CHECK_EQUAL(si2,(0)(2));
  96. si.splice(si.begin(),si,si.begin(),si.begin());
  97. CHECK_EQUAL(si,(5)(1)(8)(4)(6)(3));
  98. si.splice(project<1>(ss,ss.find(8)),si,project<1>(ss,ss.find(4)),si.end());
  99. CHECK_EQUAL(si,(5)(1)(4)(6)(3)(8));
  100. si.sort();
  101. si2.sort();
  102. BOOST_TEST(is_sorted(si,std::less<int>()));
  103. BOOST_TEST(is_sorted(si2,std::less<int>()));
  104. si.merge(si2);
  105. BOOST_TEST(is_sorted(si,std::less<int>()));
  106. BOOST_TEST(si2.empty());
  107. {
  108. Sequence ss3(ss);
  109. sequenced_index &si3=get<1>(ss3);
  110. si3.sort(std::greater<int>());
  111. si.reverse();
  112. BOOST_TEST(si==si3);
  113. }
  114. si2.splice(si2.end(),si,project<1>(ss,ss.find(6)),project<1>(ss,ss.find(3)));
  115. CHECK_EQUAL(si2,(6)(5)(4));
  116. si.merge(si2,std::greater<int>());
  117. BOOST_TEST(is_sorted(si,std::greater<int>()));
  118. BOOST_TEST(si2.empty());
  119. /* testcase for bug reported at
  120. * https://svn.boost.org/trac/boost/ticket/3076
  121. */
  122. {
  123. Sequence ss3;
  124. sequenced_index &si3=get<1>(ss3);
  125. si3.sort();
  126. }
  127. }
  128. template<typename Sequence>
  129. static void test_list_ops_non_unique_seq()
  130. {
  131. typedef typename Sequence::iterator iterator;
  132. Sequence ss;
  133. for(int i=0;i<10;++i){
  134. ss.push_back(i);
  135. ss.push_back(i);
  136. ss.push_front(i);
  137. ss.push_front(i);
  138. } /* 9988776655443322110000112233445566778899 */
  139. ss.unique();
  140. CHECK_EQUAL(
  141. ss,
  142. (9)(8)(7)(6)(5)(4)(3)(2)(1)(0)
  143. (1)(2)(3)(4)(5)(6)(7)(8)(9));
  144. iterator it=ss.begin();
  145. for(int j=0;j<9;++j,++it){} /* it points to o */
  146. Sequence ss2;
  147. ss2.splice(ss2.end(),ss,ss.begin(),it);
  148. ss2.reverse();
  149. ss.merge(ss2);
  150. CHECK_EQUAL(
  151. ss,
  152. (0)(1)(1)(2)(2)(3)(3)(4)(4)(5)(5)
  153. (6)(6)(7)(7)(8)(8)(9)(9));
  154. ss.unique(same_integral_div<3>());
  155. CHECK_EQUAL(ss,(0)(3)(6)(9));
  156. ss.unique(same_integral_div<1>());
  157. CHECK_EQUAL(ss,(0)(3)(6)(9));
  158. /* testcases for bugs reported at
  159. * http://lists.boost.org/boost-users/2006/09/22604.php
  160. */
  161. {
  162. Sequence ss_,ss2_;
  163. ss_.push_back(0);
  164. ss2_.push_back(0);
  165. ss_.splice(ss_.end(),ss2_,ss2_.begin());
  166. CHECK_EQUAL(ss_,(0)(0));
  167. BOOST_TEST(ss2_.empty());
  168. ss_.clear();
  169. ss2_.clear();
  170. ss_.push_back(0);
  171. ss2_.push_back(0);
  172. ss_.splice(ss_.end(),ss2_,ss2_.begin(),ss2_.end());
  173. CHECK_EQUAL(ss_,(0)(0));
  174. BOOST_TEST(ss2_.empty());
  175. ss_.clear();
  176. ss2_.clear();
  177. ss_.push_back(0);
  178. ss2_.push_back(0);
  179. ss_.merge(ss2_);
  180. CHECK_EQUAL(ss_,(0)(0));
  181. BOOST_TEST(ss2_.empty());
  182. typedef typename Sequence::value_type value_type;
  183. ss_.clear();
  184. ss2_.clear();
  185. ss_.push_back(0);
  186. ss2_.push_back(0);
  187. ss_.merge(ss2_,std::less<value_type>());
  188. CHECK_EQUAL(ss_,(0)(0));
  189. BOOST_TEST(ss2_.empty());
  190. }
  191. }
  192. #if BOOST_WORKAROUND(__MWERKS__,<=0x3003)
  193. #pragma parse_func_templ reset
  194. #endif
  195. void test_list_ops()
  196. {
  197. typedef multi_index_container<
  198. int,
  199. indexed_by<
  200. ordered_unique<identity<int> >,
  201. sequenced<>
  202. >
  203. > sequenced_set;
  204. test_list_ops_unique_seq<sequenced_set>();
  205. typedef multi_index_container<
  206. int,
  207. indexed_by<
  208. ordered_unique<identity<int> >,
  209. random_access<>
  210. >
  211. > random_access_set;
  212. test_list_ops_unique_seq<random_access_set>();
  213. typedef multi_index_container<
  214. int,
  215. indexed_by<sequenced<> >
  216. > int_list;
  217. test_list_ops_non_unique_seq<int_list>();
  218. typedef multi_index_container<
  219. int,
  220. indexed_by<random_access<> >
  221. > int_vector;
  222. test_list_ops_non_unique_seq<int_vector>();
  223. }