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