2 * Copyright (C) 2012 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
30 #include "WeakSetInlines.h"
31 #include <wtf/Assertions.h>
32 #include <wtf/NullPtr.h>
33 #include <wtf/TypeTraits.h>
37 template<typename T
> class Weak
;
38 template<typename T
> class PassWeak
;
39 template<typename T
> PassWeak
<T
> adoptWeak(WeakImpl
*);
41 template<typename Base
, typename T
> class WeakImplAccessor
{
45 T
* operator->() const;
50 bool was(GetType
) const;
54 template<typename T
> class PassWeak
: public WeakImplAccessor
<PassWeak
<T
>, T
> {
56 friend class WeakImplAccessor
<PassWeak
<T
>, T
>;
57 typedef typename WeakImplAccessor
<PassWeak
<T
>, T
>::GetType GetType
;
60 PassWeak(std::nullptr_t
);
61 PassWeak(GetType
, WeakHandleOwner
* = 0, void* context
= 0);
63 // It somewhat breaks the type system to allow transfer of ownership out of
64 // a const PassWeak. However, it makes it much easier to work with PassWeak
65 // temporaries, and we don't have a need to use real const PassWeaks anyway.
66 PassWeak(const PassWeak
&);
67 template<typename U
> PassWeak(const PassWeak
<U
>&);
71 bool operator!() const;
73 // This conversion operator allows implicit conversion to bool but not to other integer types.
74 typedef JSValue (PassWeak::*UnspecifiedBoolType
);
75 operator UnspecifiedBoolType
*() const;
77 WeakImpl
* leakImpl() const WARN_UNUSED_RETURN
;
80 friend PassWeak adoptWeak
<T
>(WeakImpl
*);
81 explicit PassWeak(WeakImpl
*);
86 template<typename Base
, typename T
> inline T
* WeakImplAccessor
<Base
, T
>::operator->() const
88 ASSERT(static_cast<const Base
*>(this)->m_impl
&& static_cast<const Base
*>(this)->m_impl
->state() == WeakImpl::Live
);
89 return jsCast
<T
*>(static_cast<const Base
*>(this)->m_impl
->jsValue().asCell());
92 template<typename Base
, typename T
> inline T
& WeakImplAccessor
<Base
, T
>::operator*() const
94 ASSERT(static_cast<const Base
*>(this)->m_impl
&& static_cast<const Base
*>(this)->m_impl
->state() == WeakImpl::Live
);
95 return *jsCast
<T
*>(static_cast<const Base
*>(this)->m_impl
->jsValue().asCell());
98 template<typename Base
, typename T
> inline typename WeakImplAccessor
<Base
, T
>::GetType WeakImplAccessor
<Base
, T
>::get() const
100 if (!static_cast<const Base
*>(this)->m_impl
|| static_cast<const Base
*>(this)->m_impl
->state() != WeakImpl::Live
)
102 return jsCast
<T
*>(static_cast<const Base
*>(this)->m_impl
->jsValue().asCell());
106 template<typename Base
, typename T
> inline bool WeakImplAccessor
<Base
, T
>::was(typename WeakImplAccessor
<Base
, T
>::GetType other
) const
108 return jsCast
<T
*>(static_cast<const Base
*>(this)->m_impl
->jsValue().asCell()) == other
;
112 template<typename T
> inline PassWeak
<T
>::PassWeak()
117 template<typename T
> inline PassWeak
<T
>::PassWeak(std::nullptr_t
)
122 template<typename T
> inline PassWeak
<T
>::PassWeak(typename PassWeak
<T
>::GetType getType
, WeakHandleOwner
* weakOwner
, void* context
)
123 : m_impl(getType
? WeakSet::allocate(getType
, weakOwner
, context
) : 0)
127 template<typename T
> inline PassWeak
<T
>::PassWeak(const PassWeak
& o
)
128 : m_impl(o
.leakImpl())
132 template<typename T
> template<typename U
> inline PassWeak
<T
>::PassWeak(const PassWeak
<U
>& o
)
133 : m_impl(o
.leakImpl())
137 template<typename T
> inline PassWeak
<T
>::~PassWeak()
141 WeakSet::deallocate(m_impl
);
144 template<typename T
> inline bool PassWeak
<T
>::operator!() const
146 return !m_impl
|| m_impl
->state() != WeakImpl::Live
|| !m_impl
->jsValue();
149 template<typename T
> inline PassWeak
<T
>::operator UnspecifiedBoolType
*() const
151 return reinterpret_cast<UnspecifiedBoolType
*>(!!*this);
154 template<typename T
> inline PassWeak
<T
>::PassWeak(WeakImpl
* impl
)
159 template<typename T
> inline WeakImpl
* PassWeak
<T
>::leakImpl() const
162 std::swap(tmp
, const_cast<WeakImpl
*&>(m_impl
));
166 template<typename T
> PassWeak
<T
> inline adoptWeak(WeakImpl
* impl
)
168 return PassWeak
<T
>(impl
);
171 template<typename T
, typename U
> inline bool operator==(const PassWeak
<T
>& a
, const PassWeak
<U
>& b
)
173 return a
.get() == b
.get();
176 template<typename T
, typename U
> inline bool operator==(const PassWeak
<T
>& a
, const Weak
<U
>& b
)
178 return a
.get() == b
.get();
181 template<typename T
, typename U
> inline bool operator==(const Weak
<T
>& a
, const PassWeak
<U
>& b
)
183 return a
.get() == b
.get();
186 template<typename T
, typename U
> inline bool operator==(const PassWeak
<T
>& a
, U
* b
)
191 template<typename T
, typename U
> inline bool operator==(T
* a
, const PassWeak
<U
>& b
)
196 template<typename T
, typename U
> inline bool operator!=(const PassWeak
<T
>& a
, const PassWeak
<U
>& b
)
198 return a
.get() != b
.get();
201 template<typename T
, typename U
> inline bool operator!=(const PassWeak
<T
>& a
, const Weak
<U
>& b
)
203 return a
.get() != b
.get();
206 template<typename T
, typename U
> inline bool operator!=(const Weak
<T
>& a
, const PassWeak
<U
>& b
)
208 return a
.get() != b
.get();
211 template<typename T
, typename U
> inline bool operator!=(const PassWeak
<T
>& a
, U
* b
)
216 template<typename T
, typename U
> inline bool operator!=(T
* a
, const PassWeak
<U
>& b
)