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 nullptr. | 61 // PassThru(ptr2.Pass()); // ptr2 is correspondingly NULL. |
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 != nullptr) { | 217 if (data_.ptr != NULL) { |
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 != nullptr && p == data_.ptr) | 226 if (p != NULL && 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 nullptr while | 239 // During the transition period, set the stored pointer to NULL 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 = nullptr; | 244 data_.ptr = NULL; |
245 if (old != nullptr) | 245 if (old != NULL) |
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 = nullptr; | 266 data_.ptr = NULL; |
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 nullptr or a pointer to a T | 296 // Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object. |
297 // object. Also like T*, scoped_ptr<T> is thread-compatible, and once you | 297 // 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 nullptr. | 321 // Constructor. Defaults to initializing with NULL. |
322 scoped_ptr() : impl_(nullptr) {} | 322 scoped_ptr() : impl_(NULL) { } |
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) {} | |
332 | 329 |
333 // Constructor. Allows construction from a scoped_ptr rvalue for a | 330 // Constructor. Allows construction from a scoped_ptr rvalue for a |
334 // convertible type and deleter. | 331 // convertible type and deleter. |
335 // | 332 // |
336 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct | 333 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct |
337 // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor | 334 // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor |
338 // has different post-conditions if D is a reference type. Since this | 335 // has different post-conditions if D is a reference type. Since this |
339 // implementation does not support deleters with reference type, | 336 // implementation does not support deleters with reference type, |
340 // we do not need a separate move constructor allowing us to avoid one | 337 // we do not need a separate move constructor allowing us to avoid one |
341 // use of SFINAE. You only need to care about this if you modify the | 338 // use of SFINAE. You only need to care about this if you modify the |
342 // implementation of scoped_ptr. | 339 // implementation of scoped_ptr. |
343 template <typename U, typename V> | 340 template <typename U, typename V> |
344 scoped_ptr(scoped_ptr<U, V>&& other) | 341 scoped_ptr(scoped_ptr<U, V> other) : impl_(&other.impl_) { |
345 : impl_(&other.impl_) { | |
346 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); | 342 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); |
347 } | 343 } |
348 | 344 |
349 // Constructor. Move constructor for C++03 move emulation of this type. | 345 // Constructor. Move constructor for C++03 move emulation of this type. |
350 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) {} | 346 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { } |
351 | 347 |
352 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible | 348 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible |
353 // type and deleter. | 349 // type and deleter. |
354 // | 350 // |
355 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from | 351 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from |
356 // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated | 352 // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated |
357 // form has different requirements on for move-only Deleters. Since this | 353 // form has different requirements on for move-only Deleters. Since this |
358 // implementation does not support move-only Deleters, we do not need a | 354 // implementation does not support move-only Deleters, we do not need a |
359 // separate move assignment operator allowing us to avoid one use of SFINAE. | 355 // separate move assignment operator allowing us to avoid one use of SFINAE. |
360 // You only need to care about this if you modify the implementation of | 356 // You only need to care about this if you modify the implementation of |
361 // scoped_ptr. | 357 // scoped_ptr. |
362 template <typename U, typename V> | 358 template <typename U, typename V> |
363 scoped_ptr& operator=(scoped_ptr<U, V>&& rhs) { | 359 scoped_ptr& operator=(scoped_ptr<U, V> rhs) { |
364 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); | 360 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); |
365 impl_.TakeState(&rhs.impl_); | 361 impl_.TakeState(&rhs.impl_); |
366 return *this; | 362 return *this; |
367 } | 363 } |
368 | 364 |
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 | |
376 // Reset. Deletes the currently owned object, if any. | 365 // Reset. Deletes the currently owned object, if any. |
377 // Then takes ownership of a new object, if given. | 366 // Then takes ownership of a new object, if given. |
378 void reset(element_type* p = nullptr) { impl_.reset(p); } | 367 void reset(element_type* p = NULL) { impl_.reset(p); } |
379 | 368 |
380 // Accessors to get the owned object. | 369 // Accessors to get the owned object. |
381 // operator* and operator-> will assert() if there is no current object. | 370 // operator* and operator-> will assert() if there is no current object. |
382 element_type& operator*() const { | 371 element_type& operator*() const { |
383 assert(impl_.get() != nullptr); | 372 assert(impl_.get() != NULL); |
384 return *impl_.get(); | 373 return *impl_.get(); |
385 } | 374 } |
386 element_type* operator->() const { | 375 element_type* operator->() const { |
387 assert(impl_.get() != nullptr); | 376 assert(impl_.get() != NULL); |
388 return impl_.get(); | 377 return impl_.get(); |
389 } | 378 } |
390 element_type* get() const { return impl_.get(); } | 379 element_type* get() const { return impl_.get(); } |
391 | 380 |
392 // Access to the deleter. | 381 // Access to the deleter. |
393 deleter_type& get_deleter() { return impl_.get_deleter(); } | 382 deleter_type& get_deleter() { return impl_.get_deleter(); } |
394 const deleter_type& get_deleter() const { return impl_.get_deleter(); } | 383 const deleter_type& get_deleter() const { return impl_.get_deleter(); } |
395 | 384 |
396 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not | 385 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not |
397 // implicitly convertible to a real bool (which is dangerous). | 386 // implicitly convertible to a real bool (which is dangerous). |
398 // | 387 // |
399 // Note that this trick is only safe when the == and != operators | 388 // Note that this trick is only safe when the == and != operators |
400 // are declared explicitly, as otherwise "scoped_ptr1 == | 389 // are declared explicitly, as otherwise "scoped_ptr1 == |
401 // scoped_ptr2" will compile but do the wrong thing (i.e., convert | 390 // scoped_ptr2" will compile but do the wrong thing (i.e., convert |
402 // to Testable and then do the comparison). | 391 // to Testable and then do the comparison). |
403 private: | 392 private: |
404 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> | 393 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> |
405 scoped_ptr::*Testable; | 394 scoped_ptr::*Testable; |
406 | 395 |
407 public: | 396 public: |
408 operator Testable() const { | 397 operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; } |
409 return impl_.get() ? &scoped_ptr::impl_ : nullptr; | |
410 } | |
411 | 398 |
412 // Comparison operators. | 399 // Comparison operators. |
413 // These return whether two scoped_ptr refer to the same object, not just to | 400 // These return whether two scoped_ptr refer to the same object, not just to |
414 // two different but equal objects. | 401 // two different but equal objects. |
415 bool operator==(const element_type* p) const { return impl_.get() == p; } | 402 bool operator==(const element_type* p) const { return impl_.get() == p; } |
416 bool operator!=(const element_type* p) const { return impl_.get() != p; } | 403 bool operator!=(const element_type* p) const { return impl_.get() != p; } |
417 | 404 |
418 // Swap two scoped pointers. | 405 // Swap two scoped pointers. |
419 void swap(scoped_ptr& p2) { | 406 void swap(scoped_ptr& p2) { |
420 impl_.swap(p2.impl_); | 407 impl_.swap(p2.impl_); |
421 } | 408 } |
422 | 409 |
423 // Release a pointer. | 410 // Release a pointer. |
424 // The return value is the current pointer held by this object. If this object | 411 // The return value is the current pointer held by this object. |
425 // holds a nullptr, the return value is nullptr. After this operation, this | 412 // If this object holds a NULL pointer, the return value is NULL. |
426 // object will hold a nullptr, and will not own the object any more. | 413 // After this operation, this object will hold a NULL pointer, |
| 414 // and will not own the object any more. |
427 element_type* release() WARN_UNUSED_RESULT { | 415 element_type* release() WARN_UNUSED_RESULT { |
428 return impl_.release(); | 416 return impl_.release(); |
429 } | 417 } |
430 | 418 |
431 // C++98 doesn't support functions templates with default parameters which | 419 // C++98 doesn't support functions templates with default parameters which |
432 // makes it hard to write a PassAs() that understands converting the deleter | 420 // makes it hard to write a PassAs() that understands converting the deleter |
433 // while preserving simple calling semantics. | 421 // while preserving simple calling semantics. |
434 // | 422 // |
435 // Until there is a use case for PassAs() with custom deleters, just ignore | 423 // Until there is a use case for PassAs() with custom deleters, just ignore |
436 // the custom deleter. | 424 // the custom deleter. |
(...skipping 20 matching lines...) Expand all Loading... |
457 | 445 |
458 template <class T, class D> | 446 template <class T, class D> |
459 class scoped_ptr<T[], D> { | 447 class scoped_ptr<T[], D> { |
460 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) | 448 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) |
461 | 449 |
462 public: | 450 public: |
463 // The element and deleter types. | 451 // The element and deleter types. |
464 typedef T element_type; | 452 typedef T element_type; |
465 typedef D deleter_type; | 453 typedef D deleter_type; |
466 | 454 |
467 // Constructor. Defaults to initializing with nullptr. | 455 // Constructor. Defaults to initializing with NULL. |
468 scoped_ptr() : impl_(nullptr) {} | 456 scoped_ptr() : impl_(NULL) { } |
469 | 457 |
470 // Constructor. Stores the given array. Note that the argument's type | 458 // Constructor. Stores the given array. Note that the argument's type |
471 // must exactly match T*. In particular: | 459 // must exactly match T*. In particular: |
472 // - it cannot be a pointer to a type derived from T, because it is | 460 // - it cannot be a pointer to a type derived from T, because it is |
473 // inherently unsafe in the general case to access an array through a | 461 // inherently unsafe in the general case to access an array through a |
474 // pointer whose dynamic type does not match its static type (eg., if | 462 // pointer whose dynamic type does not match its static type (eg., if |
475 // T and the derived types had different sizes access would be | 463 // T and the derived types had different sizes access would be |
476 // incorrectly calculated). Deletion is also always undefined | 464 // incorrectly calculated). Deletion is also always undefined |
477 // (C++98 [expr.delete]p3). If you're doing this, fix your code. | 465 // (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. |
478 // - it cannot be const-qualified differently from T per unique_ptr spec | 469 // - it cannot be const-qualified differently from T per unique_ptr spec |
479 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting | 470 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting |
480 // to work around this may use implicit_cast<const T*>(). | 471 // to work around this may use implicit_cast<const T*>(). |
481 // However, because of the first bullet in this comment, users MUST | 472 // However, because of the first bullet in this comment, users MUST |
482 // NOT use implicit_cast<Base*>() to upcast the static type of the array. | 473 // NOT use implicit_cast<Base*>() to upcast the static type of the array. |
483 explicit scoped_ptr(element_type* array) : impl_(array) {} | 474 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_) {} | |
490 | 475 |
491 // Constructor. Move constructor for C++03 move emulation of this type. | 476 // Constructor. Move constructor for C++03 move emulation of this type. |
492 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) {} | 477 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 } | |
499 | 478 |
500 // operator=. Move operator= for C++03 move emulation of this type. | 479 // operator=. Move operator= for C++03 move emulation of this type. |
501 scoped_ptr& operator=(RValue rhs) { | 480 scoped_ptr& operator=(RValue rhs) { |
502 impl_.TakeState(&rhs.object->impl_); | 481 impl_.TakeState(&rhs.object->impl_); |
503 return *this; | 482 return *this; |
504 } | 483 } |
505 | 484 |
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 | |
513 // Reset. Deletes the currently owned array, if any. | 485 // Reset. Deletes the currently owned array, if any. |
514 // Then takes ownership of a new object, if given. | 486 // Then takes ownership of a new object, if given. |
515 void reset(element_type* array = nullptr) { impl_.reset(array); } | 487 void reset(element_type* array = NULL) { impl_.reset(array); } |
516 | 488 |
517 // Accessors to get the owned array. | 489 // Accessors to get the owned array. |
518 element_type& operator[](size_t i) const { | 490 element_type& operator[](size_t i) const { |
519 assert(impl_.get() != nullptr); | 491 assert(impl_.get() != NULL); |
520 return impl_.get()[i]; | 492 return impl_.get()[i]; |
521 } | 493 } |
522 element_type* get() const { return impl_.get(); } | 494 element_type* get() const { return impl_.get(); } |
523 | 495 |
524 // Access to the deleter. | 496 // Access to the deleter. |
525 deleter_type& get_deleter() { return impl_.get_deleter(); } | 497 deleter_type& get_deleter() { return impl_.get_deleter(); } |
526 const deleter_type& get_deleter() const { return impl_.get_deleter(); } | 498 const deleter_type& get_deleter() const { return impl_.get_deleter(); } |
527 | 499 |
528 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not | 500 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not |
529 // implicitly convertible to a real bool (which is dangerous). | 501 // implicitly convertible to a real bool (which is dangerous). |
530 private: | 502 private: |
531 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> | 503 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> |
532 scoped_ptr::*Testable; | 504 scoped_ptr::*Testable; |
533 | 505 |
534 public: | 506 public: |
535 operator Testable() const { | 507 operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; } |
536 return impl_.get() ? &scoped_ptr::impl_ : nullptr; | |
537 } | |
538 | 508 |
539 // Comparison operators. | 509 // Comparison operators. |
540 // These return whether two scoped_ptr refer to the same object, not just to | 510 // These return whether two scoped_ptr refer to the same object, not just to |
541 // two different but equal objects. | 511 // two different but equal objects. |
542 bool operator==(element_type* array) const { return impl_.get() == array; } | 512 bool operator==(element_type* array) const { return impl_.get() == array; } |
543 bool operator!=(element_type* array) const { return impl_.get() != array; } | 513 bool operator!=(element_type* array) const { return impl_.get() != array; } |
544 | 514 |
545 // Swap two scoped pointers. | 515 // Swap two scoped pointers. |
546 void swap(scoped_ptr& p2) { | 516 void swap(scoped_ptr& p2) { |
547 impl_.swap(p2.impl_); | 517 impl_.swap(p2.impl_); |
548 } | 518 } |
549 | 519 |
550 // Release a pointer. | 520 // Release a pointer. |
551 // The return value is the current pointer held by this object. If this object | 521 // The return value is the current pointer held by this object. |
552 // holds a nullptr, the return value is nullptr. After this operation, this | 522 // If this object holds a NULL pointer, the return value is NULL. |
553 // object will hold a nullptr, and will not own the object any more. | 523 // After this operation, this object will hold a NULL pointer, |
| 524 // and will not own the object any more. |
554 element_type* release() WARN_UNUSED_RESULT { | 525 element_type* release() WARN_UNUSED_RESULT { |
555 return impl_.release(); | 526 return impl_.release(); |
556 } | 527 } |
557 | 528 |
558 private: | 529 private: |
559 // Force element_type to be a complete type. | 530 // Force element_type to be a complete type. |
560 enum { type_must_be_complete = sizeof(element_type) }; | 531 enum { type_must_be_complete = sizeof(element_type) }; |
561 | 532 |
562 // Actually hold the data. | 533 // Actually hold the data. |
563 base::internal::scoped_ptr_impl<element_type, deleter_type> impl_; | 534 base::internal::scoped_ptr_impl<element_type, deleter_type> impl_; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 | 572 |
602 // A function to convert T* into scoped_ptr<T> | 573 // A function to convert T* into scoped_ptr<T> |
603 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation | 574 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation |
604 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) | 575 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) |
605 template <typename T> | 576 template <typename T> |
606 scoped_ptr<T> make_scoped_ptr(T* ptr) { | 577 scoped_ptr<T> make_scoped_ptr(T* ptr) { |
607 return scoped_ptr<T>(ptr); | 578 return scoped_ptr<T>(ptr); |
608 } | 579 } |
609 | 580 |
610 #endif // BASE_MEMORY_SCOPED_PTR_H_ | 581 #endif // BASE_MEMORY_SCOPED_PTR_H_ |
OLD | NEW |