1 /* 2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2013 Intel Corporation. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #ifndef WTF_PassOwnPtr_h 28 #define WTF_PassOwnPtr_h 29 30 #include "wtf/NullPtr.h" 31 #include "wtf/OwnPtrCommon.h" 32 33 namespace WTF { 34 35 template<typename T> class OwnPtr; 36 template<typename T> class PassOwnPtr; 37 template<typename T> PassOwnPtr<T> adoptPtr(T*); 38 template<typename T> PassOwnPtr<T[]> adoptArrayPtr(T*); 39 40 template<typename T> class PassOwnPtr { 41 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(PassOwnPtr); 42 public: 43 typedef typename RemoveExtent<T>::Type ValueType; 44 typedef ValueType* PtrType; 45 PassOwnPtr()46 PassOwnPtr() : m_ptr(0) { } PassOwnPtr(std::nullptr_t)47 PassOwnPtr(std::nullptr_t) : m_ptr(0) { } 48 49 // It somewhat breaks the type system to allow transfer of ownership out of 50 // a const PassOwnPtr. However, it makes it much easier to work with PassOwnPtr 51 // temporaries, and we don't have a need to use real const PassOwnPtrs anyway. PassOwnPtr(const PassOwnPtr & o)52 PassOwnPtr(const PassOwnPtr& o) : m_ptr(o.leakPtr()) { } 53 template<typename U> PassOwnPtr(const PassOwnPtr<U>&, EnsurePtrConvertibleArgDecl(U, T)); 54 ~PassOwnPtr()55 ~PassOwnPtr() { OwnedPtrDeleter<T>::deletePtr(m_ptr); } 56 get()57 PtrType get() const { return m_ptr; } 58 59 PtrType leakPtr() const WARN_UNUSED_RETURN; 60 61 ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; } 62 PtrType operator->() const { ASSERT(m_ptr); return m_ptr; } 63 64 bool operator!() const { return !m_ptr; } 65 66 // This conversion operator allows implicit conversion to bool but not to other integer types. 67 typedef PtrType PassOwnPtr::*UnspecifiedBoolType; UnspecifiedBoolType()68 operator UnspecifiedBoolType() const { return m_ptr ? &PassOwnPtr::m_ptr : 0; } 69 70 template<typename U> friend PassOwnPtr<U> adoptPtr(U*); 71 template<typename U> friend PassOwnPtr<U[]> adoptArrayPtr(U*); 72 template<typename U> friend class OwnPtr; 73 74 private: PassOwnPtr(PtrType ptr)75 explicit PassOwnPtr(PtrType ptr) : m_ptr(ptr) { } 76 77 PassOwnPtr& operator=(const PassOwnPtr&) { COMPILE_ASSERT(!sizeof(T*), PassOwnPtr_should_never_be_assigned_to); return *this; } 78 79 // We should never have two OwnPtrs for the same underlying object (otherwise we'll get 80 // double-destruction), so these equality operators should never be needed. 81 template<typename U> bool operator==(const PassOwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; } 82 template<typename U> bool operator!=(const PassOwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; } 83 template<typename U> bool operator==(const OwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; } 84 template<typename U> bool operator!=(const OwnPtr<U>&) const { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; } 85 86 mutable PtrType m_ptr; 87 }; 88 PassOwnPtr(const PassOwnPtr<U> & o,EnsurePtrConvertibleArgDefn (U,T))89 template<typename T> template<typename U> inline PassOwnPtr<T>::PassOwnPtr(const PassOwnPtr<U>& o, EnsurePtrConvertibleArgDefn(U, T)) 90 : m_ptr(o.leakPtr()) 91 { 92 COMPILE_ASSERT(!IsArray<T>::value, Pointers_to_array_must_never_be_converted); 93 } 94 leakPtr()95 template<typename T> inline typename PassOwnPtr<T>::PtrType PassOwnPtr<T>::leakPtr() const 96 { 97 PtrType ptr = m_ptr; 98 m_ptr = 0; 99 return ptr; 100 } 101 102 template<typename T, typename U> inline bool operator==(const PassOwnPtr<T>& a, U* b) 103 { 104 return a.get() == b; 105 } 106 107 template<typename T, typename U> inline bool operator==(T* a, const PassOwnPtr<U>& b) 108 { 109 return a == b.get(); 110 } 111 112 template<typename T, typename U> inline bool operator!=(const PassOwnPtr<T>& a, U* b) 113 { 114 return a.get() != b; 115 } 116 117 template<typename T, typename U> inline bool operator!=(T* a, const PassOwnPtr<U>& b) 118 { 119 return a != b.get(); 120 } 121 adoptPtr(T * ptr)122 template<typename T> inline PassOwnPtr<T> adoptPtr(T* ptr) 123 { 124 return PassOwnPtr<T>(ptr); 125 } 126 adoptArrayPtr(T * ptr)127 template<typename T> inline PassOwnPtr<T[]> adoptArrayPtr(T* ptr) 128 { 129 return PassOwnPtr<T[]>(ptr); 130 } 131 static_pointer_cast(const PassOwnPtr<U> & p)132 template<typename T, typename U> inline PassOwnPtr<T> static_pointer_cast(const PassOwnPtr<U>& p) 133 { 134 COMPILE_ASSERT(!IsArray<T>::value, Pointers_to_array_must_never_be_converted); 135 return adoptPtr(static_cast<T*>(p.leakPtr())); 136 } 137 getPtr(const PassOwnPtr<T> & p)138 template<typename T> inline T* getPtr(const PassOwnPtr<T>& p) 139 { 140 return p.get(); 141 } 142 143 } // namespace WTF 144 145 using WTF::PassOwnPtr; 146 using WTF::adoptPtr; 147 using WTF::adoptArrayPtr; 148 using WTF::static_pointer_cast; 149 150 #endif // WTF_PassOwnPtr_h 151