pointer_deleter01.pass.cpp revision b64f8b07c104c6cc986570ac8ee0ed16a9f23976
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
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
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
44public:
45#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
46    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    }
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
64    Deleter() : state_(5) {}
65
66#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
67    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);
76#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
77    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()) {}
81#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
82public:
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}
100