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