d520e42cf0106db852c80a7cc56a5eee428d2795
[WebKit-https.git] / Source / WTF / wtf / OwnPtr.h
1 /*
2  *  Copyright (C) 2006, 2007, 2008, 2009, 2010, 2014 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/Atomics.h>
26 #include <wtf/GetPtr.h>
27 #include <wtf/Noncopyable.h>
28 #include <wtf/OwnPtrCommon.h>
29 #include <algorithm>
30 #include <cstddef>
31 #include <memory>
32
33 namespace WTF {
34
35     template<typename T> class PassOwnPtr;
36     template<typename T> PassOwnPtr<T> adoptPtr(T*);
37
38     template<typename T> class OwnPtr {
39     public:
40         typedef T ValueType;
41         typedef ValueType* PtrType;
42
43         OwnPtr() : m_ptr(0) { }
44         OwnPtr(std::nullptr_t) : m_ptr(0) { }
45
46         // See comment in PassOwnPtr.h for why this takes a const reference.
47         template<typename U> OwnPtr(const PassOwnPtr<U>& o);
48
49         ~OwnPtr() { deleteOwnedPtr(m_ptr); }
50
51         PtrType get() const { return m_ptr; }
52
53         void clear();
54         PassOwnPtr<T> release();
55         PtrType leakPtr() WARN_UNUSED_RETURN;
56
57         ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; }
58         PtrType operator->() const { ASSERT(m_ptr); return m_ptr; }
59
60         bool operator!() const { return !m_ptr; }
61
62         // This conversion operator allows implicit conversion to bool but not to other integer types.
63         typedef PtrType OwnPtr::*UnspecifiedBoolType;
64         operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::m_ptr : 0; }
65
66         OwnPtr& operator=(const PassOwnPtr<T>&);
67         OwnPtr& operator=(std::nullptr_t) { clear(); return *this; }
68         template<typename U> OwnPtr& operator=(const PassOwnPtr<U>&);
69
70         OwnPtr(OwnPtr&&);
71         template<typename U> OwnPtr(OwnPtr<U>&&);
72
73         OwnPtr& operator=(OwnPtr&&);
74         template<typename U> OwnPtr& operator=(OwnPtr<U>&&);
75
76         void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); }
77         
78         // Construct an object to store into this OwnPtr, but only so long as this OwnPtr
79         // doesn't already point to an object. This will ensure that after you call this,
80         // the OwnPtr will point to an instance of T, even if called concurrently. This
81         // instance may or may not have been created by this call. Moreover, this call uses
82         // an opportunistic transaction, in that we may create an instance of T and then
83         // immediately throw it away, if in the process of creating that instance some
84         // other thread was doing the same thing and stored its instance into this pointer
85         // before we had a chance to do so.
86         template<typename... Args>
87         void createTransactionally(Args...);
88
89     private:
90         explicit OwnPtr(PtrType ptr) : m_ptr(ptr) { }
91
92         // We should never have two OwnPtrs for the same underlying object (otherwise we'll get
93         // double-destruction), so these equality operators should never be needed.
94         template<typename U> bool operator==(const OwnPtr<U>&) { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
95         template<typename U> bool operator!=(const OwnPtr<U>&) { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
96         template<typename U> bool operator==(const PassOwnPtr<U>&) { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
97         template<typename U> bool operator!=(const PassOwnPtr<U>&) { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
98
99         PtrType m_ptr;
100     };
101
102     template<typename T> template<typename U> inline OwnPtr<T>::OwnPtr(const PassOwnPtr<U>& o)
103         : m_ptr(o.leakPtr())
104     {
105     }
106
107     template<typename T> inline void OwnPtr<T>::clear()
108     {
109         PtrType ptr = m_ptr;
110         m_ptr = 0;
111         deleteOwnedPtr(ptr);
112     }
113
114     template<typename T> inline PassOwnPtr<T> OwnPtr<T>::release()
115     {
116         PtrType ptr = m_ptr;
117         m_ptr = 0;
118         return adoptPtr(ptr);
119     }
120
121     template<typename T> inline typename OwnPtr<T>::PtrType OwnPtr<T>::leakPtr()
122     {
123         PtrType ptr = m_ptr;
124         m_ptr = 0;
125         return ptr;
126     }
127
128     template<typename T> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<T>& o)
129     {
130         PtrType ptr = m_ptr;
131         m_ptr = o.leakPtr();
132         ASSERT(!ptr || m_ptr != ptr);
133         deleteOwnedPtr(ptr);
134         return *this;
135     }
136
137     template<typename T> template<typename U> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<U>& o)
138     {
139         PtrType ptr = m_ptr;
140         m_ptr = o.leakPtr();
141         ASSERT(!ptr || m_ptr != ptr);
142         deleteOwnedPtr(ptr);
143         return *this;
144     }
145
146     template<typename T> inline OwnPtr<T>::OwnPtr(OwnPtr<T>&& o)
147         : m_ptr(o.leakPtr())
148     {
149     }
150
151     template<typename T> template<typename U> inline OwnPtr<T>::OwnPtr(OwnPtr<U>&& o)
152         : m_ptr(o.leakPtr())
153     {
154     }
155
156     template<typename T> inline auto OwnPtr<T>::operator=(OwnPtr&& o) -> OwnPtr&
157     {
158         ASSERT(!o || o != m_ptr);
159         OwnPtr ptr = WTF::move(o);
160         swap(ptr);
161         return *this;
162     }
163
164     template<typename T> template<typename U> inline auto OwnPtr<T>::operator=(OwnPtr<U>&& o) -> OwnPtr&
165     {
166         ASSERT(!o || o != m_ptr);
167         OwnPtr ptr = WTF::move(o);
168         swap(ptr);
169         return *this;
170     }
171
172     template<typename T> inline void swap(OwnPtr<T>& a, OwnPtr<T>& b)
173     {
174         a.swap(b);
175     }
176
177     template<typename T, typename U> inline bool operator==(const OwnPtr<T>& a, U* b)
178     {
179         return a.get() == b; 
180     }
181
182     template<typename T, typename U> inline bool operator==(T* a, const OwnPtr<U>& b) 
183     {
184         return a == b.get(); 
185     }
186
187     template<typename T, typename U> inline bool operator!=(const OwnPtr<T>& a, U* b)
188     {
189         return a.get() != b; 
190     }
191
192     template<typename T, typename U> inline bool operator!=(T* a, const OwnPtr<U>& b)
193     {
194         return a != b.get(); 
195     }
196
197     template <typename T> struct IsSmartPtr<OwnPtr<T>> {
198         static const bool value = true;
199     };
200
201     template<typename T> template<typename... Args> inline void OwnPtr<T>::createTransactionally(Args... args)
202     {
203         if (m_ptr) {
204             WTF::loadLoadFence();
205             return;
206         }
207         
208         T* newObject = new T(args...);
209         WTF::storeStoreFence();
210 #if ENABLE(COMPARE_AND_SWAP)
211         do {
212             if (m_ptr) {
213                 delete newObject;
214                 WTF::loadLoadFence();
215                 return;
216             }
217         } while (!WTF::weakCompareAndSwap(bitwise_cast<void*volatile*>(&m_ptr), nullptr, newObject));
218 #else
219         m_ptr = newObject;
220 #endif
221     }
222
223 } // namespace WTF
224
225 using WTF::OwnPtr;
226
227 #endif // WTF_OwnPtr_h