1 //===----------------------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // <memory>
11
12 // unique_ptr
13
14 // Test unique_ptr(pointer) ctor
15
16 #include <memory>
17 #include <cassert>
18
19 // unique_ptr(pointer, deleter()) only requires MoveConstructible deleter
20
21 struct A
22 {
23 static int count;
AA24 A() {++count;}
AA25 A(const A&) {++count;}
~AA26 ~A() {--count;}
27 };
28
29 int A::count = 0;
30
31 template <class T>
32 class Deleter
33 {
34 int state_;
35
36 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
37 Deleter(const Deleter&);
38 Deleter& operator=(const Deleter&);
39 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
40 Deleter(Deleter&);
41 Deleter& operator=(Deleter&);
42 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
43
44 public:
45 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Deleter(Deleter && r)46 Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
operator =(Deleter && r)47 Deleter& operator=(Deleter&& r)
48 {
49 state_ = r.state_;
50 r.state_ = 0;
51 return *this;
52 }
53 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
54 operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
55 Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
56 Deleter& operator=(std::__rv<Deleter> r)
57 {
58 state_ = r->state_;
59 r->state_ = 0;
60 return *this;
61 }
62 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
63
Deleter()64 Deleter() : state_(5) {}
65
66 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
67 template <class U>
Deleter(Deleter<U> && d,typename std::enable_if<!std::is_same<U,T>::value>::type * =0)68 Deleter(Deleter<U>&& d,
69 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
70 : state_(d.state()) {d.set_state(0);}
71
72 private:
73 template <class U>
74 Deleter(const Deleter<U>& d,
75 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
76 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
77 template <class U>
Deleter(Deleter<U> d,typename std::enable_if<!std::is_same<U,T>::value>::type * =0)78 Deleter(Deleter<U> d,
79 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
80 : state_(d.state()) {}
81 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
82 public:
state() const83 int state() const {return state_;}
set_state(int i)84 void set_state(int i) {state_ = i;}
85
operator ()(T * p)86 void operator()(T* p) {delete p;}
87 };
88
main()89 int main()
90 {
91 {
92 A* p = new A;
93 assert(A::count == 1);
94 std::unique_ptr<A, Deleter<A> > s(p, Deleter<A>());
95 assert(s.get() == p);
96 assert(s.get_deleter().state() == 5);
97 }
98 assert(A::count == 0);
99 }
100