OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // Scopers help you manage ownership of a pointer, helping you easily manage a | 5 // Scopers help you manage ownership of a pointer, helping you easily manage a |
6 // pointer within a scope, and automatically destroying the pointer at the end | 6 // pointer within a scope, and automatically destroying the pointer at the end |
7 // of a scope. There are two main classes you will use, which correspond to the | 7 // of a scope. There are two main classes you will use, which correspond to the |
8 // operators new/delete and new[]/delete[]. | 8 // operators new/delete and new[]/delete[]. |
9 // | 9 // |
10 // Example usage (scoped_ptr<T>): | 10 // Example usage (scoped_ptr<T>): |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 // } | 51 // } |
52 // scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) { | 52 // scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) { |
53 // return arg.Pass(); | 53 // return arg.Pass(); |
54 // } | 54 // } |
55 // | 55 // |
56 // { | 56 // { |
57 // scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay"). | 57 // scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay"). |
58 // TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay"). | 58 // TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay"). |
59 // scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo. | 59 // scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo. |
60 // scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2. | 60 // scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2. |
61 // PassThru(ptr2.Pass()); // ptr2 is correspondingly NULL. | 61 // PassThru(ptr2.Pass()); // ptr2 is correspondingly nullptr. |
62 // } | 62 // } |
63 // | 63 // |
64 // Notice that if you do not call Pass() when returning from PassThru(), or | 64 // Notice that if you do not call Pass() when returning from PassThru(), or |
65 // when invoking TakesOwnership(), the code will not compile because scopers | 65 // when invoking TakesOwnership(), the code will not compile because scopers |
66 // are not copyable; they only implement move semantics which require calling | 66 // are not copyable; they only implement move semantics which require calling |
67 // the Pass() function to signify a destructive transfer of state. CreateFoo() | 67 // the Pass() function to signify a destructive transfer of state. CreateFoo() |
68 // is different though because we are constructing a temporary on the return | 68 // is different though because we are constructing a temporary on the return |
69 // line and thus can avoid needing to call Pass(). | 69 // line and thus can avoid needing to call Pass(). |
70 // | 70 // |
71 // Pass() properly handles upcast in initialization, i.e. you can use a | 71 // Pass() properly handles upcast in initialization, i.e. you can use a |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>:: | 182 !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>:: |
183 value | 183 value |
184 }; | 184 }; |
185 }; | 185 }; |
186 | 186 |
187 // Minimal implementation of the core logic of scoped_ptr, suitable for | 187 // Minimal implementation of the core logic of scoped_ptr, suitable for |
188 // reuse in both scoped_ptr and its specializations. | 188 // reuse in both scoped_ptr and its specializations. |
189 template <class T, class D> | 189 template <class T, class D> |
190 class scoped_ptr_impl { | 190 class scoped_ptr_impl { |
191 public: | 191 public: |
192 explicit scoped_ptr_impl(T* p) : data_(p) { } | 192 explicit scoped_ptr_impl(T* p) : data_(p) {} |
193 | 193 |
194 // Initializer for deleters that have data parameters. | 194 // Initializer for deleters that have data parameters. |
195 scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} | 195 scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} |
196 | 196 |
197 // Templated constructor that destructively takes the value from another | 197 // Templated constructor that destructively takes the value from another |
198 // scoped_ptr_impl. | 198 // scoped_ptr_impl. |
199 template <typename U, typename V> | 199 template <typename U, typename V> |
200 scoped_ptr_impl(scoped_ptr_impl<U, V>* other) | 200 scoped_ptr_impl(scoped_ptr_impl<U, V>* other) |
201 : data_(other->release(), other->get_deleter()) { | 201 : data_(other->release(), other->get_deleter()) { |
202 // We do not support move-only deleters. We could modify our move | 202 // We do not support move-only deleters. We could modify our move |
203 // emulation to have base::subtle::move() and base::subtle::forward() | 203 // emulation to have base::subtle::move() and base::subtle::forward() |
204 // functions that are imperfect emulations of their C++11 equivalents, | 204 // functions that are imperfect emulations of their C++11 equivalents, |
205 // but until there's a requirement, just assume deleters are copyable. | 205 // but until there's a requirement, just assume deleters are copyable. |
206 } | 206 } |
207 | 207 |
208 template <typename U, typename V> | 208 template <typename U, typename V> |
209 void TakeState(scoped_ptr_impl<U, V>* other) { | 209 void TakeState(scoped_ptr_impl<U, V>* other) { |
210 // See comment in templated constructor above regarding lack of support | 210 // See comment in templated constructor above regarding lack of support |
211 // for move-only deleters. | 211 // for move-only deleters. |
212 reset(other->release()); | 212 reset(other->release()); |
213 get_deleter() = other->get_deleter(); | 213 get_deleter() = other->get_deleter(); |
214 } | 214 } |
215 | 215 |
216 ~scoped_ptr_impl() { | 216 ~scoped_ptr_impl() { |
217 if (data_.ptr != NULL) { | 217 if (data_.ptr != nullptr) { |
218 // Not using get_deleter() saves one function call in non-optimized | 218 // Not using get_deleter() saves one function call in non-optimized |
219 // builds. | 219 // builds. |
220 static_cast<D&>(data_)(data_.ptr); | 220 static_cast<D&>(data_)(data_.ptr); |
221 } | 221 } |
222 } | 222 } |
223 | 223 |
224 void reset(T* p) { | 224 void reset(T* p) { |
225 // This is a self-reset, which is no longer allowed: http://crbug.com/162971 | 225 // This is a self-reset, which is no longer allowed: http://crbug.com/162971 |
226 if (p != NULL && p == data_.ptr) | 226 if (p != nullptr && p == data_.ptr) |
227 abort(); | 227 abort(); |
228 | 228 |
229 // Note that running data_.ptr = p can lead to undefined behavior if | 229 // Note that running data_.ptr = p can lead to undefined behavior if |
230 // get_deleter()(get()) deletes this. In order to prevent this, reset() | 230 // get_deleter()(get()) deletes this. In order to prevent this, reset() |
231 // should update the stored pointer before deleting its old value. | 231 // should update the stored pointer before deleting its old value. |
232 // | 232 // |
233 // However, changing reset() to use that behavior may cause current code to | 233 // However, changing reset() to use that behavior may cause current code to |
234 // break in unexpected ways. If the destruction of the owned object | 234 // break in unexpected ways. If the destruction of the owned object |
235 // dereferences the scoped_ptr when it is destroyed by a call to reset(), | 235 // dereferences the scoped_ptr when it is destroyed by a call to reset(), |
236 // then it will incorrectly dispatch calls to |p| rather than the original | 236 // then it will incorrectly dispatch calls to |p| rather than the original |
237 // value of |data_.ptr|. | 237 // value of |data_.ptr|. |
238 // | 238 // |
239 // During the transition period, set the stored pointer to NULL while | 239 // During the transition period, set the stored pointer to nullptr while |
240 // deleting the object. Eventually, this safety check will be removed to | 240 // deleting the object. Eventually, this safety check will be removed to |
241 // prevent the scenario initially described from occuring and | 241 // prevent the scenario initially described from occuring and |
242 // http://crbug.com/176091 can be closed. | 242 // http://crbug.com/176091 can be closed. |
243 T* old = data_.ptr; | 243 T* old = data_.ptr; |
244 data_.ptr = NULL; | 244 data_.ptr = nullptr; |
245 if (old != NULL) | 245 if (old != nullptr) |
246 static_cast<D&>(data_)(old); | 246 static_cast<D&>(data_)(old); |
247 data_.ptr = p; | 247 data_.ptr = p; |
248 } | 248 } |
249 | 249 |
250 T* get() const { return data_.ptr; } | 250 T* get() const { return data_.ptr; } |
251 | 251 |
252 D& get_deleter() { return data_; } | 252 D& get_deleter() { return data_; } |
253 const D& get_deleter() const { return data_; } | 253 const D& get_deleter() const { return data_; } |
254 | 254 |
255 void swap(scoped_ptr_impl& p2) { | 255 void swap(scoped_ptr_impl& p2) { |
256 // Standard swap idiom: 'using std::swap' ensures that std::swap is | 256 // Standard swap idiom: 'using std::swap' ensures that std::swap is |
257 // present in the overload set, but we call swap unqualified so that | 257 // present in the overload set, but we call swap unqualified so that |
258 // any more-specific overloads can be used, if available. | 258 // any more-specific overloads can be used, if available. |
259 using std::swap; | 259 using std::swap; |
260 swap(static_cast<D&>(data_), static_cast<D&>(p2.data_)); | 260 swap(static_cast<D&>(data_), static_cast<D&>(p2.data_)); |
261 swap(data_.ptr, p2.data_.ptr); | 261 swap(data_.ptr, p2.data_.ptr); |
262 } | 262 } |
263 | 263 |
264 T* release() { | 264 T* release() { |
265 T* old_ptr = data_.ptr; | 265 T* old_ptr = data_.ptr; |
266 data_.ptr = NULL; | 266 data_.ptr = nullptr; |
267 return old_ptr; | 267 return old_ptr; |
268 } | 268 } |
269 | 269 |
270 private: | 270 private: |
271 // Needed to allow type-converting constructor. | 271 // Needed to allow type-converting constructor. |
272 template <typename U, typename V> friend class scoped_ptr_impl; | 272 template <typename U, typename V> friend class scoped_ptr_impl; |
273 | 273 |
274 // Use the empty base class optimization to allow us to have a D | 274 // Use the empty base class optimization to allow us to have a D |
275 // member, while avoiding any space overhead for it when D is an | 275 // member, while avoiding any space overhead for it when D is an |
276 // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good | 276 // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good |
277 // discussion of this technique. | 277 // discussion of this technique. |
278 struct Data : public D { | 278 struct Data : public D { |
279 explicit Data(T* ptr_in) : ptr(ptr_in) {} | 279 explicit Data(T* ptr_in) : ptr(ptr_in) {} |
280 Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {} | 280 Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {} |
281 T* ptr; | 281 T* ptr; |
282 }; | 282 }; |
283 | 283 |
284 Data data_; | 284 Data data_; |
285 | 285 |
286 DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl); | 286 DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl); |
287 }; | 287 }; |
288 | 288 |
289 } // namespace internal | 289 } // namespace internal |
290 | 290 |
291 } // namespace base | 291 } // namespace base |
292 | 292 |
293 // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> | 293 // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> |
294 // automatically deletes the pointer it holds (if any). | 294 // automatically deletes the pointer it holds (if any). |
295 // That is, scoped_ptr<T> owns the T object that it points to. | 295 // That is, scoped_ptr<T> owns the T object that it points to. |
296 // Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object. | 296 // Like a T*, a scoped_ptr<T> may hold either nullptr or a pointer to a T |
297 // Also like T*, scoped_ptr<T> is thread-compatible, and once you | 297 // object. Also like T*, scoped_ptr<T> is thread-compatible, and once you |
298 // dereference it, you get the thread safety guarantees of T. | 298 // dereference it, you get the thread safety guarantees of T. |
299 // | 299 // |
300 // The size of scoped_ptr is small. On most compilers, when using the | 300 // The size of scoped_ptr is small. On most compilers, when using the |
301 // DefaultDeleter, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters will | 301 // DefaultDeleter, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters will |
302 // increase the size proportional to whatever state they need to have. See | 302 // increase the size proportional to whatever state they need to have. See |
303 // comments inside scoped_ptr_impl<> for details. | 303 // comments inside scoped_ptr_impl<> for details. |
304 // | 304 // |
305 // Current implementation targets having a strict subset of C++11's | 305 // Current implementation targets having a strict subset of C++11's |
306 // unique_ptr<> features. Known deficiencies include not supporting move-only | 306 // unique_ptr<> features. Known deficiencies include not supporting move-only |
307 // deleteres, function pointers as deleters, and deleters with reference | 307 // deleteres, function pointers as deleters, and deleters with reference |
308 // types. | 308 // types. |
309 template <class T, class D = base::DefaultDeleter<T> > | 309 template <class T, class D = base::DefaultDeleter<T> > |
310 class scoped_ptr { | 310 class scoped_ptr { |
311 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) | 311 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) |
312 | 312 |
313 COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value, | 313 COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value, |
314 T_is_refcounted_type_and_needs_scoped_refptr); | 314 T_is_refcounted_type_and_needs_scoped_refptr); |
315 | 315 |
316 public: | 316 public: |
317 // The element and deleter types. | 317 // The element and deleter types. |
318 typedef T element_type; | 318 typedef T element_type; |
319 typedef D deleter_type; | 319 typedef D deleter_type; |
320 | 320 |
321 // Constructor. Defaults to initializing with NULL. | 321 // Constructor. Defaults to initializing with nullptr. |
322 scoped_ptr() : impl_(NULL) { } | 322 scoped_ptr() : impl_(nullptr) {} |
323 | 323 |
324 // Constructor. Takes ownership of p. | 324 // Constructor. Takes ownership of p. |
325 explicit scoped_ptr(element_type* p) : impl_(p) { } | 325 explicit scoped_ptr(element_type* p) : impl_(p) {} |
326 | 326 |
327 // Constructor. Allows initialization of a stateful deleter. | 327 // Constructor. Allows initialization of a stateful deleter. |
328 scoped_ptr(element_type* p, const D& d) : impl_(p, d) { } | 328 scoped_ptr(element_type* p, const D& d) : impl_(p, d) {} |
| 329 |
| 330 // Constructor. Allows construction from a nullptr. |
| 331 scoped_ptr(decltype(nullptr)) : impl_(nullptr) {} |
329 | 332 |
330 // Constructor. Allows construction from a scoped_ptr rvalue for a | 333 // Constructor. Allows construction from a scoped_ptr rvalue for a |
331 // convertible type and deleter. | 334 // convertible type and deleter. |
332 // | 335 // |
333 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct | 336 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct |
334 // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor | 337 // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor |
335 // has different post-conditions if D is a reference type. Since this | 338 // has different post-conditions if D is a reference type. Since this |
336 // implementation does not support deleters with reference type, | 339 // implementation does not support deleters with reference type, |
337 // we do not need a separate move constructor allowing us to avoid one | 340 // we do not need a separate move constructor allowing us to avoid one |
338 // use of SFINAE. You only need to care about this if you modify the | 341 // use of SFINAE. You only need to care about this if you modify the |
339 // implementation of scoped_ptr. | 342 // implementation of scoped_ptr. |
340 template <typename U, typename V> | 343 template <typename U, typename V> |
341 scoped_ptr(scoped_ptr<U, V> other) : impl_(&other.impl_) { | 344 scoped_ptr(scoped_ptr<U, V>&& other) |
| 345 : impl_(&other.impl_) { |
342 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); | 346 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); |
343 } | 347 } |
344 | 348 |
345 // Constructor. Move constructor for C++03 move emulation of this type. | 349 // Constructor. Move constructor for C++03 move emulation of this type. |
346 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { } | 350 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) {} |
347 | 351 |
348 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible | 352 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible |
349 // type and deleter. | 353 // type and deleter. |
350 // | 354 // |
351 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from | 355 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from |
352 // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated | 356 // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated |
353 // form has different requirements on for move-only Deleters. Since this | 357 // form has different requirements on for move-only Deleters. Since this |
354 // implementation does not support move-only Deleters, we do not need a | 358 // implementation does not support move-only Deleters, we do not need a |
355 // separate move assignment operator allowing us to avoid one use of SFINAE. | 359 // separate move assignment operator allowing us to avoid one use of SFINAE. |
356 // You only need to care about this if you modify the implementation of | 360 // You only need to care about this if you modify the implementation of |
357 // scoped_ptr. | 361 // scoped_ptr. |
358 template <typename U, typename V> | 362 template <typename U, typename V> |
359 scoped_ptr& operator=(scoped_ptr<U, V> rhs) { | 363 scoped_ptr& operator=(scoped_ptr<U, V>&& rhs) { |
360 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); | 364 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); |
361 impl_.TakeState(&rhs.impl_); | 365 impl_.TakeState(&rhs.impl_); |
362 return *this; | 366 return *this; |
363 } | 367 } |
364 | 368 |
| 369 // operator=. Allows assignment from a nullptr. Deletes the currently owned |
| 370 // object, if any. |
| 371 scoped_ptr& operator=(decltype(nullptr)) { |
| 372 reset(); |
| 373 return *this; |
| 374 } |
| 375 |
365 // Reset. Deletes the currently owned object, if any. | 376 // Reset. Deletes the currently owned object, if any. |
366 // Then takes ownership of a new object, if given. | 377 // Then takes ownership of a new object, if given. |
367 void reset(element_type* p = NULL) { impl_.reset(p); } | 378 void reset(element_type* p = nullptr) { impl_.reset(p); } |
368 | 379 |
369 // Accessors to get the owned object. | 380 // Accessors to get the owned object. |
370 // operator* and operator-> will assert() if there is no current object. | 381 // operator* and operator-> will assert() if there is no current object. |
371 element_type& operator*() const { | 382 element_type& operator*() const { |
372 assert(impl_.get() != NULL); | 383 assert(impl_.get() != nullptr); |
373 return *impl_.get(); | 384 return *impl_.get(); |
374 } | 385 } |
375 element_type* operator->() const { | 386 element_type* operator->() const { |
376 assert(impl_.get() != NULL); | 387 assert(impl_.get() != nullptr); |
377 return impl_.get(); | 388 return impl_.get(); |
378 } | 389 } |
379 element_type* get() const { return impl_.get(); } | 390 element_type* get() const { return impl_.get(); } |
380 | 391 |
381 // Access to the deleter. | 392 // Access to the deleter. |
382 deleter_type& get_deleter() { return impl_.get_deleter(); } | 393 deleter_type& get_deleter() { return impl_.get_deleter(); } |
383 const deleter_type& get_deleter() const { return impl_.get_deleter(); } | 394 const deleter_type& get_deleter() const { return impl_.get_deleter(); } |
384 | 395 |
385 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not | 396 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not |
386 // implicitly convertible to a real bool (which is dangerous). | 397 // implicitly convertible to a real bool (which is dangerous). |
387 // | 398 // |
388 // Note that this trick is only safe when the == and != operators | 399 // Note that this trick is only safe when the == and != operators |
389 // are declared explicitly, as otherwise "scoped_ptr1 == | 400 // are declared explicitly, as otherwise "scoped_ptr1 == |
390 // scoped_ptr2" will compile but do the wrong thing (i.e., convert | 401 // scoped_ptr2" will compile but do the wrong thing (i.e., convert |
391 // to Testable and then do the comparison). | 402 // to Testable and then do the comparison). |
392 private: | 403 private: |
393 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> | 404 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> |
394 scoped_ptr::*Testable; | 405 scoped_ptr::*Testable; |
395 | 406 |
396 public: | 407 public: |
397 operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; } | 408 operator Testable() const { |
| 409 return impl_.get() ? &scoped_ptr::impl_ : nullptr; |
| 410 } |
398 | 411 |
399 // Comparison operators. | 412 // Comparison operators. |
400 // These return whether two scoped_ptr refer to the same object, not just to | 413 // These return whether two scoped_ptr refer to the same object, not just to |
401 // two different but equal objects. | 414 // two different but equal objects. |
402 bool operator==(const element_type* p) const { return impl_.get() == p; } | 415 bool operator==(const element_type* p) const { return impl_.get() == p; } |
403 bool operator!=(const element_type* p) const { return impl_.get() != p; } | 416 bool operator!=(const element_type* p) const { return impl_.get() != p; } |
404 | 417 |
405 // Swap two scoped pointers. | 418 // Swap two scoped pointers. |
406 void swap(scoped_ptr& p2) { | 419 void swap(scoped_ptr& p2) { |
407 impl_.swap(p2.impl_); | 420 impl_.swap(p2.impl_); |
408 } | 421 } |
409 | 422 |
410 // Release a pointer. | 423 // Release a pointer. |
411 // The return value is the current pointer held by this object. | 424 // The return value is the current pointer held by this object. If this object |
412 // If this object holds a NULL pointer, the return value is NULL. | 425 // holds a nullptr, the return value is nullptr. After this operation, this |
413 // After this operation, this object will hold a NULL pointer, | 426 // object will hold a nullptr, and will not own the object any more. |
414 // and will not own the object any more. | |
415 element_type* release() WARN_UNUSED_RESULT { | 427 element_type* release() WARN_UNUSED_RESULT { |
416 return impl_.release(); | 428 return impl_.release(); |
417 } | 429 } |
418 | 430 |
419 // C++98 doesn't support functions templates with default parameters which | 431 // C++98 doesn't support functions templates with default parameters which |
420 // makes it hard to write a PassAs() that understands converting the deleter | 432 // makes it hard to write a PassAs() that understands converting the deleter |
421 // while preserving simple calling semantics. | 433 // while preserving simple calling semantics. |
422 // | 434 // |
423 // Until there is a use case for PassAs() with custom deleters, just ignore | 435 // Until there is a use case for PassAs() with custom deleters, just ignore |
424 // the custom deleter. | 436 // the custom deleter. |
(...skipping 20 matching lines...) Expand all Loading... |
445 | 457 |
446 template <class T, class D> | 458 template <class T, class D> |
447 class scoped_ptr<T[], D> { | 459 class scoped_ptr<T[], D> { |
448 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) | 460 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) |
449 | 461 |
450 public: | 462 public: |
451 // The element and deleter types. | 463 // The element and deleter types. |
452 typedef T element_type; | 464 typedef T element_type; |
453 typedef D deleter_type; | 465 typedef D deleter_type; |
454 | 466 |
455 // Constructor. Defaults to initializing with NULL. | 467 // Constructor. Defaults to initializing with nullptr. |
456 scoped_ptr() : impl_(NULL) { } | 468 scoped_ptr() : impl_(nullptr) {} |
457 | 469 |
458 // Constructor. Stores the given array. Note that the argument's type | 470 // Constructor. Stores the given array. Note that the argument's type |
459 // must exactly match T*. In particular: | 471 // must exactly match T*. In particular: |
460 // - it cannot be a pointer to a type derived from T, because it is | 472 // - it cannot be a pointer to a type derived from T, because it is |
461 // inherently unsafe in the general case to access an array through a | 473 // inherently unsafe in the general case to access an array through a |
462 // pointer whose dynamic type does not match its static type (eg., if | 474 // pointer whose dynamic type does not match its static type (eg., if |
463 // T and the derived types had different sizes access would be | 475 // T and the derived types had different sizes access would be |
464 // incorrectly calculated). Deletion is also always undefined | 476 // incorrectly calculated). Deletion is also always undefined |
465 // (C++98 [expr.delete]p3). If you're doing this, fix your code. | 477 // (C++98 [expr.delete]p3). If you're doing this, fix your code. |
466 // - it cannot be NULL, because NULL is an integral expression, not a | |
467 // pointer to T. Use the no-argument version instead of explicitly | |
468 // passing NULL. | |
469 // - it cannot be const-qualified differently from T per unique_ptr spec | 478 // - it cannot be const-qualified differently from T per unique_ptr spec |
470 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting | 479 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting |
471 // to work around this may use implicit_cast<const T*>(). | 480 // to work around this may use implicit_cast<const T*>(). |
472 // However, because of the first bullet in this comment, users MUST | 481 // However, because of the first bullet in this comment, users MUST |
473 // NOT use implicit_cast<Base*>() to upcast the static type of the array. | 482 // NOT use implicit_cast<Base*>() to upcast the static type of the array. |
474 explicit scoped_ptr(element_type* array) : impl_(array) { } | 483 explicit scoped_ptr(element_type* array) : impl_(array) {} |
| 484 |
| 485 // Constructor. Allows construction from a nullptr. |
| 486 scoped_ptr(decltype(nullptr)) : impl_(nullptr) {} |
| 487 |
| 488 // Constructor. Allows construction from a scoped_ptr rvalue. |
| 489 scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {} |
475 | 490 |
476 // Constructor. Move constructor for C++03 move emulation of this type. | 491 // Constructor. Move constructor for C++03 move emulation of this type. |
477 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { } | 492 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) {} |
| 493 |
| 494 // operator=. Allows assignment from a scoped_ptr rvalue. |
| 495 scoped_ptr& operator=(scoped_ptr&& rhs) { |
| 496 impl_.TakeState(&rhs.impl_); |
| 497 return *this; |
| 498 } |
478 | 499 |
479 // operator=. Move operator= for C++03 move emulation of this type. | 500 // operator=. Move operator= for C++03 move emulation of this type. |
480 scoped_ptr& operator=(RValue rhs) { | 501 scoped_ptr& operator=(RValue rhs) { |
481 impl_.TakeState(&rhs.object->impl_); | 502 impl_.TakeState(&rhs.object->impl_); |
482 return *this; | 503 return *this; |
483 } | 504 } |
484 | 505 |
| 506 // operator=. Allows assignment from a nullptr. Deletes the currently owned |
| 507 // array, if any. |
| 508 scoped_ptr& operator=(decltype(nullptr)) { |
| 509 reset(); |
| 510 return *this; |
| 511 } |
| 512 |
485 // Reset. Deletes the currently owned array, if any. | 513 // Reset. Deletes the currently owned array, if any. |
486 // Then takes ownership of a new object, if given. | 514 // Then takes ownership of a new object, if given. |
487 void reset(element_type* array = NULL) { impl_.reset(array); } | 515 void reset(element_type* array = nullptr) { impl_.reset(array); } |
488 | 516 |
489 // Accessors to get the owned array. | 517 // Accessors to get the owned array. |
490 element_type& operator[](size_t i) const { | 518 element_type& operator[](size_t i) const { |
491 assert(impl_.get() != NULL); | 519 assert(impl_.get() != nullptr); |
492 return impl_.get()[i]; | 520 return impl_.get()[i]; |
493 } | 521 } |
494 element_type* get() const { return impl_.get(); } | 522 element_type* get() const { return impl_.get(); } |
495 | 523 |
496 // Access to the deleter. | 524 // Access to the deleter. |
497 deleter_type& get_deleter() { return impl_.get_deleter(); } | 525 deleter_type& get_deleter() { return impl_.get_deleter(); } |
498 const deleter_type& get_deleter() const { return impl_.get_deleter(); } | 526 const deleter_type& get_deleter() const { return impl_.get_deleter(); } |
499 | 527 |
500 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not | 528 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not |
501 // implicitly convertible to a real bool (which is dangerous). | 529 // implicitly convertible to a real bool (which is dangerous). |
502 private: | 530 private: |
503 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> | 531 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> |
504 scoped_ptr::*Testable; | 532 scoped_ptr::*Testable; |
505 | 533 |
506 public: | 534 public: |
507 operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; } | 535 operator Testable() const { |
| 536 return impl_.get() ? &scoped_ptr::impl_ : nullptr; |
| 537 } |
508 | 538 |
509 // Comparison operators. | 539 // Comparison operators. |
510 // These return whether two scoped_ptr refer to the same object, not just to | 540 // These return whether two scoped_ptr refer to the same object, not just to |
511 // two different but equal objects. | 541 // two different but equal objects. |
512 bool operator==(element_type* array) const { return impl_.get() == array; } | 542 bool operator==(element_type* array) const { return impl_.get() == array; } |
513 bool operator!=(element_type* array) const { return impl_.get() != array; } | 543 bool operator!=(element_type* array) const { return impl_.get() != array; } |
514 | 544 |
515 // Swap two scoped pointers. | 545 // Swap two scoped pointers. |
516 void swap(scoped_ptr& p2) { | 546 void swap(scoped_ptr& p2) { |
517 impl_.swap(p2.impl_); | 547 impl_.swap(p2.impl_); |
518 } | 548 } |
519 | 549 |
520 // Release a pointer. | 550 // Release a pointer. |
521 // The return value is the current pointer held by this object. | 551 // The return value is the current pointer held by this object. If this object |
522 // If this object holds a NULL pointer, the return value is NULL. | 552 // holds a nullptr, the return value is nullptr. After this operation, this |
523 // After this operation, this object will hold a NULL pointer, | 553 // object will hold a nullptr, and will not own the object any more. |
524 // and will not own the object any more. | |
525 element_type* release() WARN_UNUSED_RESULT { | 554 element_type* release() WARN_UNUSED_RESULT { |
526 return impl_.release(); | 555 return impl_.release(); |
527 } | 556 } |
528 | 557 |
529 private: | 558 private: |
530 // Force element_type to be a complete type. | 559 // Force element_type to be a complete type. |
531 enum { type_must_be_complete = sizeof(element_type) }; | 560 enum { type_must_be_complete = sizeof(element_type) }; |
532 | 561 |
533 // Actually hold the data. | 562 // Actually hold the data. |
534 base::internal::scoped_ptr_impl<element_type, deleter_type> impl_; | 563 base::internal::scoped_ptr_impl<element_type, deleter_type> impl_; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 | 601 |
573 // A function to convert T* into scoped_ptr<T> | 602 // A function to convert T* into scoped_ptr<T> |
574 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation | 603 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation |
575 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) | 604 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) |
576 template <typename T> | 605 template <typename T> |
577 scoped_ptr<T> make_scoped_ptr(T* ptr) { | 606 scoped_ptr<T> make_scoped_ptr(T* ptr) { |
578 return scoped_ptr<T>(ptr); | 607 return scoped_ptr<T>(ptr); |
579 } | 608 } |
580 | 609 |
581 #endif // BASE_MEMORY_SCOPED_PTR_H_ | 610 #endif // BASE_MEMORY_SCOPED_PTR_H_ |
OLD | NEW |