unique_ptr_movector.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Howard Hinnant 2009
  4. // (C) Copyright Ion Gaztanaga 2014-2014.
  5. //
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // See http://www.boost.org/libs/move for documentation.
  11. //
  12. //////////////////////////////////////////////////////////////////////////////
  13. #include <boost/move/utility_core.hpp>
  14. #include <boost/move/unique_ptr.hpp>
  15. #include <boost/static_assert.hpp>
  16. #include <boost/core/lightweight_test.hpp>
  17. //////////////////////////////////////////////
  18. //
  19. // The initial implementation of these tests
  20. // was written by Howard Hinnant.
  21. //
  22. // These test were later refactored grouping
  23. // and porting them to Boost.Move.
  24. //
  25. // Many thanks to Howard for releasing his C++03
  26. // unique_ptr implementation with such detailed
  27. // test cases.
  28. //
  29. //////////////////////////////////////////////
  30. #include "unique_ptr_test_utils_beg.hpp"
  31. namespace bml = ::boost::movelib;
  32. namespace bmupmu = ::boost::move_upmu;
  33. ////////////////////////////////
  34. // unique_ptr_ctor_move_defdel
  35. ////////////////////////////////
  36. namespace unique_ptr_ctor_move_defdel{
  37. // test converting move ctor. Should only require a MoveConstructible deleter, or if
  38. // deleter is a reference, not even that.
  39. void test()
  40. {
  41. //Single unique_ptr
  42. reset_counters();
  43. {
  44. bml::unique_ptr<A> s(new A);
  45. A* p = s.get();
  46. bml::unique_ptr<A> s2(boost::move(s));
  47. BOOST_TEST(s2.get() == p);
  48. BOOST_TEST(s.get() == 0);
  49. BOOST_TEST(A::count == 1);
  50. }
  51. BOOST_TEST(A::count == 0);
  52. //Unbounded array unique_ptr
  53. reset_counters();
  54. {
  55. bml::unique_ptr<A[]> s(new A[2]);
  56. A* p = s.get();
  57. bml::unique_ptr<A[]> s2(boost::move(s));
  58. BOOST_TEST(s2.get() == p);
  59. BOOST_TEST(s.get() == 0);
  60. BOOST_TEST(A::count == 2);
  61. }
  62. BOOST_TEST(A::count == 0);
  63. //Bounded array unique_ptr
  64. reset_counters();
  65. {
  66. bml::unique_ptr<A[2]> s(new A[2]);
  67. A* p = s.get();
  68. bml::unique_ptr<A[2]> s2(boost::move(s));
  69. BOOST_TEST(s2.get() == p);
  70. BOOST_TEST(s.get() == 0);
  71. BOOST_TEST(A::count == 2);
  72. }
  73. BOOST_TEST(A::count == 0);
  74. }
  75. } //namespace unique_ptr_ctor_move_defdel{
  76. ////////////////////////////////
  77. // unique_ptr_ctor_move_movedel
  78. ////////////////////////////////
  79. namespace unique_ptr_ctor_move_movedel{
  80. // test converting move ctor. Should only require a MoveConstructible deleter, or if
  81. // deleter is a reference, not even that.
  82. void test()
  83. {
  84. //Single unique_ptr
  85. reset_counters();
  86. {
  87. bml::unique_ptr<A, move_constr_deleter<A> > s(new A);
  88. A* p = s.get();
  89. bml::unique_ptr<A, move_constr_deleter<A> > s2 = boost::move(s);
  90. BOOST_TEST(s2.get() == p);
  91. BOOST_TEST(s.get() == 0);
  92. BOOST_TEST(A::count == 1);
  93. BOOST_TEST(s2.get_deleter().state() == 5);
  94. BOOST_TEST(s.get_deleter().state() == 0);
  95. }
  96. BOOST_TEST(A::count == 0);
  97. //Unbounded array unique_ptr
  98. reset_counters();
  99. {
  100. bml::unique_ptr<A[], move_constr_deleter<A[]> > s(new A[2]);
  101. A* p = s.get();
  102. bml::unique_ptr<A[], move_constr_deleter<A[]> > s2 = boost::move(s);
  103. BOOST_TEST(s2.get() == p);
  104. BOOST_TEST(s.get() == 0);
  105. BOOST_TEST(A::count == 2);
  106. BOOST_TEST(s2.get_deleter().state() == 5);
  107. BOOST_TEST(s.get_deleter().state() == 0);
  108. }
  109. BOOST_TEST(A::count == 0);
  110. //Bounded array unique_ptr
  111. reset_counters();
  112. {
  113. bml::unique_ptr<A[2]> s(new A[2]);
  114. A* p = s.get();
  115. bml::unique_ptr<A[2]> s2 = boost::move(s);
  116. BOOST_TEST(s2.get() == p);
  117. BOOST_TEST(s.get() == 0);
  118. BOOST_TEST(A::count == 2);
  119. }
  120. BOOST_TEST(A::count == 0);
  121. }
  122. } //namespace unique_ptr_ctor_move_movedel{
  123. ////////////////////////////////
  124. // unique_ptr_ctor_move_dfctrdelref
  125. ////////////////////////////////
  126. namespace unique_ptr_ctor_move_dfctrdelref{
  127. // test converting move ctor. Should only require a MoveConstructible deleter, or if
  128. // deleter is a reference, not even that.
  129. void test()
  130. {
  131. //Single unique_ptr
  132. reset_counters();
  133. {
  134. def_constr_deleter<A> d;
  135. bml::unique_ptr<A, def_constr_deleter<A>&> s(new A, d);
  136. A* p = s.get();
  137. bml::unique_ptr<A, def_constr_deleter<A>&> s2 = boost::move(s);
  138. BOOST_TEST(s2.get() == p);
  139. BOOST_TEST(s.get() == 0);
  140. BOOST_TEST(A::count == 1);
  141. d.set_state(6);
  142. BOOST_TEST(s2.get_deleter().state() == d.state());
  143. BOOST_TEST(s.get_deleter().state() == d.state());
  144. }
  145. BOOST_TEST(A::count == 0);
  146. //Unbounded array unique_ptr
  147. reset_counters();
  148. {
  149. def_constr_deleter<A[]> d;
  150. bml::unique_ptr<A[], def_constr_deleter<A[]>&> s(new A[2], d);
  151. A* p = s.get();
  152. bml::unique_ptr<A[], def_constr_deleter<A[]>&> s2 = boost::move(s);
  153. BOOST_TEST(s2.get() == p);
  154. BOOST_TEST(s.get() == 0);
  155. BOOST_TEST(A::count == 2);
  156. d.set_state(6);
  157. BOOST_TEST(s2.get_deleter().state() == d.state());
  158. BOOST_TEST(s.get_deleter().state() == d.state());
  159. }
  160. BOOST_TEST(A::count == 0);
  161. //Bounded array unique_ptr
  162. reset_counters();
  163. {
  164. def_constr_deleter<A[2]> d;
  165. bml::unique_ptr<A[2], def_constr_deleter<A[2]>&> s(new A[2], d);
  166. A* p = s.get();
  167. bml::unique_ptr<A[2], def_constr_deleter<A[2]>&> s2(boost::move(s));
  168. BOOST_TEST(s2.get() == p);
  169. BOOST_TEST(s.get() == 0);
  170. BOOST_TEST(A::count == 2);
  171. d.set_state(6);
  172. BOOST_TEST(s2.get_deleter().state() == d.state());
  173. BOOST_TEST(s.get_deleter().state() == d.state());
  174. }
  175. BOOST_TEST(A::count == 0);
  176. }
  177. } //namespace unique_ptr_ctor_move_dfctrdelref{
  178. ////////////////////////////////
  179. // unique_ptr_ctor_move_convert_defdel
  180. ////////////////////////////////
  181. namespace unique_ptr_ctor_move_convert_defdel{
  182. // test converting move ctor. Should only require a MoveConstructible deleter, or if
  183. // deleter is a reference, not even that.
  184. void test()
  185. {
  186. //Single unique_ptr
  187. reset_counters();
  188. {
  189. bml::unique_ptr<B> s(new B);
  190. A* p = s.get();
  191. bml::unique_ptr<A> s2(boost::move(s));
  192. BOOST_TEST(s2.get() == p);
  193. BOOST_TEST(s.get() == 0);
  194. BOOST_TEST(A::count == 1);
  195. BOOST_TEST(B::count == 1);
  196. }
  197. BOOST_TEST(A::count == 0);
  198. BOOST_TEST(B::count == 0);
  199. //Unbounded array unique_ptr
  200. reset_counters();
  201. {
  202. bml::unique_ptr<A[]> s(new A[2]);
  203. A* p = s.get();
  204. bml::unique_ptr<const volatile A[]> s2(boost::move(s));
  205. BOOST_TEST(s2.get() == p);
  206. BOOST_TEST(s.get() == 0);
  207. BOOST_TEST(A::count == 2);
  208. }
  209. BOOST_TEST(A::count == 0);
  210. //Bounded array unique_ptr
  211. reset_counters();
  212. {
  213. bml::unique_ptr<A[2]> s(new A[2]);
  214. A* p = s.get();
  215. bml::unique_ptr<const volatile A[2]> s2(boost::move(s));
  216. BOOST_TEST(s2.get() == p);
  217. BOOST_TEST(s.get() == 0);
  218. BOOST_TEST(A::count == 2);
  219. }
  220. BOOST_TEST(A::count == 0);
  221. {
  222. bml::unique_ptr<A[2]> s(new A[2]);
  223. A* p = s.get();
  224. bml::unique_ptr<const volatile A[]> s2(boost::move(s));
  225. BOOST_TEST(s2.get() == p);
  226. BOOST_TEST(s.get() == 0);
  227. BOOST_TEST(A::count == 2);
  228. }
  229. BOOST_TEST(A::count == 0);
  230. }
  231. } //namespace unique_ptr_ctor_move_convert_defdel{
  232. ////////////////////////////////
  233. // unique_ptr_ctor_move_convert_movedel
  234. ////////////////////////////////
  235. namespace unique_ptr_ctor_move_convert_movedel{
  236. // test converting move ctor. Should only require a MoveConstructible deleter, or if
  237. // deleter is a reference, not even that.
  238. void test()
  239. {
  240. //Single unique_ptr
  241. reset_counters();
  242. BOOST_STATIC_ASSERT((bmupmu::is_convertible<B, A>::value));
  243. {
  244. bml::unique_ptr<B, move_constr_deleter<B> > s(new B);
  245. A* p = s.get();
  246. bml::unique_ptr<A, move_constr_deleter<A> > s2(boost::move(s));
  247. BOOST_TEST(s2.get() == p);
  248. BOOST_TEST(s.get() == 0);
  249. BOOST_TEST(A::count == 1);
  250. BOOST_TEST(B::count == 1);
  251. BOOST_TEST(s2.get_deleter().state() == 5);
  252. BOOST_TEST(s.get_deleter().state() == 0);
  253. }
  254. BOOST_TEST(A::count == 0);
  255. BOOST_TEST(B::count == 0);
  256. //Unbounded array unique_ptr
  257. reset_counters();
  258. {
  259. bml::unique_ptr<const A[], move_constr_deleter<const A[]> > s(new const A[2]);
  260. const A* p = s.get();
  261. bml::unique_ptr<const volatile A[], move_constr_deleter<const volatile A[]> > s2(boost::move(s));
  262. BOOST_TEST(s2.get() == p);
  263. BOOST_TEST(s.get() == 0);
  264. BOOST_TEST(A::count == 2);
  265. BOOST_TEST(s2.get_deleter().state() == 5);
  266. BOOST_TEST(s.get_deleter().state() == 0);
  267. }
  268. BOOST_TEST(A::count == 0);
  269. BOOST_TEST(B::count == 0);
  270. //Bounded array unique_ptr
  271. reset_counters();
  272. {
  273. bml::unique_ptr<const A[2], move_constr_deleter<const A[2]> > s(new const A[2]);
  274. const A* p = s.get();
  275. bml::unique_ptr<const volatile A[2], move_constr_deleter<const volatile A[2]> > s2(boost::move(s));
  276. BOOST_TEST(s2.get() == p);
  277. BOOST_TEST(s.get() == 0);
  278. BOOST_TEST(A::count == 2);
  279. BOOST_TEST(s2.get_deleter().state() == 5);
  280. BOOST_TEST(s.get_deleter().state() == 0);
  281. }
  282. BOOST_TEST(A::count == 0);
  283. BOOST_TEST(B::count == 0);
  284. {
  285. bml::unique_ptr<const A[2], move_constr_deleter<const A[2]> > s(new const A[2]);
  286. const A* p = s.get();
  287. bml::unique_ptr<const volatile A[], move_constr_deleter<const volatile A[]> > s2(boost::move(s));
  288. BOOST_TEST(s2.get() == p);
  289. BOOST_TEST(s.get() == 0);
  290. BOOST_TEST(A::count == 2);
  291. BOOST_TEST(s2.get_deleter().state() == 5);
  292. BOOST_TEST(s.get_deleter().state() == 0);
  293. }
  294. BOOST_TEST(A::count == 0);
  295. BOOST_TEST(B::count == 0);
  296. }
  297. } //namespace unique_ptr_ctor_move_convert_movedel{
  298. ////////////////////////////////
  299. // unique_ptr_ctor_move_convert_dfctrdelref
  300. ////////////////////////////////
  301. namespace unique_ptr_ctor_move_convert_dfctrdelref{
  302. // test converting move ctor. Should only require a MoveConstructible deleter, or if
  303. // deleter is a reference, not even that.
  304. void test()
  305. {
  306. //Single unique_ptr
  307. reset_counters();
  308. {
  309. def_constr_deleter<A> d;
  310. bml::unique_ptr<B, def_constr_deleter<A>&> s(new B, d);
  311. A* p = s.get();
  312. bml::unique_ptr<A, def_constr_deleter<A>&> s2(boost::move(s));
  313. BOOST_TEST(s2.get() == p);
  314. BOOST_TEST(s.get() == 0);
  315. BOOST_TEST(A::count == 1);
  316. BOOST_TEST(B::count == 1);
  317. d.set_state(6);
  318. BOOST_TEST(s2.get_deleter().state() == d.state());
  319. BOOST_TEST(s.get_deleter().state() == d.state());
  320. }
  321. BOOST_TEST(A::count == 0);
  322. BOOST_TEST(B::count == 0);
  323. //Unbounded array unique_ptr
  324. reset_counters();
  325. {
  326. def_constr_deleter<volatile A[]> d;
  327. bml::unique_ptr<A[], def_constr_deleter<volatile A[]>&> s(new A[2], d);
  328. A* p = s.get();
  329. bml::unique_ptr<volatile A[], def_constr_deleter<volatile A[]>&> s2(boost::move(s));
  330. BOOST_TEST(s2.get() == p);
  331. BOOST_TEST(s.get() == 0);
  332. BOOST_TEST(A::count == 2);
  333. d.set_state(6);
  334. BOOST_TEST(s2.get_deleter().state() == d.state());
  335. BOOST_TEST(s.get_deleter().state() == d.state());
  336. }
  337. BOOST_TEST(A::count == 0);
  338. //Bounded array unique_ptr
  339. reset_counters();
  340. {
  341. def_constr_deleter<volatile A[2]> d;
  342. bml::unique_ptr<A[2], def_constr_deleter<volatile A[2]>&> s(new A[2], d);
  343. A* p = s.get();
  344. bml::unique_ptr<volatile A[2], def_constr_deleter<volatile A[2]>&> s2(boost::move(s));
  345. BOOST_TEST(s2.get() == p);
  346. BOOST_TEST(s.get() == 0);
  347. BOOST_TEST(A::count == 2);
  348. d.set_state(6);
  349. BOOST_TEST(s2.get_deleter().state() == d.state());
  350. BOOST_TEST(s.get_deleter().state() == d.state());
  351. }
  352. BOOST_TEST(A::count == 0);
  353. {
  354. def_constr_deleter<volatile A[]> d;
  355. bml::unique_ptr<A[2], def_constr_deleter<volatile A[]>&> s(new A[2], d);
  356. A* p = s.get();
  357. bml::unique_ptr<volatile A[], def_constr_deleter<volatile A[]>&> s2(boost::move(s));
  358. BOOST_TEST(s2.get() == p);
  359. BOOST_TEST(s.get() == 0);
  360. BOOST_TEST(A::count == 2);
  361. d.set_state(6);
  362. BOOST_TEST(s2.get_deleter().state() == d.state());
  363. BOOST_TEST(s.get_deleter().state() == d.state());
  364. }
  365. BOOST_TEST(A::count == 0);
  366. }
  367. } //namespace unique_ptr_ctor_move_convert_dfctrdelref{
  368. ////////////////////////////////
  369. // unique_ptr_ctor_move_sourcesink
  370. ////////////////////////////////
  371. namespace unique_ptr_ctor_move_sourcesink{
  372. // test move ctor. Should only require a MoveConstructible deleter, or if
  373. // deleter is a reference, not even that.
  374. bml::unique_ptr<A> source1()
  375. { return bml::unique_ptr<A>(new A); }
  376. bml::unique_ptr<A[]> source1_unbounded_array()
  377. { return bml::unique_ptr<A[]> (new A[2]); }
  378. bml::unique_ptr<A[2]> source1_bounded_array()
  379. { return bml::unique_ptr<A[2]> (new A[2]); }
  380. void sink1(bml::unique_ptr<A>)
  381. {}
  382. void sink1_unbounded_array(bml::unique_ptr<A[]>)
  383. {}
  384. void sink1_bounded_array(bml::unique_ptr<A[2]>)
  385. {}
  386. bml::unique_ptr<A, move_constr_deleter<A> > source2()
  387. { return bml::unique_ptr<A, move_constr_deleter<A> > (new A); }
  388. bml::unique_ptr<A[], move_constr_deleter<A[]> > source2_unbounded_array()
  389. { return bml::unique_ptr<A[], move_constr_deleter<A[]> >(new A[2]); }
  390. bml::unique_ptr<A[2], move_constr_deleter<A[2]> > source2_bounded_array()
  391. { return bml::unique_ptr<A[2], move_constr_deleter<A[2]> >(new A[2]); }
  392. void sink2(bml::unique_ptr<A, move_constr_deleter<A> >)
  393. {}
  394. void sink2_unbounded_array(bml::unique_ptr<A[], move_constr_deleter<A[]> >)
  395. {}
  396. void sink2_bounded_array(bml::unique_ptr<A[2], move_constr_deleter<A[2]> >)
  397. {}
  398. bml::unique_ptr<A, def_constr_deleter<A>&> source3()
  399. {
  400. static def_constr_deleter<A> d;
  401. return bml::unique_ptr<A, def_constr_deleter<A>&>(new A, d);
  402. }
  403. bml::unique_ptr<A[], def_constr_deleter<A[]>&> source3_unbounded_array()
  404. {
  405. static def_constr_deleter<A[]> d;
  406. return bml::unique_ptr<A[], def_constr_deleter<A[]>&>(new A[2], d);
  407. }
  408. bml::unique_ptr<A[2], def_constr_deleter<A[2]>&> source3_bounded_array()
  409. {
  410. static def_constr_deleter<A[2]> d;
  411. return bml::unique_ptr<A[2], def_constr_deleter<A[2]>&>(new A[2], d);
  412. }
  413. void sink3(bml::unique_ptr<A, def_constr_deleter<A>&> )
  414. {}
  415. void sink3_unbounded_array(bml::unique_ptr<A[], def_constr_deleter<A[]>&> )
  416. {}
  417. void sink3_bounded_array(bml::unique_ptr<A[2], def_constr_deleter<A[2]>&> )
  418. {}
  419. void test()
  420. {
  421. //Single unique_ptr
  422. reset_counters();
  423. sink1(source1());
  424. sink2(source2());
  425. sink3(source3());
  426. BOOST_TEST(A::count == 0);
  427. //Unbounded array unique_ptr
  428. reset_counters();
  429. sink1_unbounded_array(source1_unbounded_array());
  430. sink2_unbounded_array(source2_unbounded_array());
  431. sink3_unbounded_array(source3_unbounded_array());
  432. BOOST_TEST(A::count == 0);
  433. //Bbounded array unique_ptr
  434. reset_counters();
  435. sink1_bounded_array(source1_bounded_array());
  436. sink2_bounded_array(source2_bounded_array());
  437. sink3_bounded_array(source3_bounded_array());
  438. BOOST_TEST(A::count == 0);
  439. }
  440. } //namespace unique_ptr_ctor_move_sourcesink{
  441. ////////////////////////////////
  442. // main
  443. ////////////////////////////////
  444. int main()
  445. {
  446. //Move Constructor
  447. unique_ptr_ctor_move_defdel::test();
  448. unique_ptr_ctor_move_movedel::test();
  449. unique_ptr_ctor_move_dfctrdelref::test();
  450. unique_ptr_ctor_move_convert_defdel::test();
  451. unique_ptr_ctor_move_convert_movedel::test();
  452. unique_ptr_ctor_move_convert_dfctrdelref::test();
  453. unique_ptr_ctor_move_sourcesink::test();
  454. //Test results
  455. return boost::report_errors();
  456. }
  457. #include "unique_ptr_test_utils_end.hpp"