list_test.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. ////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2006. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/container for documentation.
  8. //
  9. ////////////////////////////////////////
  10. #ifndef BOOST_CONTAINER_TEST_LIST_TEST_HEADER
  11. #define BOOST_CONTAINER_TEST_LIST_TEST_HEADER
  12. #include <boost/container/detail/config_begin.hpp>
  13. #include <boost/container/detail/iterator.hpp>
  14. #include "check_equal_containers.hpp"
  15. #include "print_container.hpp"
  16. #include "input_from_forward_iterator.hpp"
  17. #include <boost/move/utility_core.hpp>
  18. #include <boost/move/iterator.hpp>
  19. #include <boost/move/make_unique.hpp>
  20. #include <list>
  21. #include <functional> //std::greater
  22. namespace boost{
  23. namespace container {
  24. namespace test{
  25. template<class V1, class V2>
  26. bool list_copyable_only(V1 &, V2 &, boost::container::dtl::false_type)
  27. {
  28. return true;
  29. }
  30. //Function to check if both sets are equal
  31. template<class V1, class V2>
  32. bool list_copyable_only(V1 &boostlist, V2 &stdlist, boost::container::dtl::true_type)
  33. {
  34. typedef typename V1::value_type IntType;
  35. boostlist.insert(boostlist.end(), 50, IntType(1));
  36. stdlist.insert(stdlist.end(), 50, 1);
  37. if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
  38. {
  39. IntType move_me(1);
  40. boostlist.insert(boostlist.begin(), 50, boost::move(move_me));
  41. stdlist.insert(stdlist.begin(), 50, 1);
  42. if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
  43. }
  44. {
  45. IntType move_me(2);
  46. boostlist.assign(boostlist.size()/2, boost::move(move_me));
  47. stdlist.assign(stdlist.size()/2, 2);
  48. if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
  49. }
  50. {
  51. IntType move_me(3);
  52. boostlist.assign(boostlist.size()*3-1, boost::move(move_me));
  53. stdlist.assign(stdlist.size()*3-1, 3);
  54. if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
  55. }
  56. {
  57. IntType copy_me(3);
  58. const IntType ccopy_me(3);
  59. boostlist.push_front(copy_me);
  60. stdlist.push_front(int(3));
  61. boostlist.push_front(ccopy_me);
  62. stdlist.push_front(int(3));
  63. if(!test::CheckEqualContainers(boostlist, stdlist)) return false;
  64. }
  65. { //List(const List &)
  66. ::boost::movelib::unique_ptr<V1> const pv1 = ::boost::movelib::make_unique<V1>(boostlist);
  67. ::boost::movelib::unique_ptr<V2> const pv2 = ::boost::movelib::make_unique<V2>(stdlist);
  68. V1 &v1 = *pv1;
  69. V2 &v2 = *pv2;
  70. boostlist.clear();
  71. stdlist.clear();
  72. boostlist.assign(v1.begin(), v1.end());
  73. stdlist.assign(v2.begin(), v2.end());
  74. if(!test::CheckEqualContainers(boostlist, stdlist)) return 1;
  75. }
  76. { //List(const List &, alloc)
  77. ::boost::movelib::unique_ptr<V1> const pv1 = ::boost::movelib::make_unique<V1>(boostlist, typename V1::allocator_type());
  78. ::boost::movelib::unique_ptr<V2> const pv2 = ::boost::movelib::make_unique<V2>(stdlist);
  79. V1 &v1 = *pv1;
  80. V2 &v2 = *pv2;
  81. boostlist.clear();
  82. stdlist.clear();
  83. boostlist.assign(v1.begin(), v1.end());
  84. stdlist.assign(v2.begin(), v2.end());
  85. if(!test::CheckEqualContainers(boostlist, stdlist)) return 1;
  86. }
  87. return true;
  88. }
  89. template<bool DoublyLinked>
  90. struct list_push_data_function
  91. {
  92. template<class MyBoostList, class MyStdList>
  93. static int execute(int max, MyBoostList &boostlist, MyStdList &stdlist)
  94. {
  95. typedef typename MyBoostList::value_type IntType;
  96. for(int i = 0; i < max; ++i){
  97. IntType move_me(i);
  98. boostlist.push_back(boost::move(move_me));
  99. stdlist.push_back(i);
  100. boostlist.push_front(IntType(i));
  101. stdlist.push_front(int(i));
  102. }
  103. if(!CheckEqualContainers(boostlist, stdlist))
  104. return 1;
  105. return 0;
  106. }
  107. };
  108. template<>
  109. struct list_push_data_function<false>
  110. {
  111. template<class MyBoostList, class MyStdList>
  112. static int execute(int max, MyBoostList &boostlist, MyStdList &stdlist)
  113. {
  114. typedef typename MyBoostList::value_type IntType;
  115. for(int i = 0; i < max; ++i){
  116. IntType move_me(i);
  117. boostlist.push_front(boost::move(move_me));
  118. stdlist.push_front(i);
  119. boostlist.push_front(IntType(i));
  120. stdlist.push_front(int(i));
  121. }
  122. if(!CheckEqualContainers(boostlist, stdlist))
  123. return 1;
  124. return 0;
  125. }
  126. };
  127. template<bool DoublyLinked>
  128. struct list_pop_back_function
  129. {
  130. template<class MyStdList, class MyBoostList>
  131. static int execute(MyBoostList &boostlist, MyStdList &stdlist)
  132. {
  133. boostlist.pop_back();
  134. stdlist.pop_back();
  135. if(!CheckEqualContainers(boostlist, stdlist))
  136. return 1;
  137. return 0;
  138. }
  139. };
  140. template<>
  141. struct list_pop_back_function<false>
  142. {
  143. template<class MyStdList, class MyBoostList>
  144. static int execute(MyBoostList &boostlist, MyStdList &stdlist)
  145. {
  146. (void)boostlist; (void)stdlist;
  147. return 0;
  148. }
  149. };
  150. template<class MyBoostList
  151. ,bool DoublyLinked>
  152. int list_test (bool copied_allocators_equal = true)
  153. {
  154. typedef std::list<int> MyStdList;
  155. typedef typename MyBoostList::value_type IntType;
  156. const int max = 100;
  157. typedef list_push_data_function<DoublyLinked> push_data_t;
  158. { //List(n)
  159. ::boost::movelib::unique_ptr<MyBoostList> const pboostlist = ::boost::movelib::make_unique<MyBoostList>(100);
  160. ::boost::movelib::unique_ptr<MyStdList> const pstdlist = ::boost::movelib::make_unique<MyStdList>(100);
  161. if(!test::CheckEqualContainers(*pboostlist, *pstdlist)) return 1;
  162. }
  163. { //List(n, alloc)
  164. ::boost::movelib::unique_ptr<MyBoostList> const pboostlist = ::boost::movelib::make_unique<MyBoostList>(100, typename MyBoostList::allocator_type());
  165. ::boost::movelib::unique_ptr<MyStdList> const pstdlist = ::boost::movelib::make_unique<MyStdList>(100);
  166. if(!test::CheckEqualContainers(*pboostlist, *pstdlist)) return 1;
  167. }
  168. { //List(List &&)
  169. ::boost::movelib::unique_ptr<MyStdList> const stdlistp = ::boost::movelib::make_unique<MyStdList>(100);
  170. ::boost::movelib::unique_ptr<MyBoostList> const boostlistp = ::boost::movelib::make_unique<MyBoostList>(100);
  171. ::boost::movelib::unique_ptr<MyBoostList> const boostlistp2 = ::boost::movelib::make_unique<MyBoostList>(::boost::move(*boostlistp));
  172. if(!test::CheckEqualContainers(*boostlistp2, *stdlistp)) return 1;
  173. }
  174. { //List(List &&, alloc)
  175. ::boost::movelib::unique_ptr<MyStdList> const stdlistp = ::boost::movelib::make_unique<MyStdList>(100);
  176. ::boost::movelib::unique_ptr<MyBoostList> const boostlistp = ::boost::movelib::make_unique<MyBoostList>(100);
  177. ::boost::movelib::unique_ptr<MyBoostList> const boostlistp2 = ::boost::movelib::make_unique<MyBoostList>
  178. (::boost::move(*boostlistp), typename MyBoostList::allocator_type());
  179. if(!test::CheckEqualContainers(*boostlistp2, *stdlistp)) return 1;
  180. }
  181. { //List operator=(List &&)
  182. ::boost::movelib::unique_ptr<MyStdList> const stdlistp = ::boost::movelib::make_unique<MyStdList>(100);
  183. ::boost::movelib::unique_ptr<MyBoostList> const boostlistp = ::boost::movelib::make_unique<MyBoostList>(100);
  184. ::boost::movelib::unique_ptr<MyBoostList> const boostlistp2 = ::boost::movelib::make_unique<MyBoostList>();
  185. *boostlistp2 = ::boost::move(*boostlistp);
  186. if(!test::CheckEqualContainers(*boostlistp2, *stdlistp)) return 1;
  187. }
  188. ::boost::movelib::unique_ptr<MyBoostList> const pboostlist = ::boost::movelib::make_unique<MyBoostList>();
  189. ::boost::movelib::unique_ptr<MyStdList> const pstdlist = ::boost::movelib::make_unique<MyStdList>();
  190. MyBoostList &boostlist = *pboostlist;
  191. MyStdList &stdlist = *pstdlist;
  192. if(push_data_t::execute(max, boostlist, stdlist)){
  193. return 1;
  194. }
  195. boostlist.erase(boostlist.begin()++);
  196. stdlist.erase(stdlist.begin()++);
  197. if(!CheckEqualContainers(boostlist, stdlist)) return 1;
  198. if(list_pop_back_function<DoublyLinked>::execute(boostlist, stdlist)){
  199. return 1;
  200. }
  201. boostlist.pop_front();
  202. stdlist.pop_front();
  203. if(!CheckEqualContainers(boostlist, stdlist)) return 1;
  204. {
  205. IntType aux_vect[50];
  206. for(int i = 0; i < 50; ++i){
  207. IntType move_me(-1);
  208. aux_vect[i] = boost::move(move_me);
  209. }
  210. int aux_vect2[50];
  211. for(int i = 0; i < 50; ++i){
  212. aux_vect2[i] = -1;
  213. }
  214. boostlist.assign(boost::make_move_iterator(&aux_vect[0])
  215. ,boost::make_move_iterator(&aux_vect[50]));
  216. stdlist.assign(&aux_vect2[0], &aux_vect2[50]);
  217. if(!CheckEqualContainers(boostlist, stdlist)) return 1;
  218. for(int i = 0; i < 50; ++i){
  219. IntType move_me(-1);
  220. aux_vect[i] = boost::move(move_me);
  221. }
  222. for(int i = 0; i < 50; ++i){
  223. aux_vect2[i] = -1;
  224. }
  225. boostlist.assign(boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[0]))
  226. ,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[50])));
  227. stdlist.assign(&aux_vect2[0], &aux_vect2[50]);
  228. if(!CheckEqualContainers(boostlist, stdlist)) return 1;
  229. }
  230. if(copied_allocators_equal){
  231. boostlist.sort();
  232. stdlist.sort();
  233. if(!CheckEqualContainers(boostlist, stdlist)) return 1;
  234. }
  235. boostlist.reverse();
  236. stdlist.reverse();
  237. if(!CheckEqualContainers(boostlist, stdlist)) return 1;
  238. boostlist.reverse();
  239. stdlist.reverse();
  240. if(!CheckEqualContainers(boostlist, stdlist)) return 1;
  241. {
  242. IntType aux_vect[50];
  243. for(int i = 0; i < 50; ++i){
  244. IntType move_me(-1);
  245. aux_vect[i] = boost::move(move_me);
  246. }
  247. int aux_vect2[50];
  248. for(int i = 0; i < 50; ++i){
  249. aux_vect2[i] = -1;
  250. }
  251. typename MyBoostList::iterator old_begin = boostlist.begin();
  252. typename MyBoostList::iterator it_insert =
  253. boostlist.insert(boostlist.begin()
  254. ,boost::make_move_iterator(&aux_vect[0])
  255. ,boost::make_move_iterator(&aux_vect[50]));
  256. if(it_insert != boostlist.begin() || boost::container::iterator_distance(it_insert, old_begin) != 50)
  257. return 1;
  258. stdlist.insert(stdlist.begin(), &aux_vect2[0], &aux_vect2[50]);
  259. if(!CheckEqualContainers(boostlist, stdlist))
  260. return 1;
  261. for(int i = 0; i < 50; ++i){
  262. IntType move_me(-1);
  263. aux_vect[i] = boost::move(move_me);
  264. }
  265. for(int i = 0; i < 50; ++i){
  266. aux_vect2[i] = -1;
  267. }
  268. old_begin = boostlist.begin();
  269. it_insert = boostlist.insert(boostlist.end()
  270. ,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[0]))
  271. ,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[50])));
  272. if(boost::container::iterator_distance(it_insert, boostlist.end()) != 50)
  273. return 1;
  274. stdlist.insert(stdlist.end(), &aux_vect2[0], &aux_vect2[50]);
  275. if(!CheckEqualContainers(boostlist, stdlist))
  276. return 1;
  277. }
  278. boostlist.unique();
  279. stdlist.unique();
  280. if(!CheckEqualContainers(boostlist, stdlist))
  281. return 1;
  282. if(copied_allocators_equal){
  283. boostlist.sort(std::greater<IntType>());
  284. stdlist.sort(std::greater<int>());
  285. if(!CheckEqualContainers(boostlist, stdlist))
  286. return 1;
  287. }
  288. for(int i = 0; i < max; ++i){
  289. IntType new_int(i);
  290. boostlist.insert(boostlist.end(), boost::move(new_int));
  291. stdlist.insert(stdlist.end(), i);
  292. if(!test::CheckEqualContainers(boostlist, stdlist)) return 1;
  293. }
  294. if(!test::CheckEqualContainers(boostlist, stdlist)) return 1;
  295. boostlist.resize(25);
  296. stdlist.resize(25);
  297. boostlist.resize(50);
  298. stdlist.resize(50);
  299. boostlist.resize(0);
  300. stdlist.resize(0);
  301. if(!CheckEqualContainers(boostlist, stdlist))
  302. return 1;
  303. //some comparison operators
  304. if(!(boostlist == boostlist))
  305. return 1;
  306. if(boostlist != boostlist)
  307. return 1;
  308. if(boostlist < boostlist)
  309. return 1;
  310. if(boostlist > boostlist)
  311. return 1;
  312. if(!(boostlist <= boostlist))
  313. return 1;
  314. if(!(boostlist >= boostlist))
  315. return 1;
  316. if(push_data_t::execute(max, boostlist, stdlist)){
  317. return 1;
  318. }
  319. {
  320. MyBoostList otherboostlist(boostlist.get_allocator());
  321. MyStdList otherstdlist;
  322. int listsize = (int)boostlist.size();
  323. if(push_data_t::execute(listsize, boostlist, stdlist)){
  324. return 1;
  325. }
  326. if(copied_allocators_equal){
  327. boostlist.splice(boostlist.begin(), otherboostlist);
  328. stdlist.splice(stdlist.begin(), otherstdlist);
  329. if(!CheckEqualContainers(boostlist, stdlist))
  330. return 1;
  331. }
  332. listsize = (int)boostlist.size();
  333. if(push_data_t::execute(listsize, boostlist, stdlist)){
  334. return 1;
  335. }
  336. if(push_data_t::execute(listsize, otherboostlist, otherstdlist)){
  337. return 1;
  338. }
  339. if(copied_allocators_equal){
  340. boostlist.sort(std::greater<IntType>());
  341. stdlist.sort(std::greater<int>());
  342. if(!CheckEqualContainers(boostlist, stdlist))
  343. return 1;
  344. otherboostlist.sort(std::greater<IntType>());
  345. otherstdlist.sort(std::greater<int>());
  346. if(!CheckEqualContainers(otherboostlist, otherstdlist))
  347. return 1;
  348. boostlist.merge(otherboostlist, std::greater<IntType>());
  349. stdlist.merge(otherstdlist, std::greater<int>());
  350. if(!CheckEqualContainers(boostlist, stdlist))
  351. return 1;
  352. }
  353. if(!list_copyable_only(boostlist, stdlist
  354. ,dtl::bool_<boost::container::test::is_copyable<IntType>::value>())){
  355. return 1;
  356. }
  357. }
  358. return 0;
  359. }
  360. template<class List>
  361. bool test_list_methods_with_initializer_list_as_argument_for()
  362. {
  363. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  364. const std::initializer_list<int> il = {5, 10, 15};
  365. const List expected_list(il.begin(), il.end());
  366. {
  367. List sl = il;
  368. if(sl != expected_list)
  369. return false;
  370. }
  371. {
  372. List sl = {1, 2};
  373. sl = il;
  374. if(sl != expected_list)
  375. return false;
  376. }
  377. {
  378. List sl({ 1, 2 }, typename List::allocator_type());
  379. sl = il;
  380. if (sl != expected_list)
  381. return false;
  382. }
  383. {
  384. List sl = {4, 5};
  385. sl.assign(il);
  386. if(sl != expected_list)
  387. return false;
  388. }
  389. {
  390. List sl = {15};
  391. sl.insert(sl.cbegin(), {5, 10});
  392. if(sl != expected_list)
  393. return false;
  394. }
  395. {
  396. List sl = {5};
  397. sl.insert_after(sl.cbegin(), {10, 15});
  398. if(sl != expected_list)
  399. return false;
  400. }
  401. return true;
  402. #endif
  403. return true;
  404. }
  405. } //namespace test{
  406. } //namespace container {
  407. } //namespace boost{
  408. #include <boost/container/detail/config_end.hpp>
  409. #endif