blob: 61545a1742368be856147348e06323b288e0e63f [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 move ctor
15
16#include <memory>
17#include <cassert>
18
19// test move ctor. Should only require a MoveConstructible deleter, or if
20// deleter is a reference, not even that.
21
22struct A
23{
24 static int count;
25 A() {++count;}
26 A(const A&) {++count;}
27 ~A() {--count;}
28};
29
30int A::count = 0;
31
32template <class T>
33class Deleter
34{
35 int state_;
36
Howard Hinnant73d21a42010-09-04 23:28:19 +000037#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000038 Deleter(const Deleter&);
39 Deleter& operator=(const Deleter&);
Howard Hinnant73d21a42010-09-04 23:28:19 +000040#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000041 Deleter(Deleter&);
42 Deleter& operator=(Deleter&);
Howard Hinnant73d21a42010-09-04 23:28:19 +000043#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000044
45public:
Howard Hinnant73d21a42010-09-04 23:28:19 +000046#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000047 Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
48 Deleter& operator=(Deleter&& r)
49 {
50 state_ = r.state_;
51 r.state_ = 0;
52 return *this;
53 }
Howard Hinnant73d21a42010-09-04 23:28:19 +000054#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000055 operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
56 Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
57 Deleter& operator=(std::__rv<Deleter> r)
58 {
59 state_ = r->state_;
60 r->state_ = 0;
61 return *this;
62 }
Howard Hinnant73d21a42010-09-04 23:28:19 +000063#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000064
65 Deleter() : state_(5) {}
66
Howard Hinnant73d21a42010-09-04 23:28:19 +000067#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000068 template <class U>
69 Deleter(Deleter<U>&& d,
70 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
71 : state_(d.state()) {d.set_state(0);}
72
73private:
74 template <class U>
75 Deleter(const Deleter<U>& d,
76 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
Howard Hinnant73d21a42010-09-04 23:28:19 +000077#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000078 template <class U>
79 Deleter(Deleter<U> d,
80 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
81 : state_(d.state()) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +000082#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000083public:
84 int state() const {return state_;}
85 void set_state(int i) {state_ = i;}
86
87 void operator()(T* p) {delete p;}
88};
89
90class CDeleter
91{
92 int state_;
93
94 CDeleter(CDeleter&);
95 CDeleter& operator=(CDeleter&);
96public:
97
98 CDeleter() : state_(5) {}
99
100 int state() const {return state_;}
101 void set_state(int s) {state_ = s;}
102
103 void operator()(A* p) {delete p;}
104};
105
106int main()
107{
108 {
109 std::unique_ptr<A> s(new A);
110 A* p = s.get();
111 std::unique_ptr<A> s2 = std::move(s);
112 assert(s2.get() == p);
113 assert(s.get() == 0);
114 assert(A::count == 1);
115 }
116 assert(A::count == 0);
117 {
118 std::unique_ptr<A, Deleter<A> > s(new A);
119 A* p = s.get();
120 std::unique_ptr<A, Deleter<A> > s2 = std::move(s);
121 assert(s2.get() == p);
122 assert(s.get() == 0);
123 assert(A::count == 1);
124 assert(s2.get_deleter().state() == 5);
125 assert(s.get_deleter().state() == 0);
126 }
127 assert(A::count == 0);
128 {
129 CDeleter d;
130 std::unique_ptr<A, CDeleter&> s(new A, d);
131 A* p = s.get();
132 std::unique_ptr<A, CDeleter&> s2 = std::move(s);
133 assert(s2.get() == p);
134 assert(s.get() == 0);
135 assert(A::count == 1);
136 d.set_state(6);
137 assert(s2.get_deleter().state() == d.state());
138 assert(s.get_deleter().state() == d.state());
139 }
140 assert(A::count == 0);
141}