test_update.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /* Boost.MultiIndex test for replace(), modify() and modify_key().
  2. *
  3. * Copyright 2003-2018 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_update.hpp"
  11. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  12. #include <algorithm>
  13. #include <cstddef>
  14. #include "pre_multi_index.hpp"
  15. #include "employee.hpp"
  16. #include "pair_of_ints.hpp"
  17. #include <boost/detail/lightweight_test.hpp>
  18. #include <boost/next_prior.hpp>
  19. struct do_nothing
  20. {
  21. template<typename T>
  22. void operator()(const T&)const{}
  23. };
  24. struct null_hash
  25. {
  26. template<typename T>
  27. std::size_t operator()(const T&)const{return 0;}
  28. };
  29. struct assign_value
  30. {
  31. assign_value(int n):n_(n){}
  32. void operator()(int& x)const{x=n_;}
  33. int n_;
  34. };
  35. template<class MultiIndexContainer>
  36. void test_stable_update()
  37. {
  38. typedef typename MultiIndexContainer::iterator iterator;
  39. typedef typename MultiIndexContainer::size_type size_type;
  40. typedef typename MultiIndexContainer::difference_type difference_type;
  41. MultiIndexContainer c;
  42. c.insert(0);
  43. c.insert(1);c.insert(1);
  44. c.insert(2);c.insert(2);c.insert(2);c.insert(2);
  45. c.insert(3);
  46. c.insert(4);c.insert(4);c.insert(4);
  47. c.insert(5);c.insert(5);
  48. c.insert(6);
  49. c.insert(7);
  50. size_type num_elems=
  51. c.count(0)+c.count(1)+c.count(2)+c.count(3)+
  52. c.count(4)+c.count(5)+c.count(6)+c.count(7);
  53. for(size_type n=c.size();n--;){
  54. iterator it=boost::next(c.begin(),(difference_type)n);
  55. c.replace(it,*it);
  56. BOOST_TEST((size_type)std::distance(c.begin(),it)==n);
  57. c.modify(it,do_nothing());
  58. BOOST_TEST((size_type)std::distance(c.begin(),it)==n);
  59. c.modify(it,do_nothing(),do_nothing());
  60. BOOST_TEST((size_type)std::distance(c.begin(),it)==n);
  61. for(int i=0;i<=8;++i){
  62. MultiIndexContainer cpy(c);
  63. bool b=c.modify(it,assign_value(i),assign_value(*it));
  64. BOOST_TEST(b||(size_type)std::distance(c.begin(),it)==n);
  65. BOOST_TEST(c.count(0)+c.count(1)+c.count(2)+c.count(3)+c.count(4)+
  66. c.count(5)+c.count(6)+c.count(7)+c.count(8)==num_elems);
  67. if(b){
  68. c=cpy;
  69. it=boost::next(c.begin(),(difference_type)n);
  70. }
  71. }
  72. }
  73. }
  74. using namespace boost::multi_index;
  75. void test_update()
  76. {
  77. employee_set es;
  78. employee_set_as_inserted& i=get<as_inserted>(es);
  79. employee_set_randomly& r=get<randomly>(es);
  80. es.insert(employee(0,"Joe",31,1123));
  81. es.insert(employee(1,"Robert",27,5601));
  82. es.insert(employee(2,"John",40,7889));
  83. es.insert(employee(3,"Olbert",20,9012));
  84. es.insert(employee(4,"John",57,1002));
  85. employee_set::iterator it=es.find(employee(0,"Joe",31,1123));
  86. employee_set_as_inserted::iterator it1=
  87. project<as_inserted>(es,get<name>(es).find("Olbert"));
  88. employee_set_randomly::iterator it2=
  89. project<randomly>(es,get<age>(es).find(57));
  90. BOOST_TEST(es.replace(it,*it));
  91. BOOST_TEST(i.replace(it1,*it1));
  92. BOOST_TEST(r.replace(it2,*it2));
  93. BOOST_TEST(!es.replace(it,employee(3,"Joe",31,1123))&&it->id==0);
  94. BOOST_TEST(es.replace(it,employee(0,"Joe",32,1123))&&it->age==32);
  95. BOOST_TEST(i.replace(it1,employee(3,"Albert",20,9012))&&it1->name==
  96. "Albert");
  97. BOOST_TEST(!r.replace(it2,employee(4,"John",57,5601)));
  98. {
  99. typedef multi_index_container<
  100. pair_of_ints,
  101. indexed_by<
  102. ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
  103. hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)>,
  104. sequenced<> > >
  105. int_int_set;
  106. int_int_set iis;
  107. nth_index<int_int_set,1>::type& ii1=get<1>(iis);
  108. nth_index<int_int_set,2>::type& ii2=get<2>(iis);
  109. iis.insert(pair_of_ints(0,0));
  110. iis.insert(pair_of_ints(5,5));
  111. iis.insert(pair_of_ints(10,10));
  112. BOOST_TEST(!iis.replace(iis.begin(),pair_of_ints(5,0)));
  113. BOOST_TEST(!ii2.replace(ii2.begin(),pair_of_ints(0,5)));
  114. BOOST_TEST(!ii1.replace(project<1>(iis,iis.begin()),pair_of_ints(5,11)));
  115. BOOST_TEST(!iis.replace(iis.begin(),pair_of_ints(11,5)));
  116. BOOST_TEST(!iis.replace(boost::next(iis.begin()),pair_of_ints(10,5)));
  117. BOOST_TEST(!ii1.replace(
  118. project<1>(iis,boost::next(iis.begin())),pair_of_ints(5,10)));
  119. BOOST_TEST(!iis.replace(boost::prior(iis.end()),pair_of_ints(5,10)));
  120. BOOST_TEST(!ii2.replace(boost::prior(ii2.end()),pair_of_ints(10,5)));
  121. BOOST_TEST(iis.modify(iis.begin(),increment_first));
  122. BOOST_TEST(ii2.modify(ii2.begin(),increment_first));
  123. BOOST_TEST(ii1.modify(project<1>(iis,iis.begin()),increment_first));
  124. BOOST_TEST(ii2.modify(ii2.begin(),increment_first,decrement_first));
  125. BOOST_TEST(!iis.modify(iis.begin(),increment_first,decrement_first));
  126. BOOST_TEST(iis.size()==3);
  127. BOOST_TEST(!iis.modify(iis.begin(),increment_first));
  128. BOOST_TEST(iis.size()==2);
  129. iis.insert(pair_of_ints(0,0));
  130. BOOST_TEST(ii2.modify(boost::prior(ii2.end()),increment_second));
  131. BOOST_TEST(iis.modify(iis.begin(),increment_second));
  132. BOOST_TEST(ii2.modify(boost::prior(ii2.end()),increment_second));
  133. BOOST_TEST(iis.modify(iis.begin(),increment_second,decrement_second));
  134. BOOST_TEST(!ii2.modify(
  135. boost::prior(ii2.end()),increment_second,decrement_second));
  136. BOOST_TEST(ii2.size()==3);
  137. BOOST_TEST(!ii2.modify(boost::prior(ii2.end()),increment_second));
  138. BOOST_TEST(ii2.size()==2);
  139. iis.insert(pair_of_ints(0,0));
  140. BOOST_TEST(iis.modify_key(iis.begin(),increment_int));
  141. BOOST_TEST(iis.modify_key(iis.begin(),increment_int,decrement_int));
  142. BOOST_TEST(iis.modify_key(iis.begin(),increment_int));
  143. BOOST_TEST(iis.modify_key(iis.begin(),increment_int));
  144. BOOST_TEST(!iis.modify_key(iis.begin(),increment_int,decrement_int));
  145. BOOST_TEST(iis.size()==3);
  146. BOOST_TEST(!iis.modify_key(iis.begin(),increment_int));
  147. BOOST_TEST(iis.size()==2);
  148. nth_index_iterator<int_int_set,1>::type it_=ii1.find(5);
  149. BOOST_TEST(ii1.modify_key(it_,increment_int));
  150. BOOST_TEST(ii1.modify_key(it_,increment_int));
  151. BOOST_TEST(ii1.modify_key(it_,increment_int,decrement_int));
  152. BOOST_TEST(ii1.modify_key(it_,increment_int));
  153. BOOST_TEST(!ii1.modify_key(it_,increment_int,decrement_int));
  154. BOOST_TEST(ii1.size()==2);
  155. BOOST_TEST(!ii1.modify_key(it_,increment_int));
  156. BOOST_TEST(ii1.size()==1);
  157. }
  158. {
  159. typedef multi_index_container<
  160. pair_of_ints,
  161. indexed_by<
  162. hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
  163. random_access<>,
  164. ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)> > >
  165. int_int_set;
  166. int_int_set iis;
  167. nth_index<int_int_set,1>::type& ii1=get<1>(iis);
  168. int_int_set::iterator p1=iis.insert(pair_of_ints(0,0)).first;
  169. int_int_set::iterator p2=iis.insert(pair_of_ints(5,5)).first;
  170. int_int_set::iterator p3=iis.insert(pair_of_ints(10,10)).first;
  171. BOOST_TEST(!iis.replace(p1,pair_of_ints(5,0)));
  172. BOOST_TEST(!ii1.replace(ii1.begin(),pair_of_ints(0,5)));
  173. BOOST_TEST(!iis.replace(p1,pair_of_ints(5,11)));
  174. BOOST_TEST(!iis.replace(p1,pair_of_ints(11,5)));
  175. BOOST_TEST(!iis.replace(p2,pair_of_ints(10,5)));
  176. BOOST_TEST(!iis.replace(p2,pair_of_ints(5,10)));
  177. BOOST_TEST(!iis.replace(p3,pair_of_ints(5,10)));
  178. BOOST_TEST(!ii1.replace(boost::prior(ii1.end()),pair_of_ints(10,5)));
  179. BOOST_TEST(iis.modify(p1,increment_first));
  180. BOOST_TEST(ii1.modify(ii1.begin(),increment_first));
  181. BOOST_TEST(iis.modify(p1,increment_first));
  182. BOOST_TEST(ii1.modify(ii1.begin(),increment_first,decrement_first));
  183. BOOST_TEST(!iis.modify(p1,increment_first,decrement_first));
  184. BOOST_TEST(iis.size()==3);
  185. BOOST_TEST(!iis.modify(p1,increment_first));
  186. BOOST_TEST(iis.size()==2);
  187. p1=iis.insert(pair_of_ints(0,0)).first;
  188. BOOST_TEST(ii1.modify(boost::prior(ii1.end()),increment_second));
  189. BOOST_TEST(iis.modify(p1,increment_second,decrement_second));
  190. BOOST_TEST(ii1.modify(boost::prior(ii1.end()),increment_second));
  191. BOOST_TEST(iis.modify(p1,increment_second));
  192. BOOST_TEST(!ii1.modify(
  193. boost::prior(ii1.end()),increment_second,decrement_second));
  194. BOOST_TEST(ii1.size()==3);
  195. BOOST_TEST(!ii1.modify(boost::prior(ii1.end()),increment_second));
  196. BOOST_TEST(ii1.size()==2);
  197. }
  198. {
  199. typedef multi_index_container<
  200. int,
  201. indexed_by<
  202. ordered_non_unique<identity<int> >
  203. >
  204. > int_multiset;
  205. test_stable_update<int_multiset>();
  206. typedef multi_index_container<
  207. int,
  208. indexed_by<
  209. hashed_unique<identity<int> >
  210. >
  211. > int_hashed_set;
  212. test_stable_update<int_hashed_set>();
  213. typedef multi_index_container<
  214. int,
  215. indexed_by<
  216. hashed_unique<identity<int> >
  217. >
  218. > int_hashed_multiset;
  219. test_stable_update<int_hashed_multiset>();
  220. typedef multi_index_container<
  221. int,
  222. indexed_by<
  223. hashed_unique<identity<int>,null_hash>
  224. >
  225. > degenerate_int_hashed_set;
  226. test_stable_update<degenerate_int_hashed_set>();
  227. typedef multi_index_container<
  228. int,
  229. indexed_by<
  230. hashed_non_unique<identity<int>,null_hash>
  231. >
  232. > degenerate_int_hashed_multiset;
  233. test_stable_update<degenerate_int_hashed_multiset>();
  234. }
  235. }