unique_ptr_assign.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  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. ////////////////////////////////
  33. // unique_ptr_asgn_move_convert_defdel
  34. ////////////////////////////////
  35. namespace unique_ptr_asgn_move_convert_defdel {
  36. void test()
  37. {
  38. //Single unique_ptr
  39. reset_counters();
  40. {
  41. bml::unique_ptr<B> s(new B);
  42. A* p = s.get();
  43. bml::unique_ptr<A> s2(new A);
  44. BOOST_TEST(A::count == 2);
  45. s2 = boost::move(s);
  46. BOOST_TEST(s2.get() == p);
  47. BOOST_TEST(s.get() == 0);
  48. BOOST_TEST(A::count == 1);
  49. BOOST_TEST(B::count == 1);
  50. }
  51. BOOST_TEST(A::count == 0);
  52. BOOST_TEST(B::count == 0);
  53. //Unbounded array unique_ptr
  54. reset_counters();
  55. {
  56. bml::unique_ptr<A[]> s(new A[2]);
  57. A* p = s.get();
  58. bml::unique_ptr<const A[]> s2(new const A[2]);
  59. BOOST_TEST(A::count == 4);
  60. s2 = boost::move(s);
  61. BOOST_TEST(s2.get() == p);
  62. BOOST_TEST(s.get() == 0);
  63. BOOST_TEST(A::count == 2);
  64. }
  65. BOOST_TEST(A::count == 0);
  66. //Bounded array unique_ptr
  67. reset_counters();
  68. {
  69. bml::unique_ptr<A[2]> s(new A[2]);
  70. A* p = s.get();
  71. bml::unique_ptr<const A[2]> s2(new const A[2]);
  72. BOOST_TEST(A::count == 4);
  73. s2 = boost::move(s);
  74. BOOST_TEST(s2.get() == p);
  75. BOOST_TEST(s.get() == 0);
  76. BOOST_TEST(A::count == 2);
  77. }
  78. {
  79. BOOST_TEST(A::count == 0);
  80. bml::unique_ptr<A[2]> s(new A[2]);
  81. A* p = s.get();
  82. bml::unique_ptr<const A[]> s2(new const A[2]);
  83. BOOST_TEST(A::count == 4);
  84. s2 = boost::move(s);
  85. BOOST_TEST(s2.get() == p);
  86. BOOST_TEST(s.get() == 0);
  87. BOOST_TEST(A::count == 2);
  88. }
  89. BOOST_TEST(A::count == 0);
  90. }
  91. } //namespace unique_ptr_asgn_move_convert_defdel{
  92. ////////////////////////////////
  93. // unique_ptr_asgn_move_convert_movdel
  94. ////////////////////////////////
  95. namespace unique_ptr_asgn_move_convert_movedel{
  96. void test()
  97. {
  98. //Single unique_ptr
  99. reset_counters();
  100. {
  101. bml::unique_ptr<B, move_constr_deleter<B> > s(new B);
  102. A* p = s.get();
  103. bml::unique_ptr<A, move_constr_deleter<A> > s2(new A);
  104. BOOST_TEST(A::count == 2);
  105. s2 = (boost::move(s));
  106. BOOST_TEST(s2.get() == p);
  107. BOOST_TEST(s.get() == 0);
  108. BOOST_TEST(A::count == 1);
  109. BOOST_TEST(B::count == 1);
  110. BOOST_TEST(s2.get_deleter().state() == 5);
  111. BOOST_TEST(s.get_deleter().state() == 0);
  112. }
  113. BOOST_TEST(A::count == 0);
  114. BOOST_TEST(B::count == 0);
  115. //Unbounded array unique_ptr
  116. reset_counters();
  117. {
  118. bml::unique_ptr<A[], move_constr_deleter<A[]> > s(new A[2]);
  119. A* p = s.get();
  120. bml::unique_ptr<const A[], move_constr_deleter<const A[]> > s2(new const A[2]);
  121. BOOST_TEST(A::count == 4);
  122. s2 = (boost::move(s));
  123. BOOST_TEST(s2.get() == p);
  124. BOOST_TEST(s.get() == 0);
  125. BOOST_TEST(A::count == 2);
  126. BOOST_TEST(s2.get_deleter().state() == 5);
  127. BOOST_TEST(s.get_deleter().state() == 0);
  128. }
  129. BOOST_TEST(A::count == 0);
  130. //Bounded array unique_ptr
  131. reset_counters();
  132. {
  133. bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s(new A[3]);
  134. A* p = s.get();
  135. bml::unique_ptr<const A[2], move_constr_deleter<const A[2]> > s2(new const A[2]);
  136. BOOST_TEST(A::count == 5);
  137. s2 = (boost::move(s));
  138. BOOST_TEST(s2.get() == p);
  139. BOOST_TEST(s.get() == 0);
  140. BOOST_TEST(A::count == 3);
  141. BOOST_TEST(s2.get_deleter().state() == 5);
  142. BOOST_TEST(s.get_deleter().state() == 0);
  143. }
  144. BOOST_TEST(A::count == 0);
  145. reset_counters();
  146. {
  147. bml::unique_ptr<A[2], move_constr_deleter<A[3]> > s(new A[2]);
  148. A* p = s.get();
  149. bml::unique_ptr<const A[], move_constr_deleter<const A[]> > s2(new const A[2]);
  150. BOOST_TEST(A::count == 4);
  151. s2 = (boost::move(s));
  152. BOOST_TEST(s2.get() == p);
  153. BOOST_TEST(s.get() == 0);
  154. BOOST_TEST(A::count == 2);
  155. BOOST_TEST(s2.get_deleter().state() == 5);
  156. BOOST_TEST(s.get_deleter().state() == 0);
  157. }
  158. BOOST_TEST(A::count == 0);
  159. }
  160. } //namespace unique_ptr_asgn_move_convert_movedel{
  161. ////////////////////////////////
  162. // unique_ptr_asgn_move_convert_copydelref
  163. ////////////////////////////////
  164. namespace unique_ptr_asgn_move_convert_copydelref{
  165. // test converting move assignment with reference deleters
  166. void test()
  167. {
  168. //Single unique_ptr
  169. reset_counters();
  170. {
  171. copy_constr_deleter<B> db(5);
  172. bml::unique_ptr<B, copy_constr_deleter<B>&> s(new B, db);
  173. A* p = s.get();
  174. copy_constr_deleter<A> da(6);
  175. bml::unique_ptr<A, copy_constr_deleter<A>&> s2(new A, da);
  176. s2 = boost::move(s);
  177. BOOST_TEST(s2.get() == p);
  178. BOOST_TEST(s.get() == 0);
  179. BOOST_TEST(A::count == 1);
  180. BOOST_TEST(B::count == 1);
  181. BOOST_TEST(s2.get_deleter().state() == 5);
  182. }
  183. BOOST_TEST(A::count == 0);
  184. BOOST_TEST(B::count == 0);
  185. //Unbounded array unique_ptr
  186. reset_counters();
  187. {
  188. copy_constr_deleter<A[]> db(5);
  189. bml::unique_ptr<A[], copy_constr_deleter<A[]>&> s(new A[2], db);
  190. A* p = s.get();
  191. copy_constr_deleter<const A[]> da(6);
  192. bml::unique_ptr<const A[], copy_constr_deleter<const A[]>&> s2(new const A[2], da);
  193. BOOST_TEST(A::count == 4);
  194. s2 = boost::move(s);
  195. BOOST_TEST(s2.get() == p);
  196. BOOST_TEST(s.get() == 0);
  197. BOOST_TEST(A::count == 2);
  198. BOOST_TEST(s2.get_deleter().state() == 5);
  199. }
  200. BOOST_TEST(A::count == 0);
  201. //Bounded array unique_ptr
  202. reset_counters();
  203. {
  204. copy_constr_deleter<A[2]> db(5);
  205. bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s(new A[2], db);
  206. A* p = s.get();
  207. copy_constr_deleter<const A[2]> da(6);
  208. bml::unique_ptr<const A[2], copy_constr_deleter<const A[2]>&> s2(new const A[2], da);
  209. BOOST_TEST(A::count == 4);
  210. s2 = boost::move(s);
  211. BOOST_TEST(s2.get() == p);
  212. BOOST_TEST(s.get() == 0);
  213. BOOST_TEST(A::count == 2);
  214. BOOST_TEST(s2.get_deleter().state() == 5);
  215. }
  216. BOOST_TEST(A::count == 0);
  217. reset_counters();
  218. {
  219. copy_constr_deleter<A[2]> db(5);
  220. bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s(new A[2], db);
  221. A* p = s.get();
  222. copy_constr_deleter<const A[]> da(6);
  223. bml::unique_ptr<const A[], copy_constr_deleter<const A[]>&> s2(new const A[2], da);
  224. BOOST_TEST(A::count == 4);
  225. s2 = boost::move(s);
  226. BOOST_TEST(s2.get() == p);
  227. BOOST_TEST(s.get() == 0);
  228. BOOST_TEST(A::count == 2);
  229. BOOST_TEST(s2.get_deleter().state() == 5);
  230. }
  231. BOOST_TEST(A::count == 0);
  232. }
  233. } //namespace unique_ptr_asgn_move_convert_copydelref{
  234. ////////////////////////////////
  235. // unique_ptr_asgn_move_defdel
  236. ////////////////////////////////
  237. namespace unique_ptr_asgn_move_defdel {
  238. void test()
  239. {
  240. //Single unique_ptr
  241. reset_counters();
  242. {
  243. bml::unique_ptr<A> s1(new A);
  244. A* p = s1.get();
  245. bml::unique_ptr<A> s2(new A);
  246. BOOST_TEST(A::count == 2);
  247. s2 = boost::move(s1);
  248. BOOST_TEST(A::count == 1);
  249. BOOST_TEST(s2.get() == p);
  250. BOOST_TEST(s1.get() == 0);
  251. }
  252. BOOST_TEST(A::count == 0);
  253. //Unbounded array unique_ptr
  254. reset_counters();
  255. {
  256. bml::unique_ptr<A[]> s1(new A[2]);
  257. A* p = s1.get();
  258. bml::unique_ptr<A[]> s2(new A[2]);
  259. BOOST_TEST(A::count == 4);
  260. s2 = boost::move(s1);
  261. BOOST_TEST(A::count == 2);
  262. BOOST_TEST(s2.get() == p);
  263. BOOST_TEST(s1.get() == 0);
  264. }
  265. BOOST_TEST(A::count == 0);
  266. //Bounded array unique_ptr
  267. reset_counters();
  268. {
  269. bml::unique_ptr<A[2]> s1(new A[2]);
  270. A* p = s1.get();
  271. bml::unique_ptr<A[2]> s2(new A[2]);
  272. BOOST_TEST(A::count == 4);
  273. s2 = boost::move(s1);
  274. BOOST_TEST(A::count == 2);
  275. BOOST_TEST(s2.get() == p);
  276. BOOST_TEST(s1.get() == 0);
  277. }
  278. BOOST_TEST(A::count == 0);
  279. }
  280. } //unique_ptr_asgn_move_defdel
  281. ////////////////////////////////
  282. // unique_ptr_asgn_move_movedel
  283. ////////////////////////////////
  284. namespace unique_ptr_asgn_move_movedel {
  285. void test()
  286. {
  287. //Single unique_ptr
  288. reset_counters();
  289. {
  290. bml::unique_ptr<A, move_constr_deleter<A> > s1(new A);
  291. A* p = s1.get();
  292. bml::unique_ptr<A, move_constr_deleter<A> > s2(new A);
  293. BOOST_TEST(A::count == 2);
  294. s2 = boost::move(s1);
  295. BOOST_TEST(s2.get() == p);
  296. BOOST_TEST(s1.get() == 0);
  297. BOOST_TEST(A::count == 1);
  298. BOOST_TEST(s2.get_deleter().state() == 5);
  299. BOOST_TEST(s1.get_deleter().state() == 0);
  300. }
  301. BOOST_TEST(A::count == 0);
  302. //Unbounded array unique_ptr
  303. reset_counters();
  304. {
  305. bml::unique_ptr<A[], move_constr_deleter<A[]> > s1(new A[2]);
  306. A* p = s1.get();
  307. bml::unique_ptr<A[], move_constr_deleter<A[]> > s2(new A[2]);
  308. BOOST_TEST(A::count == 4);
  309. s2 = boost::move(s1);
  310. BOOST_TEST(s2.get() == p);
  311. BOOST_TEST(s1.get() == 0);
  312. BOOST_TEST(A::count == 2);
  313. BOOST_TEST(s2.get_deleter().state() == 5);
  314. BOOST_TEST(s1.get_deleter().state() == 0);
  315. }
  316. BOOST_TEST(A::count == 0);
  317. BOOST_TEST(A::count == 0);
  318. //Bounded array unique_ptr
  319. reset_counters();
  320. {
  321. bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s1(new A[2]);
  322. A* p = s1.get();
  323. bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s2(new A[2]);
  324. BOOST_TEST(A::count == 4);
  325. s2 = boost::move(s1);
  326. BOOST_TEST(s2.get() == p);
  327. BOOST_TEST(s1.get() == 0);
  328. BOOST_TEST(A::count == 2);
  329. BOOST_TEST(s2.get_deleter().state() == 5);
  330. BOOST_TEST(s1.get_deleter().state() == 0);
  331. }
  332. BOOST_TEST(A::count == 0);
  333. }
  334. } //unique_ptr_asgn_move_movedel
  335. ////////////////////////////////
  336. // unique_ptr_asgn_move_copydelref
  337. ////////////////////////////////
  338. namespace unique_ptr_asgn_move_copydelref {
  339. void test()
  340. {
  341. //Single unique_ptr
  342. reset_counters();
  343. {
  344. copy_constr_deleter<A> d1(5);
  345. bml::unique_ptr<A, copy_constr_deleter<A>&> s1(new A, d1);
  346. A* p = s1.get();
  347. copy_constr_deleter<A> d2(6);
  348. bml::unique_ptr<A, copy_constr_deleter<A>&> s2(new A, d2);
  349. s2 = boost::move(s1);
  350. BOOST_TEST(s2.get() == p);
  351. BOOST_TEST(s1.get() == 0);
  352. BOOST_TEST(A::count == 1);
  353. BOOST_TEST(d1.state() == 5);
  354. BOOST_TEST(d2.state() == 5);
  355. }
  356. BOOST_TEST(A::count == 0);
  357. //Unbounded array unique_ptr
  358. reset_counters();
  359. {
  360. copy_constr_deleter<A[]> d1(5);
  361. bml::unique_ptr<A[], copy_constr_deleter<A[]>&> s1(new A[2], d1);
  362. A* p = s1.get();
  363. copy_constr_deleter<A[]> d2(6);
  364. bml::unique_ptr<A[], copy_constr_deleter<A[]>&> s2(new A[2], d2);
  365. BOOST_TEST(A::count == 4);
  366. s2 = boost::move(s1);
  367. BOOST_TEST(s2.get() == p);
  368. BOOST_TEST(s1.get() == 0);
  369. BOOST_TEST(A::count == 2);
  370. BOOST_TEST(d1.state() == 5);
  371. BOOST_TEST(d2.state() == 5);
  372. }
  373. BOOST_TEST(A::count == 0);
  374. //Bounded array unique_ptr
  375. reset_counters();
  376. {
  377. copy_constr_deleter<A[2]> d1(5);
  378. bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s1(new A[2], d1);
  379. A* p = s1.get();
  380. copy_constr_deleter<A[2]> d2(6);
  381. bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s2(new A[2], d2);
  382. BOOST_TEST(A::count == 4);
  383. s2 = boost::move(s1);
  384. BOOST_TEST(s2.get() == p);
  385. BOOST_TEST(s1.get() == 0);
  386. BOOST_TEST(A::count == 2);
  387. BOOST_TEST(d1.state() == 5);
  388. BOOST_TEST(d2.state() == 5);
  389. }
  390. BOOST_TEST(A::count == 0);
  391. }
  392. } //unique_ptr_asgn_move_copydelref
  393. ////////////////////////////////
  394. // main
  395. ////////////////////////////////
  396. int main()
  397. {
  398. //Assignment
  399. unique_ptr_asgn_move_convert_defdel::test();
  400. unique_ptr_asgn_move_convert_movedel::test();
  401. unique_ptr_asgn_move_convert_copydelref::test();
  402. unique_ptr_asgn_move_defdel::test();
  403. unique_ptr_asgn_move_movedel::test();
  404. unique_ptr_asgn_move_copydelref::test();
  405. //Test results
  406. return boost::report_errors();
  407. }
  408. #include "unique_ptr_test_utils_end.hpp"