swap.pass.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. // <memory>
  9. // unique_ptr
  10. // Test swap
  11. #include <memory>
  12. #include <cassert>
  13. #include "test_macros.h"
  14. #include "deleter_types.h"
  15. struct A
  16. {
  17. int state_;
  18. static int count;
  19. A() : state_(0) {++count;}
  20. explicit A(int i) : state_(i) {++count;}
  21. A(const A& a) : state_(a.state_) {++count;}
  22. A& operator=(const A& a) {state_ = a.state_; return *this;}
  23. ~A() {--count;}
  24. friend bool operator==(const A& x, const A& y)
  25. {return x.state_ == y.state_;}
  26. };
  27. int A::count = 0;
  28. template <class T>
  29. struct NonSwappableDeleter {
  30. explicit NonSwappableDeleter(int) {}
  31. NonSwappableDeleter& operator=(NonSwappableDeleter const&) { return *this; }
  32. void operator()(T*) const {}
  33. private:
  34. NonSwappableDeleter(NonSwappableDeleter const&);
  35. };
  36. int main(int, char**)
  37. {
  38. {
  39. A* p1 = new A(1);
  40. std::unique_ptr<A, Deleter<A> > s1(p1, Deleter<A>(1));
  41. A* p2 = new A(2);
  42. std::unique_ptr<A, Deleter<A> > s2(p2, Deleter<A>(2));
  43. assert(s1.get() == p1);
  44. assert(*s1 == A(1));
  45. assert(s1.get_deleter().state() == 1);
  46. assert(s2.get() == p2);
  47. assert(*s2 == A(2));
  48. assert(s2.get_deleter().state() == 2);
  49. swap(s1, s2);
  50. assert(s1.get() == p2);
  51. assert(*s1 == A(2));
  52. assert(s1.get_deleter().state() == 2);
  53. assert(s2.get() == p1);
  54. assert(*s2 == A(1));
  55. assert(s2.get_deleter().state() == 1);
  56. assert(A::count == 2);
  57. }
  58. assert(A::count == 0);
  59. {
  60. A* p1 = new A[3];
  61. std::unique_ptr<A[], Deleter<A[]> > s1(p1, Deleter<A[]>(1));
  62. A* p2 = new A[3];
  63. std::unique_ptr<A[], Deleter<A[]> > s2(p2, Deleter<A[]>(2));
  64. assert(s1.get() == p1);
  65. assert(s1.get_deleter().state() == 1);
  66. assert(s2.get() == p2);
  67. assert(s2.get_deleter().state() == 2);
  68. swap(s1, s2);
  69. assert(s1.get() == p2);
  70. assert(s1.get_deleter().state() == 2);
  71. assert(s2.get() == p1);
  72. assert(s2.get_deleter().state() == 1);
  73. assert(A::count == 6);
  74. }
  75. assert(A::count == 0);
  76. #if TEST_STD_VER >= 11
  77. {
  78. // test that unique_ptr's specialized swap is disabled when the deleter
  79. // is non-swappable. Instead we should pick up the generic swap(T, T)
  80. // and perform 3 move constructions.
  81. typedef NonSwappableDeleter<int> D;
  82. D d(42);
  83. int x = 42;
  84. int y = 43;
  85. std::unique_ptr<int, D&> p(&x, d);
  86. std::unique_ptr<int, D&> p2(&y, d);
  87. std::swap(p, p2);
  88. }
  89. #endif
  90. return 0;
  91. }