1/*
2 *  Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
3 *
4 *  This library is free software; you can redistribute it and/or
5 *  modify it under the terms of the GNU Library General Public
6 *  License as published by the Free Software Foundation; either
7 *  version 2 of the License, or (at your option) any later version.
8 *
9 *  This library is distributed in the hope that it will be useful,
10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 *  Library General Public License for more details.
13 *
14 *  You should have received a copy of the GNU Library General Public License
15 *  along with this library; see the file COPYING.LIB.  If not, write to
16 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 *  Boston, MA 02110-1301, USA.
18 *
19 */
20
21#ifndef WTF_OwnPtr_h
22#define WTF_OwnPtr_h
23
24#include <wtf/Assertions.h>
25#include <wtf/Noncopyable.h>
26#include <wtf/OwnPtrCommon.h>
27#include <algorithm>
28#include <cstddef>
29#include <memory>
30
31namespace WTF {
32
33    template<typename T> class PassOwnPtr;
34    template<typename T> PassOwnPtr<T> adoptPtr(T*);
35
36    template<typename T> class OwnPtr {
37    public:
38        typedef T ValueType;
39        typedef ValueType* PtrType;
40
41        OwnPtr() : m_ptr(0) { }
42        OwnPtr(std::nullptr_t) : m_ptr(0) { }
43
44        // See comment in PassOwnPtr.h for why this takes a const reference.
45        template<typename U> OwnPtr(const PassOwnPtr<U>& o);
46
47        ~OwnPtr() { deleteOwnedPtr(m_ptr); }
48
49        PtrType get() const { return m_ptr; }
50
51        void clear();
52        PassOwnPtr<T> release();
53        PtrType leakPtr() WARN_UNUSED_RETURN;
54
55        ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; }
56        PtrType operator->() const { ASSERT(m_ptr); return m_ptr; }
57
58        bool operator!() const { return !m_ptr; }
59
60        // This conversion operator allows implicit conversion to bool but not to other integer types.
61        typedef PtrType OwnPtr::*UnspecifiedBoolType;
62        operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::m_ptr : 0; }
63
64        OwnPtr& operator=(const PassOwnPtr<T>&);
65        OwnPtr& operator=(std::nullptr_t) { clear(); return *this; }
66        template<typename U> OwnPtr& operator=(const PassOwnPtr<U>&);
67
68        OwnPtr(OwnPtr&&);
69        template<typename U> OwnPtr(OwnPtr<U>&&);
70
71        OwnPtr& operator=(OwnPtr&&);
72        template<typename U> OwnPtr& operator=(OwnPtr<U>&&);
73
74        void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); }
75
76    private:
77        explicit OwnPtr(PtrType ptr) : m_ptr(ptr) { }
78
79        // We should never have two OwnPtrs for the same underlying object (otherwise we'll get
80        // double-destruction), so these equality operators should never be needed.
81        template<typename U> bool operator==(const OwnPtr<U>&) { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
82        template<typename U> bool operator!=(const OwnPtr<U>&) { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
83        template<typename U> bool operator==(const PassOwnPtr<U>&) { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
84        template<typename U> bool operator!=(const PassOwnPtr<U>&) { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
85
86        PtrType m_ptr;
87    };
88
89    template<typename T> template<typename U> inline OwnPtr<T>::OwnPtr(const PassOwnPtr<U>& o)
90        : m_ptr(o.leakPtr())
91    {
92    }
93
94    template<typename T> inline void OwnPtr<T>::clear()
95    {
96        PtrType ptr = m_ptr;
97        m_ptr = 0;
98        deleteOwnedPtr(ptr);
99    }
100
101    template<typename T> inline PassOwnPtr<T> OwnPtr<T>::release()
102    {
103        PtrType ptr = m_ptr;
104        m_ptr = 0;
105        return adoptPtr(ptr);
106    }
107
108    template<typename T> inline typename OwnPtr<T>::PtrType OwnPtr<T>::leakPtr()
109    {
110        PtrType ptr = m_ptr;
111        m_ptr = 0;
112        return ptr;
113    }
114
115    template<typename T> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<T>& o)
116    {
117        PtrType ptr = m_ptr;
118        m_ptr = o.leakPtr();
119        ASSERT(!ptr || m_ptr != ptr);
120        deleteOwnedPtr(ptr);
121        return *this;
122    }
123
124    template<typename T> template<typename U> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<U>& o)
125    {
126        PtrType ptr = m_ptr;
127        m_ptr = o.leakPtr();
128        ASSERT(!ptr || m_ptr != ptr);
129        deleteOwnedPtr(ptr);
130        return *this;
131    }
132
133    template<typename T> inline OwnPtr<T>::OwnPtr(OwnPtr<T>&& o)
134        : m_ptr(o.leakPtr())
135    {
136    }
137
138    template<typename T> template<typename U> inline OwnPtr<T>::OwnPtr(OwnPtr<U>&& o)
139        : m_ptr(o.leakPtr())
140    {
141    }
142
143    template<typename T> inline auto OwnPtr<T>::operator=(OwnPtr&& o) -> OwnPtr&
144    {
145        ASSERT(!o || o != m_ptr);
146        OwnPtr ptr = WTF::move(o);
147        swap(ptr);
148        return *this;
149    }
150
151    template<typename T> template<typename U> inline auto OwnPtr<T>::operator=(OwnPtr<U>&& o) -> OwnPtr&
152    {
153        ASSERT(!o || o != m_ptr);
154        OwnPtr ptr = WTF::move(o);
155        swap(ptr);
156        return *this;
157    }
158
159    template<typename T> inline void swap(OwnPtr<T>& a, OwnPtr<T>& b)
160    {
161        a.swap(b);
162    }
163
164    template<typename T, typename U> inline bool operator==(const OwnPtr<T>& a, U* b)
165    {
166        return a.get() == b;
167    }
168
169    template<typename T, typename U> inline bool operator==(T* a, const OwnPtr<U>& b)
170    {
171        return a == b.get();
172    }
173
174    template<typename T, typename U> inline bool operator!=(const OwnPtr<T>& a, U* b)
175    {
176        return a.get() != b;
177    }
178
179    template<typename T, typename U> inline bool operator!=(T* a, const OwnPtr<U>& b)
180    {
181        return a != b.get();
182    }
183
184    template<typename T> inline typename OwnPtr<T>::PtrType getPtr(const OwnPtr<T>& p)
185    {
186        return p.get();
187    }
188
189} // namespace WTF
190
191using WTF::OwnPtr;
192
193#endif // WTF_OwnPtr_h
194