move02.pass.cpp revision c52f43e72dfcea03037729649da84c23b3beb04a
1//===----------------------------------------------------------------------===//
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
37#ifdef _LIBCPP_MOVE
38    Deleter(const Deleter&);
39    Deleter& operator=(const Deleter&);
40#else  // _LIBCPP_MOVE
41    Deleter(Deleter&);
42    Deleter& operator=(Deleter&);
43#endif  // _LIBCPP_MOVE
44
45public:
46#ifdef _LIBCPP_MOVE
47    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    }
54#else  // _LIBCPP_MOVE
55    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    }
63#endif  // _LIBCPP_MOVE
64
65    Deleter() : state_(5) {}
66
67#ifdef _LIBCPP_MOVE
68    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);
77#else  // _LIBCPP_MOVE
78    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()) {}
82#endif  // _LIBCPP_MOVE
83public:
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
106std::unique_ptr<A>
107source1()
108{
109    return std::unique_ptr<A>(new A);
110}
111
112void sink1(std::unique_ptr<A> p)
113{
114}
115
116std::unique_ptr<A, Deleter<A> >
117source2()
118{
119    return std::unique_ptr<A, Deleter<A> >(new A);
120}
121
122void sink2(std::unique_ptr<A, Deleter<A> > p)
123{
124}
125
126std::unique_ptr<A, CDeleter&>
127source3()
128{
129    static CDeleter d;
130    return std::unique_ptr<A, CDeleter&>(new A, d);
131}
132
133void sink3(std::unique_ptr<A, CDeleter&> p)
134{
135}
136
137int main()
138{
139    sink1(source1());
140    sink2(source2());
141    sink3(source3());
142    assert(A::count == 0);
143}
144