| /* |
| * Copyright (C) 2010 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| * THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef WKRetainPtr_h |
| #define WKRetainPtr_h |
| |
| #include <WebKit/WKType.h> |
| #include <algorithm> |
| #include <wtf/GetPtr.h> |
| #include <wtf/HashFunctions.h> |
| #include <wtf/HashTraits.h> |
| #include <wtf/RefPtr.h> |
| |
| namespace WebKit { |
| |
| template<typename T> class WKRetainPtr { |
| public: |
| typedef T PtrType; |
| |
| WKRetainPtr() |
| : m_ptr(0) |
| { |
| } |
| |
| WKRetainPtr(PtrType ptr) |
| : m_ptr(ptr) |
| { |
| if (ptr) |
| WKRetain(ptr); |
| } |
| |
| template<typename U> WKRetainPtr(const WKRetainPtr<U>& o) |
| : m_ptr(o.get()) |
| { |
| if (PtrType ptr = m_ptr) |
| WKRetain(ptr); |
| } |
| |
| WKRetainPtr(const WKRetainPtr& o) |
| : m_ptr(o.m_ptr) |
| { |
| if (PtrType ptr = m_ptr) |
| WKRetain(ptr); |
| } |
| |
| template<typename U> WKRetainPtr(WKRetainPtr<U>&& o) |
| : m_ptr(o.leakRef()) |
| { |
| } |
| |
| WKRetainPtr(WKRetainPtr&& o) |
| : m_ptr(o.leakRef()) |
| { |
| } |
| |
| ~WKRetainPtr() |
| { |
| if (PtrType ptr = m_ptr) |
| WKRelease(ptr); |
| } |
| |
| // Hash table deleted values, which are only constructed and never copied or destroyed. |
| WKRetainPtr(WTF::HashTableDeletedValueType) |
| : m_ptr(hashTableDeletedValue()) |
| { |
| } |
| |
| bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); } |
| constexpr static T hashTableDeletedValue() { return reinterpret_cast<T>(-1); } |
| |
| PtrType get() const { return m_ptr; } |
| |
| void clear() |
| { |
| PtrType ptr = m_ptr; |
| m_ptr = 0; |
| if (ptr) |
| WKRelease(ptr); |
| } |
| |
| PtrType leakRef() |
| { |
| PtrType ptr = m_ptr; |
| m_ptr = 0; |
| return ptr; |
| } |
| |
| PtrType operator->() const { return m_ptr; } |
| bool operator!() const { return !m_ptr; } |
| |
| // This conversion operator allows implicit conversion to bool but not to other integer types. |
| typedef PtrType WKRetainPtr::*UnspecifiedBoolType; |
| operator UnspecifiedBoolType() const { return m_ptr ? &WKRetainPtr::m_ptr : 0; } |
| |
| WKRetainPtr& operator=(const WKRetainPtr&); |
| template<typename U> WKRetainPtr& operator=(const WKRetainPtr<U>&); |
| WKRetainPtr& operator=(PtrType); |
| template<typename U> WKRetainPtr& operator=(U*); |
| |
| WKRetainPtr& operator=(WKRetainPtr&&); |
| template<typename U> WKRetainPtr& operator=(WKRetainPtr<U>&&); |
| |
| void adopt(PtrType); |
| void swap(WKRetainPtr&); |
| |
| private: |
| template<typename U> friend WKRetainPtr<U> adoptWK(U); |
| enum WKAdoptTag { AdoptWK }; |
| WKRetainPtr(WKAdoptTag, PtrType ptr) |
| : m_ptr(ptr) { } |
| |
| PtrType m_ptr; |
| }; |
| |
| template<typename T> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(const WKRetainPtr<T>& o) |
| { |
| PtrType optr = o.get(); |
| if (optr) |
| WKRetain(optr); |
| PtrType ptr = m_ptr; |
| m_ptr = optr; |
| if (ptr) |
| WKRelease(ptr); |
| return *this; |
| } |
| |
| template<typename T> template<typename U> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(const WKRetainPtr<U>& o) |
| { |
| PtrType optr = o.get(); |
| if (optr) |
| WKRetain(optr); |
| PtrType ptr = m_ptr; |
| m_ptr = optr; |
| if (ptr) |
| WKRelease(ptr); |
| return *this; |
| } |
| |
| template<typename T> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(PtrType optr) |
| { |
| if (optr) |
| WKRetain(optr); |
| PtrType ptr = m_ptr; |
| m_ptr = optr; |
| if (ptr) |
| WKRelease(ptr); |
| return *this; |
| } |
| |
| template<typename T> template<typename U> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(U* optr) |
| { |
| if (optr) |
| WKRetain(optr); |
| PtrType ptr = m_ptr; |
| m_ptr = optr; |
| if (ptr) |
| WKRelease(ptr); |
| return *this; |
| } |
| |
| template<typename T> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(WKRetainPtr<T>&& o) |
| { |
| adopt(o.leakRef()); |
| return *this; |
| } |
| |
| template<typename T> template<typename U> inline WKRetainPtr<T>& WKRetainPtr<T>::operator=(WKRetainPtr<U>&& o) |
| { |
| adopt(o.leakRef()); |
| return *this; |
| } |
| |
| template<typename T> inline void WKRetainPtr<T>::adopt(PtrType optr) |
| { |
| PtrType ptr = m_ptr; |
| m_ptr = optr; |
| if (ptr) |
| WKRelease(ptr); |
| } |
| |
| template<typename T> inline void WKRetainPtr<T>::swap(WKRetainPtr<T>& o) |
| { |
| std::swap(m_ptr, o.m_ptr); |
| } |
| |
| template<typename T> inline void swap(WKRetainPtr<T>& a, WKRetainPtr<T>& b) |
| { |
| a.swap(b); |
| } |
| |
| template<typename T, typename U> inline bool operator==(const WKRetainPtr<T>& a, const WKRetainPtr<U>& b) |
| { |
| return a.get() == b.get(); |
| } |
| |
| template<typename T, typename U> inline bool operator==(const WKRetainPtr<T>& a, U* b) |
| { |
| return a.get() == b; |
| } |
| |
| template<typename T, typename U> inline bool operator==(T* a, const WKRetainPtr<U>& b) |
| { |
| return a == b.get(); |
| } |
| |
| template<typename T, typename U> inline bool operator!=(const WKRetainPtr<T>& a, const WKRetainPtr<U>& b) |
| { |
| return a.get() != b.get(); |
| } |
| |
| template<typename T, typename U> inline bool operator!=(const WKRetainPtr<T>& a, U* b) |
| { |
| return a.get() != b; |
| } |
| |
| template<typename T, typename U> inline bool operator!=(T* a, const WKRetainPtr<U>& b) |
| { |
| return a != b.get(); |
| } |
| |
| #if (defined(WIN32) || defined(_WIN32)) && !((_MSC_VER > 1900) && __clang__) |
| template<typename T> inline WKRetainPtr<T> adoptWK(T) _Check_return_; |
| #else |
| template<typename T> inline WKRetainPtr<T> adoptWK(T) __attribute__((warn_unused_result)); |
| #endif |
| template<typename T> inline WKRetainPtr<T> adoptWK(T o) |
| { |
| return WKRetainPtr<T>(WKRetainPtr<T>::AdoptWK, o); |
| } |
| |
| template<typename T> inline WKRetainPtr<T> retainWK(T ptr) |
| { |
| return ptr; |
| } |
| |
| } // namespace WebKit |
| |
| using WebKit::WKRetainPtr; |
| using WebKit::adoptWK; |
| using WebKit::retainWK; |
| |
| namespace WTF { |
| |
| template <typename T> struct IsSmartPtr<WKRetainPtr<T>> { |
| WTF_INTERNAL static const bool value = true; |
| }; |
| |
| template<typename P> struct DefaultHash<WKRetainPtr<P>> { |
| typedef PtrHash<WKRetainPtr<P>> Hash; |
| }; |
| |
| template<typename P> struct HashTraits<WKRetainPtr<P>> : SimpleClassHashTraits<WKRetainPtr<P>> { |
| static P emptyValue() { return nullptr; } |
| |
| typedef P PeekType; |
| static PeekType peek(const WKRetainPtr<P>& value) { return value.get(); } |
| static PeekType peek(P value) { return value; } |
| }; |
| |
| } // namespace WTF |
| |
| #endif // WKRetainPtr_h |