Remove home-brewed nullptr
[WebKit-https.git] / Source / JavaScriptCore / heap / PassWeak.h
1 /*
2  * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef PassWeak_h
27 #define PassWeak_h
28
29 #include "JSCell.h"
30 #include "WeakSetInlines.h"
31 #include <cstddef>
32 #include <wtf/Assertions.h>
33
34 namespace JSC {
35
36 template<typename T> class PassWeak;
37 template<typename T> PassWeak<T> adoptWeak(WeakImpl*);
38
39 template<typename T> class PassWeak {
40 public:
41     PassWeak();
42     PassWeak(std::nullptr_t);
43     PassWeak(T*, WeakHandleOwner* = 0, void* context = 0);
44
45     // It somewhat breaks the type system to allow transfer of ownership out of
46     // a const PassWeak. However, it makes it much easier to work with PassWeak
47     // temporaries, and we don't have a need to use real const PassWeaks anyway.
48     PassWeak(const PassWeak&);
49     template<typename U> PassWeak(const PassWeak<U>&);
50
51     ~PassWeak();
52
53     T* operator->() const;
54     T& operator*() const;
55     T* get() const;
56
57     bool operator!() const;
58
59     // This conversion operator allows implicit conversion to bool but not to other integer types.
60     typedef void* (PassWeak::*UnspecifiedBoolType);
61     operator UnspecifiedBoolType*() const;
62
63     WeakImpl* leakImpl() const WARN_UNUSED_RETURN;
64
65 private:
66     friend PassWeak adoptWeak<T>(WeakImpl*);
67     explicit PassWeak(WeakImpl*);
68
69     WeakImpl* m_impl;
70 };
71
72 template<typename T> inline PassWeak<T>::PassWeak()
73     : m_impl(0)
74 {
75 }
76
77 template<typename T> inline PassWeak<T>::PassWeak(std::nullptr_t)
78     : m_impl(0)
79 {
80 }
81
82 template<typename T> inline PassWeak<T>::PassWeak(T* cell, WeakHandleOwner* weakOwner, void* context)
83     : m_impl(cell ? WeakSet::allocate(cell, weakOwner, context) : 0)
84 {
85 }
86
87 template<typename T> inline PassWeak<T>::PassWeak(const PassWeak& o)
88     : m_impl(o.leakImpl())
89 {
90 }
91
92 template<typename T> template<typename U> inline PassWeak<T>::PassWeak(const PassWeak<U>& o)
93     : m_impl(o.leakImpl())
94 {
95 }
96
97 template<typename T> inline PassWeak<T>::~PassWeak()
98 {
99     if (!m_impl)
100         return;
101     WeakSet::deallocate(m_impl);
102 }
103
104 template<typename T> inline T* PassWeak<T>::operator->() const
105 {
106     ASSERT(m_impl && m_impl->state() == WeakImpl::Live);
107     return jsCast<T*>(m_impl->jsValue().asCell());
108 }
109
110 template<typename T> inline T& PassWeak<T>::operator*() const
111 {
112     ASSERT(m_impl && m_impl->state() == WeakImpl::Live);
113     return *jsCast<T*>(m_impl->jsValue().asCell());
114 }
115
116 template<typename T> inline T* PassWeak<T>::get() const
117 {
118     if (!m_impl || m_impl->state() != WeakImpl::Live)
119         return 0;
120     return jsCast<T*>(m_impl->jsValue().asCell());
121 }
122
123 template<typename T> inline bool PassWeak<T>::operator!() const
124 {
125     return !m_impl || m_impl->state() != WeakImpl::Live || !m_impl->jsValue();
126 }
127
128 template<typename T> inline PassWeak<T>::operator UnspecifiedBoolType*() const
129 {
130     return reinterpret_cast<UnspecifiedBoolType*>(!!*this);
131 }
132
133 template<typename T> inline PassWeak<T>::PassWeak(WeakImpl* impl)
134 : m_impl(impl)
135 {
136 }
137
138 template<typename T> inline WeakImpl* PassWeak<T>::leakImpl() const
139 {
140     WeakImpl* tmp = 0;
141     std::swap(tmp, const_cast<WeakImpl*&>(m_impl));
142     return tmp;
143 }
144
145 template<typename T> PassWeak<T> inline adoptWeak(WeakImpl* impl)
146 {
147     return PassWeak<T>(impl);
148 }
149
150 template<typename T, typename U> inline bool operator==(const PassWeak<T>& a, const PassWeak<U>& b) 
151 {
152     return a.get() == b.get(); 
153 }
154
155 template<typename T, typename U> inline bool operator==(const PassWeak<T>& a, const Weak<U>& b) 
156 {
157     return a.get() == b.get(); 
158 }
159
160 template<typename T, typename U> inline bool operator==(const Weak<T>& a, const PassWeak<U>& b) 
161 {
162     return a.get() == b.get(); 
163 }
164
165 template<typename T, typename U> inline bool operator==(const PassWeak<T>& a, U* b) 
166 {
167     return a.get() == b; 
168 }
169
170 template<typename T, typename U> inline bool operator==(T* a, const PassWeak<U>& b) 
171 {
172     return a == b.get(); 
173 }
174
175 template<typename T, typename U> inline bool operator!=(const PassWeak<T>& a, const PassWeak<U>& b) 
176 {
177     return a.get() != b.get(); 
178 }
179
180 template<typename T, typename U> inline bool operator!=(const PassWeak<T>& a, const Weak<U>& b) 
181 {
182     return a.get() != b.get(); 
183 }
184
185 template<typename T, typename U> inline bool operator!=(const Weak<T>& a, const PassWeak<U>& b) 
186 {
187     return a.get() != b.get(); 
188 }
189
190 template<typename T, typename U> inline bool operator!=(const PassWeak<T>& a, U* b)
191 {
192     return a.get() != b; 
193 }
194
195 template<typename T, typename U> inline bool operator!=(T* a, const PassWeak<U>& b) 
196 {
197     return a != b.get(); 
198 }
199
200 } // namespace JSC
201
202 #endif // PassWeak_h