| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2013 Intel Corporation. All rights reserved. | 3 * Copyright (C) 2013 Intel Corporation. All rights reserved. |
| 4 * | 4 * |
| 5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
| 6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
| 7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
| 8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
| 9 * | 9 * |
| 10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #define WTF_OwnPtr_h | 23 #define WTF_OwnPtr_h |
| 24 | 24 |
| 25 #include "wtf/HashTableDeletedValueType.h" | 25 #include "wtf/HashTableDeletedValueType.h" |
| 26 #include "wtf/Noncopyable.h" | 26 #include "wtf/Noncopyable.h" |
| 27 #include "wtf/OwnPtrCommon.h" | 27 #include "wtf/OwnPtrCommon.h" |
| 28 #include <algorithm> | 28 #include <algorithm> |
| 29 #include <utility> | 29 #include <utility> |
| 30 | 30 |
| 31 namespace WTF { | 31 namespace WTF { |
| 32 | 32 |
| 33 template <typename T> class PassOwnPtr; | 33 template <typename T> |
| 34 | 34 class PassOwnPtr; |
| 35 template <typename T> class OwnPtr { | 35 |
| 36 WTF_MAKE_NONCOPYABLE(OwnPtr); | 36 template <typename T> |
| 37 public: | 37 class OwnPtr { |
| 38 typedef typename RemoveExtent<T>::Type ValueType; | 38 WTF_MAKE_NONCOPYABLE(OwnPtr); |
| 39 typedef ValueType* PtrType; | 39 |
| 40 | 40 public: |
| 41 OwnPtr() : m_ptr(nullptr) {} | 41 typedef typename RemoveExtent<T>::Type ValueType; |
| 42 OwnPtr(std::nullptr_t) : m_ptr(nullptr) {} | 42 typedef ValueType* PtrType; |
| 43 | 43 |
| 44 // See comment in PassOwnPtr.h for why this takes a const reference. | 44 OwnPtr() |
| 45 OwnPtr(const PassOwnPtr<T>&); | 45 : m_ptr(nullptr) {} |
| 46 template <typename U> OwnPtr(const PassOwnPtr<U>&, EnsurePtrConvertibleArgDe
cl(U, T)); | 46 OwnPtr(std::nullptr_t) |
| 47 | 47 : m_ptr(nullptr) {} |
| 48 // Hash table deleted values, which are only constructed and never copied or | 48 |
| 49 // destroyed. | 49 // See comment in PassOwnPtr.h for why this takes a const reference. |
| 50 OwnPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) {} | 50 OwnPtr(const PassOwnPtr<T>&); |
| 51 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue
(); } | 51 template <typename U> |
| 52 | 52 OwnPtr(const PassOwnPtr<U>&, EnsurePtrConvertibleArgDecl(U, T)); |
| 53 ~OwnPtr() | 53 |
| 54 { | 54 // Hash table deleted values, which are only constructed and never copied or |
| 55 OwnedPtrDeleter<T>::deletePtr(m_ptr); | 55 // destroyed. |
| 56 m_ptr = nullptr; | 56 OwnPtr(HashTableDeletedValueType) |
| 57 } | 57 : m_ptr(hashTableDeletedValue()) {} |
| 58 | 58 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue()
; } |
| 59 PtrType get() const { return m_ptr; } | 59 |
| 60 | 60 ~OwnPtr() { |
| 61 void clear(); | 61 OwnedPtrDeleter<T>::deletePtr(m_ptr); |
| 62 PassOwnPtr<T> release(); | 62 m_ptr = nullptr; |
| 63 PtrType leakPtr() WARN_UNUSED_RETURN; | 63 } |
| 64 | 64 |
| 65 ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; } | 65 PtrType get() const { return m_ptr; } |
| 66 PtrType operator->() const { ASSERT(m_ptr); return m_ptr; } | 66 |
| 67 | 67 void clear(); |
| 68 ValueType& operator[](std::ptrdiff_t i) const; | 68 PassOwnPtr<T> release(); |
| 69 | 69 PtrType leakPtr() WARN_UNUSED_RETURN; |
| 70 bool operator!() const { return !m_ptr; } | 70 |
| 71 | 71 ValueType& operator*() const { |
| 72 // This conversion operator allows implicit conversion to bool but not to | 72 ASSERT(m_ptr); |
| 73 // other integer types. | 73 return *m_ptr; |
| 74 typedef PtrType OwnPtr::*UnspecifiedBoolType; | 74 } |
| 75 operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::m_ptr : 0; } | 75 PtrType operator->() const { |
| 76 | 76 ASSERT(m_ptr); |
| 77 OwnPtr& operator=(const PassOwnPtr<T>&); | 77 return m_ptr; |
| 78 OwnPtr& operator=(std::nullptr_t) { clear(); return *this; } | 78 } |
| 79 template <typename U> OwnPtr& operator=(const PassOwnPtr<U>&); | 79 |
| 80 | 80 ValueType& operator[](std::ptrdiff_t i) const; |
| 81 OwnPtr(OwnPtr&&); | 81 |
| 82 template <typename U> OwnPtr(OwnPtr<U>&&); | 82 bool operator!() const { return !m_ptr; } |
| 83 | 83 |
| 84 OwnPtr& operator=(OwnPtr&&); | 84 // This conversion operator allows implicit conversion to bool but not to |
| 85 template <typename U> OwnPtr& operator=(OwnPtr<U>&&); | 85 // other integer types. |
| 86 | 86 typedef PtrType OwnPtr::*UnspecifiedBoolType; |
| 87 void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); } | 87 operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::m_ptr : 0; } |
| 88 | 88 |
| 89 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } | 89 OwnPtr& operator=(const PassOwnPtr<T>&); |
| 90 | 90 OwnPtr& operator=(std::nullptr_t) { |
| 91 private: | 91 clear(); |
| 92 // We should never have two OwnPtrs for the same underlying object | 92 return *this; |
| 93 // (otherwise we'll get double-destruction), so these equality operators | 93 } |
| 94 // should never be needed. | 94 template <typename U> |
| 95 template <typename U> bool operator==(const OwnPtr<U>&) const | 95 OwnPtr& operator=(const PassOwnPtr<U>&); |
| 96 { | 96 |
| 97 static_assert(!sizeof(U*), "OwnPtrs should never be equal"); | 97 OwnPtr(OwnPtr&&); |
| 98 return false; | 98 template <typename U> |
| 99 } | 99 OwnPtr(OwnPtr<U>&&); |
| 100 template <typename U> bool operator!=(const OwnPtr<U>&) const | 100 |
| 101 { | 101 OwnPtr& operator=(OwnPtr&&); |
| 102 static_assert(!sizeof(U*), "OwnPtrs should never be equal"); | 102 template <typename U> |
| 103 return false; | 103 OwnPtr& operator=(OwnPtr<U>&&); |
| 104 } | 104 |
| 105 template <typename U> bool operator==(const PassOwnPtr<U>&) const | 105 void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); } |
| 106 { | 106 |
| 107 static_assert(!sizeof(U*), "OwnPtrs should never be equal"); | 107 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } |
| 108 return false; | 108 |
| 109 } | 109 private: |
| 110 template <typename U> bool operator!=(const PassOwnPtr<U>&) const | 110 // We should never have two OwnPtrs for the same underlying object |
| 111 { | 111 // (otherwise we'll get double-destruction), so these equality operators |
| 112 static_assert(!sizeof(U*), "OwnPtrs should never be equal"); | 112 // should never be needed. |
| 113 return false; | 113 template <typename U> |
| 114 } | 114 bool operator==(const OwnPtr<U>&) const { |
| 115 | 115 static_assert(!sizeof(U*), "OwnPtrs should never be equal"); |
| 116 PtrType m_ptr; | 116 return false; |
| 117 } |
| 118 template <typename U> |
| 119 bool operator!=(const OwnPtr<U>&) const { |
| 120 static_assert(!sizeof(U*), "OwnPtrs should never be equal"); |
| 121 return false; |
| 122 } |
| 123 template <typename U> |
| 124 bool operator==(const PassOwnPtr<U>&) const { |
| 125 static_assert(!sizeof(U*), "OwnPtrs should never be equal"); |
| 126 return false; |
| 127 } |
| 128 template <typename U> |
| 129 bool operator!=(const PassOwnPtr<U>&) const { |
| 130 static_assert(!sizeof(U*), "OwnPtrs should never be equal"); |
| 131 return false; |
| 132 } |
| 133 |
| 134 PtrType m_ptr; |
| 117 }; | 135 }; |
| 118 | 136 |
| 119 template <typename T> inline OwnPtr<T>::OwnPtr(const PassOwnPtr<T>& o) | 137 template <typename T> |
| 120 : m_ptr(o.leakPtr()) | 138 inline OwnPtr<T>::OwnPtr(const PassOwnPtr<T>& o) |
| 121 { | 139 : m_ptr(o.leakPtr()) { |
| 122 } | 140 } |
| 123 | 141 |
| 124 template <typename T> | 142 template <typename T> |
| 125 template <typename U> inline OwnPtr<T>::OwnPtr(const PassOwnPtr<U>& o, EnsurePtr
ConvertibleArgDefn(U, T)) | 143 template <typename U> |
| 126 : m_ptr(o.leakPtr()) | 144 inline OwnPtr<T>::OwnPtr(const PassOwnPtr<U>& o, EnsurePtrConvertibleArgDefn(U,
T)) |
| 127 { | 145 : m_ptr(o.leakPtr()) { |
| 128 static_assert(!IsArray<T>::value, "pointers to array must never be converted
"); | 146 static_assert(!IsArray<T>::value, "pointers to array must never be converted")
; |
| 129 } | 147 } |
| 130 | 148 |
| 131 template <typename T> inline void OwnPtr<T>::clear() | 149 template <typename T> |
| 132 { | 150 inline void OwnPtr<T>::clear() { |
| 133 PtrType ptr = m_ptr; | 151 PtrType ptr = m_ptr; |
| 134 m_ptr = nullptr; | 152 m_ptr = nullptr; |
| 135 OwnedPtrDeleter<T>::deletePtr(ptr); | 153 OwnedPtrDeleter<T>::deletePtr(ptr); |
| 136 } | 154 } |
| 137 | 155 |
| 138 template <typename T> inline PassOwnPtr<T> OwnPtr<T>::release() | 156 template <typename T> |
| 139 { | 157 inline PassOwnPtr<T> OwnPtr<T>::release() { |
| 140 PtrType ptr = m_ptr; | 158 PtrType ptr = m_ptr; |
| 141 m_ptr = nullptr; | 159 m_ptr = nullptr; |
| 142 return PassOwnPtr<T>(ptr); | 160 return PassOwnPtr<T>(ptr); |
| 143 } | 161 } |
| 144 | 162 |
| 145 template <typename T> inline typename OwnPtr<T>::PtrType OwnPtr<T>::leakPtr() | 163 template <typename T> |
| 146 { | 164 inline typename OwnPtr<T>::PtrType OwnPtr<T>::leakPtr() { |
| 147 PtrType ptr = m_ptr; | 165 PtrType ptr = m_ptr; |
| 148 m_ptr = nullptr; | 166 m_ptr = nullptr; |
| 149 return ptr; | 167 return ptr; |
| 150 } | 168 } |
| 151 | 169 |
| 152 template <typename T> inline typename OwnPtr<T>::ValueType& OwnPtr<T>::operator[
](std::ptrdiff_t i) const | 170 template <typename T> |
| 153 { | 171 inline typename OwnPtr<T>::ValueType& OwnPtr<T>::operator[](std::ptrdiff_t i) co
nst { |
| 154 static_assert(IsArray<T>::value, "elements access is possible for arrays onl
y"); | 172 static_assert(IsArray<T>::value, "elements access is possible for arrays only"
); |
| 155 ASSERT(m_ptr); | 173 ASSERT(m_ptr); |
| 156 ASSERT(i >= 0); | 174 ASSERT(i >= 0); |
| 157 return m_ptr[i]; | 175 return m_ptr[i]; |
| 158 } | 176 } |
| 159 | 177 |
| 160 template <typename T> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<T>
& o) | 178 template <typename T> |
| 161 { | 179 inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<T>& o) { |
| 162 PtrType ptr = m_ptr; | 180 PtrType ptr = m_ptr; |
| 163 m_ptr = o.leakPtr(); | 181 m_ptr = o.leakPtr(); |
| 164 ASSERT(!ptr || m_ptr != ptr); | 182 ASSERT(!ptr || m_ptr != ptr); |
| 165 OwnedPtrDeleter<T>::deletePtr(ptr); | 183 OwnedPtrDeleter<T>::deletePtr(ptr); |
| 166 return *this; | 184 return *this; |
| 167 } | 185 } |
| 168 | 186 |
| 169 template <typename T> | 187 template <typename T> |
| 170 template <typename U> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<U>
& o) | 188 template <typename U> |
| 171 { | 189 inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<U>& o) { |
| 172 static_assert(!IsArray<T>::value, "pointers to array must never be converted
"); | 190 static_assert(!IsArray<T>::value, "pointers to array must never be converted")
; |
| 173 PtrType ptr = m_ptr; | 191 PtrType ptr = m_ptr; |
| 174 m_ptr = o.leakPtr(); | 192 m_ptr = o.leakPtr(); |
| 175 ASSERT(!ptr || m_ptr != ptr); | 193 ASSERT(!ptr || m_ptr != ptr); |
| 176 OwnedPtrDeleter<T>::deletePtr(ptr); | 194 OwnedPtrDeleter<T>::deletePtr(ptr); |
| 177 return *this; | 195 return *this; |
| 178 } | 196 } |
| 179 | 197 |
| 180 template <typename T> inline OwnPtr<T>::OwnPtr(OwnPtr<T>&& o) | 198 template <typename T> |
| 181 : m_ptr(o.leakPtr()) | 199 inline OwnPtr<T>::OwnPtr(OwnPtr<T>&& o) |
| 182 { | 200 : m_ptr(o.leakPtr()) { |
| 183 } | 201 } |
| 184 | 202 |
| 185 template <typename T> | 203 template <typename T> |
| 186 template <typename U> inline OwnPtr<T>::OwnPtr(OwnPtr<U>&& o) | 204 template <typename U> |
| 187 : m_ptr(o.leakPtr()) | 205 inline OwnPtr<T>::OwnPtr(OwnPtr<U>&& o) |
| 188 { | 206 : m_ptr(o.leakPtr()) { |
| 189 static_assert(!IsArray<T>::value, "pointers to array must never be converted
"); | 207 static_assert(!IsArray<T>::value, "pointers to array must never be converted")
; |
| 190 } | 208 } |
| 191 | 209 |
| 192 template <typename T> inline OwnPtr<T>& OwnPtr<T>::operator=(OwnPtr<T>&& o) | 210 template <typename T> |
| 193 { | 211 inline OwnPtr<T>& OwnPtr<T>::operator=(OwnPtr<T>&& o) { |
| 194 PtrType ptr = m_ptr; | 212 PtrType ptr = m_ptr; |
| 195 m_ptr = o.leakPtr(); | 213 m_ptr = o.leakPtr(); |
| 196 ASSERT(!ptr || m_ptr != ptr); | 214 ASSERT(!ptr || m_ptr != ptr); |
| 197 OwnedPtrDeleter<T>::deletePtr(ptr); | 215 OwnedPtrDeleter<T>::deletePtr(ptr); |
| 198 | 216 |
| 199 return *this; | 217 return *this; |
| 200 } | 218 } |
| 201 | 219 |
| 202 template <typename T> | 220 template <typename T> |
| 203 template <typename U> inline OwnPtr<T>& OwnPtr<T>::operator=(OwnPtr<U>&& o) | 221 template <typename U> |
| 204 { | 222 inline OwnPtr<T>& OwnPtr<T>::operator=(OwnPtr<U>&& o) { |
| 205 static_assert(!IsArray<T>::value, "pointers to array must never be converted
"); | 223 static_assert(!IsArray<T>::value, "pointers to array must never be converted")
; |
| 206 PtrType ptr = m_ptr; | 224 PtrType ptr = m_ptr; |
| 207 m_ptr = o.leakPtr(); | 225 m_ptr = o.leakPtr(); |
| 208 ASSERT(!ptr || m_ptr != ptr); | 226 ASSERT(!ptr || m_ptr != ptr); |
| 209 OwnedPtrDeleter<T>::deletePtr(ptr); | 227 OwnedPtrDeleter<T>::deletePtr(ptr); |
| 210 | 228 |
| 211 return *this; | 229 return *this; |
| 212 } | 230 } |
| 213 | 231 |
| 214 template <typename T> inline void swap(OwnPtr<T>& a, OwnPtr<T>& b) | 232 template <typename T> |
| 215 { | 233 inline void swap(OwnPtr<T>& a, OwnPtr<T>& b) { |
| 216 a.swap(b); | 234 a.swap(b); |
| 217 } | 235 } |
| 218 | 236 |
| 219 template <typename T, typename U> inline bool operator==(const OwnPtr<T>& a, U*
b) | 237 template <typename T, typename U> |
| 220 { | 238 inline bool operator==(const OwnPtr<T>& a, U* b) { |
| 221 return a.get() == b; | 239 return a.get() == b; |
| 222 } | 240 } |
| 223 | 241 |
| 224 template <typename T, typename U> inline bool operator==(T* a, const OwnPtr<U>&
b) | 242 template <typename T, typename U> |
| 225 { | 243 inline bool operator==(T* a, const OwnPtr<U>& b) { |
| 226 return a == b.get(); | 244 return a == b.get(); |
| 227 } | 245 } |
| 228 | 246 |
| 229 template <typename T, typename U> inline bool operator!=(const OwnPtr<T>& a, U*
b) | 247 template <typename T, typename U> |
| 230 { | 248 inline bool operator!=(const OwnPtr<T>& a, U* b) { |
| 231 return a.get() != b; | 249 return a.get() != b; |
| 232 } | 250 } |
| 233 | 251 |
| 234 template <typename T, typename U> inline bool operator!=(T* a, const OwnPtr<U>&
b) | 252 template <typename T, typename U> |
| 235 { | 253 inline bool operator!=(T* a, const OwnPtr<U>& b) { |
| 236 return a != b.get(); | 254 return a != b.get(); |
| 237 } | 255 } |
| 238 | 256 |
| 239 template <typename T> inline typename OwnPtr<T>::PtrType getPtr(const OwnPtr<T>&
p) | 257 template <typename T> |
| 240 { | 258 inline typename OwnPtr<T>::PtrType getPtr(const OwnPtr<T>& p) { |
| 241 return p.get(); | 259 return p.get(); |
| 242 } | 260 } |
| 243 | 261 |
| 244 } // namespace WTF | 262 } // namespace WTF |
| 245 | 263 |
| 246 using WTF::OwnPtr; | 264 using WTF::OwnPtr; |
| 247 | 265 |
| 248 #endif // WTF_OwnPtr_h | 266 #endif // WTF_OwnPtr_h |
| OLD | NEW |