1c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant//===----------------------------------------------------------------------===//
2c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant//
3c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant//                     The LLVM Compiler Infrastructure
4c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant//
5b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// Source Licenses. See LICENSE.TXT for details.
7c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant//
8c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant//===----------------------------------------------------------------------===//
9c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
10c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// <memory>
11c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
12c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// unique_ptr
13c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
14c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// Test unique_ptr converting move ctor
15c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
16c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include <memory>
17c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant#include <cassert>
18c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
19c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// test converting move ctor.  Should only require a MoveConstructible deleter, or if
20c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant//    deleter is a reference, not even that.
21c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant// Implicit version
22c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
23c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantstruct A
24c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{
25c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static int count;
26c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    A() {++count;}
27c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    A(const A&) {++count;}
28c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    virtual ~A() {--count;}
29c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant};
30c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
31c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantint A::count = 0;
32c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
33c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantstruct B
34c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    : public A
35c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{
36c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    static int count;
37c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    B() {++count;}
38c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    B(const B&) {++count;}
39c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    virtual ~B() {--count;}
40c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant};
41c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
42c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantint B::count = 0;
43c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
44c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnanttemplate <class T>
45c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantclass Deleter
46c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{
47c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    int state_;
48c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
4973d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
50c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    Deleter(const Deleter&);
51c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    Deleter& operator=(const Deleter&);
5273d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
53c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    Deleter(Deleter&);
54c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    Deleter& operator=(Deleter&);
5573d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
56c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
57c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantpublic:
5873d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
59c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
60c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    Deleter& operator=(Deleter&& r)
61c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    {
62c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant        state_ = r.state_;
63c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant        r.state_ = 0;
64c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant        return *this;
65c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    }
6673d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
67c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
68c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
69c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    Deleter& operator=(std::__rv<Deleter> r)
70c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    {
71c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant        state_ = r->state_;
72c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant        r->state_ = 0;
73c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant        return *this;
74c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    }
7573d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
76c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
77c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    Deleter() : state_(5) {}
78c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
7973d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
80c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    template <class U>
81c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant        Deleter(Deleter<U>&& d,
82c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant            typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
83c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant            : state_(d.state()) {d.set_state(0);}
84c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
85c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantprivate:
86c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    template <class U>
87c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant        Deleter(const Deleter<U>& d,
88c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant            typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
8973d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
90c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    template <class U>
91c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant        Deleter(Deleter<U> d,
92c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant            typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
93c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant            : state_(d.state()) {}
9473d21a4f0774d3fadab98e690619a359cfb160a3Howard Hinnant#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
95c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantpublic:
96c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    int state() const {return state_;}
97c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    void set_state(int i) {state_ = i;}
98c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
99c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    void operator()(T* p) {delete p;}
100c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant};
101c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant
102c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnantint main()
103c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant{
104c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    {
105c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    const std::unique_ptr<B, Deleter<B> > s(new B);
106c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    A* p = s.get();
107c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    std::unique_ptr<A, Deleter<A> > s2 = s;
108c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    assert(s2.get() == p);
109c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    assert(s.get() == 0);
110c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    assert(A::count == 1);
111c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    assert(B::count == 1);
112c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    assert(s2.get_deleter().state() == 5);
113c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    assert(s.get_deleter().state() == 0);
114c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    }
115c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    assert(A::count == 0);
116c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant    assert(B::count == 0);
117c52f43e72dfcea03037729649da84c23b3beb04aHoward Hinnant}
118