Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef PlatformSTL_h | 5 #ifndef PlatformSTL_h |
| 6 #define PlatformSTL_h | 6 #define PlatformSTL_h |
| 7 | 7 |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #define PLATFORM_EXPORT | 10 #define PLATFORM_EXPORT |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 static_assert(sizeof(T) < 0, "do not use array with size as type"); | 115 static_assert(sizeof(T) < 0, "do not use array with size as type"); |
| 116 }; | 116 }; |
| 117 | 117 |
| 118 template <typename T> class unique_ptr { | 118 template <typename T> class unique_ptr { |
| 119 public: | 119 public: |
| 120 typedef typename remove_extent<T>::type ValueType; | 120 typedef typename remove_extent<T>::type ValueType; |
| 121 typedef ValueType* PtrType; | 121 typedef ValueType* PtrType; |
| 122 | 122 |
| 123 unique_ptr() : m_ptr(nullptr) {} | 123 unique_ptr() : m_ptr(nullptr) {} |
| 124 unique_ptr(std::nullptr_t) : m_ptr(nullptr) {} | 124 unique_ptr(std::nullptr_t) : m_ptr(nullptr) {} |
| 125 unique_ptr(const unique_ptr&); | |
| 125 unique_ptr(unique_ptr&&); | 126 unique_ptr(unique_ptr&&); |
| 126 template <typename U, typename = typename enable_if<is_convertible<U*, T*>:: value>::type> unique_ptr(unique_ptr<U>&&); | 127 template <typename U, typename = typename enable_if<is_convertible<U*, T*>:: value>::type> unique_ptr(unique_ptr<U>&&); |
| 127 | 128 |
| 128 ~unique_ptr() | 129 ~unique_ptr() |
| 129 { | 130 { |
| 130 OwnedPtrDeleter<T>::deletePtr(m_ptr); | 131 OwnedPtrDeleter<T>::deletePtr(m_ptr); |
| 131 m_ptr = nullptr; | 132 m_ptr = nullptr; |
| 132 } | 133 } |
| 133 | 134 |
| 134 PtrType get() const { return m_ptr; } | 135 PtrType get() const { return m_ptr; } |
| 135 | 136 |
| 136 void reset(PtrType = nullptr); | 137 void reset(PtrType = nullptr); |
| 137 PtrType release(); | 138 PtrType release(); |
| 138 | 139 |
| 139 ValueType& operator*() const { DCHECK(m_ptr); return *m_ptr; } | 140 ValueType& operator*() const { DCHECK(m_ptr); return *m_ptr; } |
| 140 PtrType operator->() const { DCHECK(m_ptr); return m_ptr; } | 141 PtrType operator->() const { DCHECK(m_ptr); return m_ptr; } |
| 141 | 142 |
| 142 ValueType& operator[](std::ptrdiff_t i) const; | 143 ValueType& operator[](std::ptrdiff_t i) const; |
| 143 | 144 |
| 144 bool operator!() const { return !m_ptr; } | 145 bool operator!() const { return !m_ptr; } |
| 145 explicit operator bool() const { return m_ptr; } | 146 explicit operator bool() const { return m_ptr; } |
| 146 | 147 |
| 147 unique_ptr& operator=(std::nullptr_t) { reset(); return *this; } | 148 unique_ptr& operator=(std::nullptr_t) { reset(); return *this; } |
| 148 | 149 |
| 149 | 150 unique_ptr& operator=(const unique_ptr&); |
| 150 unique_ptr& operator=(unique_ptr&&); | 151 unique_ptr& operator=(unique_ptr&&); |
| 151 template <typename U> unique_ptr& operator=(unique_ptr<U>&&); | 152 template <typename U> unique_ptr& operator=(unique_ptr<U>&&); |
| 152 | 153 |
| 153 void swap(unique_ptr& o) { std::swap(m_ptr, o.m_ptr); } | 154 void swap(unique_ptr& o) { std::swap(m_ptr, o.m_ptr); } |
| 154 | 155 |
| 155 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } | 156 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } |
| 156 | 157 |
| 157 explicit unique_ptr(PtrType ptr) : m_ptr(ptr) {} | 158 explicit unique_ptr(PtrType ptr) : m_ptr(ptr) {} |
| 158 | 159 |
| 159 private: | 160 private: |
| 161 PtrType internalRelease() const | |
|
pfeldman
2016/07/15 23:14:07
How is this different from release()
eostroukhov-old
2016/07/15 23:45:53
This is an ugly hack - this method is actually con
| |
| 162 { | |
| 163 PtrType ptr = m_ptr; | |
| 164 m_ptr = nullptr; | |
| 165 return ptr; | |
| 166 } | |
| 160 | 167 |
| 161 // We should never have two unique_ptrs for the same underlying object | 168 // We should never have two unique_ptrs for the same underlying object |
| 162 // (otherwise we'll get double-destruction), so these equality operators | 169 // (otherwise we'll get double-destruction), so these equality operators |
| 163 // should never be needed. | 170 // should never be needed. |
| 164 template <typename U> bool operator==(const unique_ptr<U>&) const | 171 template <typename U> bool operator==(const unique_ptr<U>&) const |
| 165 { | 172 { |
| 166 static_assert(!sizeof(U*), "unique_ptrs should never be equal"); | 173 static_assert(!sizeof(U*), "unique_ptrs should never be equal"); |
| 167 return false; | 174 return false; |
| 168 } | 175 } |
| 169 template <typename U> bool operator!=(const unique_ptr<U>&) const | 176 template <typename U> bool operator!=(const unique_ptr<U>&) const |
| 170 { | 177 { |
| 171 static_assert(!sizeof(U*), "unique_ptrs should never be equal"); | 178 static_assert(!sizeof(U*), "unique_ptrs should never be equal"); |
| 172 return false; | 179 return false; |
| 173 } | 180 } |
| 174 | 181 |
| 175 PtrType m_ptr; | 182 mutable PtrType m_ptr; |
| 176 }; | 183 }; |
| 177 | 184 |
| 178 | 185 |
| 179 template <typename T> inline void unique_ptr<T>::reset(PtrType ptr) | 186 template <typename T> inline void unique_ptr<T>::reset(PtrType ptr) |
| 180 { | 187 { |
| 181 PtrType p = m_ptr; | 188 PtrType p = m_ptr; |
| 182 m_ptr = ptr; | 189 m_ptr = ptr; |
| 183 OwnedPtrDeleter<T>::deletePtr(p); | 190 OwnedPtrDeleter<T>::deletePtr(p); |
| 184 } | 191 } |
| 185 | 192 |
| 186 template <typename T> inline typename unique_ptr<T>::PtrType unique_ptr<T>::rele ase() | 193 template <typename T> inline typename unique_ptr<T>::PtrType unique_ptr<T>::rele ase() |
| 187 { | 194 { |
| 188 PtrType ptr = m_ptr; | 195 PtrType ptr = m_ptr; |
| 189 m_ptr = nullptr; | 196 m_ptr = nullptr; |
| 190 return ptr; | 197 return ptr; |
| 191 } | 198 } |
| 192 | 199 |
| 193 template <typename T> inline typename unique_ptr<T>::ValueType& unique_ptr<T>::o perator[](std::ptrdiff_t i) const | 200 template <typename T> inline typename unique_ptr<T>::ValueType& unique_ptr<T>::o perator[](std::ptrdiff_t i) const |
| 194 { | 201 { |
| 195 static_assert(is_array<T>::value, "elements access is possible for arrays on ly"); | 202 static_assert(is_array<T>::value, "elements access is possible for arrays on ly"); |
| 196 DCHECK(m_ptr); | 203 DCHECK(m_ptr); |
| 197 DCHECK_GE(i, 0); | 204 DCHECK_GE(i, 0); |
| 198 return m_ptr[i]; | 205 return m_ptr[i]; |
| 199 } | 206 } |
| 200 | 207 |
| 208 template <typename T> inline unique_ptr<T>::unique_ptr(const unique_ptr<T>& o) | |
| 209 : m_ptr(o.internalRelease()) | |
| 210 { | |
| 211 } | |
| 212 | |
| 201 template <typename T> inline unique_ptr<T>::unique_ptr(unique_ptr<T>&& o) | 213 template <typename T> inline unique_ptr<T>::unique_ptr(unique_ptr<T>&& o) |
| 202 : m_ptr(o.release()) | 214 : m_ptr(o.release()) |
| 203 { | 215 { |
| 204 } | 216 } |
| 205 | 217 |
| 206 template <typename T> | 218 template <typename T> |
| 207 template <typename U, typename> inline unique_ptr<T>::unique_ptr(unique_ptr<U>&& o) | 219 template <typename U, typename> inline unique_ptr<T>::unique_ptr(unique_ptr<U>&& o) |
| 208 : m_ptr(o.release()) | 220 : m_ptr(o.release()) |
| 209 { | 221 { |
| 210 static_assert(!is_array<T>::value, "pointers to array must never be converte d"); | 222 static_assert(!is_array<T>::value, "pointers to array must never be converte d"); |
| 211 } | 223 } |
| 212 | 224 |
| 225 template <typename T> inline unique_ptr<T>& unique_ptr<T>::operator=(const uniqu e_ptr<T>& o) | |
| 226 { | |
| 227 PtrType ptr = m_ptr; | |
|
pfeldman
2016/07/15 23:14:07
Looks like the same code as below, reuse?
eostroukhov-old
2016/07/15 23:45:53
Done.
| |
| 228 m_ptr = o.internalRelease(); | |
| 229 DCHECK(!ptr || m_ptr != ptr); | |
| 230 OwnedPtrDeleter<T>::deletePtr(ptr); | |
| 231 | |
| 232 return *this; | |
| 233 } | |
| 234 | |
| 213 template <typename T> inline unique_ptr<T>& unique_ptr<T>::operator=(unique_ptr< T>&& o) | 235 template <typename T> inline unique_ptr<T>& unique_ptr<T>::operator=(unique_ptr< T>&& o) |
| 214 { | 236 { |
| 215 PtrType ptr = m_ptr; | 237 PtrType ptr = m_ptr; |
| 216 m_ptr = o.release(); | 238 m_ptr = o.release(); |
| 217 DCHECK(!ptr || m_ptr != ptr); | 239 DCHECK(!ptr || m_ptr != ptr); |
| 218 OwnedPtrDeleter<T>::deletePtr(ptr); | 240 OwnedPtrDeleter<T>::deletePtr(ptr); |
| 219 | 241 |
| 220 return *this; | 242 return *this; |
| 221 } | 243 } |
| 222 | 244 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 272 | 294 |
| 273 #endif // defined(__APPLE__) && !defined(_LIBCPP_VERSION) | 295 #endif // defined(__APPLE__) && !defined(_LIBCPP_VERSION) |
| 274 | 296 |
| 275 template <typename T> | 297 template <typename T> |
| 276 std::unique_ptr<T> wrapUnique(T* ptr) | 298 std::unique_ptr<T> wrapUnique(T* ptr) |
| 277 { | 299 { |
| 278 return std::unique_ptr<T>(ptr); | 300 return std::unique_ptr<T>(ptr); |
| 279 } | 301 } |
| 280 | 302 |
| 281 #endif // PlatformSTL_h | 303 #endif // PlatformSTL_h |
| OLD | NEW |