blob: c0f4f56d25ced6d17a472dfbffba31c0dc9b163c [file] [log] [blame]
Howard Hinnantc52f43e2010-08-22 00:59:46 +00001//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. 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
21struct A
22{
23 static int count;
24 A() {++count;}
25 A(const A&) {++count;}
26 ~A() {--count;}
27};
28
29int A::count = 0;
30
31template <class T>
32class Deleter
33{
34 int state_;
35
Howard Hinnant73d21a42010-09-04 23:28:19 +000036#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000037 Deleter(const Deleter&);
38 Deleter& operator=(const Deleter&);
Howard Hinnant73d21a42010-09-04 23:28:19 +000039#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000040 Deleter(Deleter&);
41 Deleter& operator=(Deleter&);
Howard Hinnant73d21a42010-09-04 23:28:19 +000042#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000043
44public:
Howard Hinnant73d21a42010-09-04 23:28:19 +000045#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000046 Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
47 Deleter& operator=(Deleter&& r)
48 {
49 state_ = r.state_;
50 r.state_ = 0;
51 return *this;
52 }
Howard Hinnant73d21a42010-09-04 23:28:19 +000053#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000054 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 }
Howard Hinnant73d21a42010-09-04 23:28:19 +000062#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000063
64 Deleter() : state_(5) {}
65
Howard Hinnant73d21a42010-09-04 23:28:19 +000066#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000067 template <class U>
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
72private:
73 template <class U>
74 Deleter(const Deleter<U>& d,
75 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
Howard Hinnant73d21a42010-09-04 23:28:19 +000076#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000077 template <class U>
78 Deleter(Deleter<U> d,
79 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
80 : state_(d.state()) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +000081#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000082public:
83 int state() const {return state_;}
84 void set_state(int i) {state_ = i;}
85
86 void operator()(T* p) {delete p;}
87};
88
89int 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}