OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 the | 5 // Scopers help you manage ownership of a pointer, helping you easily manage the |
6 // a pointer within a scope, and automatically destroying the pointer at the | 6 // a pointer within a scope, and automatically destroying the pointer at the |
7 // end of a scope. There are two main classes you will use, which coorespond | 7 // end of a scope. There are two main classes you will use, which coorespond |
8 // to the operators new/delete and new[]/delete[]. | 8 // to the operators new/delete and new[]/delete[]. |
9 // | 9 // |
10 // Example usage (scoped_ptr): | 10 // Example usage (scoped_ptr): |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 template <class C> | 249 template <class C> |
250 bool operator==(C* p1, const scoped_array<C>& p2) { | 250 bool operator==(C* p1, const scoped_array<C>& p2) { |
251 return p1 == p2.get(); | 251 return p1 == p2.get(); |
252 } | 252 } |
253 | 253 |
254 template <class C> | 254 template <class C> |
255 bool operator!=(C* p1, const scoped_array<C>& p2) { | 255 bool operator!=(C* p1, const scoped_array<C>& p2) { |
256 return p1 != p2.get(); | 256 return p1 != p2.get(); |
257 } | 257 } |
258 | 258 |
259 // This class wraps the c library function free() in a class that can be | 259 // This template function will adapt any function that takes a void* and |
260 // passed as a template argument to scoped_ptr_malloc below. | 260 // returns void for use with scoped_ptr_malloc below. |
261 class ScopedPtrMallocFree { | 261 template<void (*FreeFn)(void*), class C> |
262 public: | 262 void FreeFnAdapter(C* x) { |
263 inline void operator()(void* x) const { | 263 FreeFn(x); |
264 free(x); | 264 } |
265 } | 265 template<int (*FreeFn)(void*), class C> |
266 }; | 266 void FreeFnAdapterIgnoreReturn(C* x) { |
| 267 FreeFn(x); |
| 268 } |
| 269 template<class C, int (*FreeFn)(C*)> |
| 270 void FreeFnIgnoreReturn(C* x) { |
| 271 FreeFn(x); |
| 272 } |
267 | 273 |
268 // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a | 274 // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a |
269 // second template argument, the functor used to free the object. | 275 // second template argument, the function used to free the object. |
270 | 276 |
271 template<class C, class FreeProc = ScopedPtrMallocFree> | 277 template<class C, void (*FreeProc)(C*) = FreeFnAdapter<free> > |
272 class scoped_ptr_malloc { | 278 class scoped_ptr_malloc { |
273 public: | 279 public: |
274 | 280 |
275 // The element type | 281 // The element type |
276 typedef C element_type; | 282 typedef C element_type; |
277 | 283 |
278 // Constructor. Defaults to intializing with NULL. | 284 // Constructor. Defaults to intializing with NULL. |
279 // There is no way to create an uninitialized scoped_ptr. | 285 // There is no way to create an uninitialized scoped_ptr. |
280 // The input parameter must be allocated with an allocator that matches the | 286 // The input parameter must be allocated with an allocator that matches the |
281 // Free functor. For the default Free functor, this is malloc, calloc, or | 287 // Free functor. For the default Free functor, this is malloc, calloc, or |
282 // realloc. | 288 // realloc. |
283 explicit scoped_ptr_malloc(C* p = NULL): ptr_(p) {} | 289 explicit scoped_ptr_malloc(C* p = NULL): ptr_(p) {} |
284 | 290 |
285 // Destructor. If there is a C object, call the Free functor. | 291 // Destructor. If there is a C object, call the Free functor. |
286 ~scoped_ptr_malloc() { | 292 ~scoped_ptr_malloc() { |
287 free_(ptr_); | 293 FreePointer(ptr_); |
288 } | 294 } |
289 | 295 |
290 // Reset. Calls the Free functor on the current owned object, if any. | 296 // Reset. Calls the Free functor on the current owned object, if any. |
291 // Then takes ownership of a new object, if given. | 297 // Then takes ownership of a new object, if given. |
292 // this->reset(this->get()) works. | 298 // this->reset(this->get()) works. |
293 void reset(C* p = NULL) { | 299 void reset(C* p = NULL) { |
294 if (ptr_ != p) { | 300 if (ptr_ != p) { |
295 free_(ptr_); | 301 FreePointer(ptr_); |
296 ptr_ = p; | 302 ptr_ = p; |
297 } | 303 } |
298 } | 304 } |
299 | 305 |
300 // Get the current object. | 306 // Get the current object. |
301 // operator* and operator-> will cause an assert() failure if there is | 307 // operator* and operator-> will cause an assert() failure if there is |
302 // no current object. | 308 // no current object. |
303 C& operator*() const { | 309 C& operator*() const { |
304 assert(ptr_ != NULL); | 310 assert(ptr_ != NULL); |
305 return *ptr_; | 311 return *ptr_; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 // If this object holds a NULL pointer, the return value is NULL. | 345 // If this object holds a NULL pointer, the return value is NULL. |
340 // After this operation, this object will hold a NULL pointer, | 346 // After this operation, this object will hold a NULL pointer, |
341 // and will not own the object any more. | 347 // and will not own the object any more. |
342 C* release() WARN_UNUSED_RESULT { | 348 C* release() WARN_UNUSED_RESULT { |
343 C* tmp = ptr_; | 349 C* tmp = ptr_; |
344 ptr_ = NULL; | 350 ptr_ = NULL; |
345 return tmp; | 351 return tmp; |
346 } | 352 } |
347 | 353 |
348 private: | 354 private: |
| 355 void FreePointer(C* x) { |
| 356 if (x) |
| 357 FreeProc(x); |
| 358 } |
349 C* ptr_; | 359 C* ptr_; |
350 | 360 |
351 // no reason to use these: each scoped_ptr_malloc should have its own object | 361 // no reason to use these: each scoped_ptr_malloc should have its own object |
352 template <class C2, class GP> | 362 template <class C2, void GP(C*)> |
353 bool operator==(scoped_ptr_malloc<C2, GP> const& p) const; | 363 bool operator==(scoped_ptr_malloc<C2, GP> const& p) const; |
354 template <class C2, class GP> | 364 template <class C2, void GP(C*)> |
355 bool operator!=(scoped_ptr_malloc<C2, GP> const& p) const; | 365 bool operator!=(scoped_ptr_malloc<C2, GP> const& p) const; |
356 | 366 |
357 static FreeProc const free_; | |
358 | |
359 // Disallow evil constructors | 367 // Disallow evil constructors |
360 scoped_ptr_malloc(const scoped_ptr_malloc&); | 368 scoped_ptr_malloc(const scoped_ptr_malloc&); |
361 void operator=(const scoped_ptr_malloc&); | 369 void operator=(const scoped_ptr_malloc&); |
362 }; | 370 }; |
363 | 371 |
364 template<class C, class FP> | 372 template<class C, void FP(C*)> inline |
365 FP const scoped_ptr_malloc<C, FP>::free_ = FP(); | |
366 | |
367 template<class C, class FP> inline | |
368 void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) { | 373 void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) { |
369 a.swap(b); | 374 a.swap(b); |
370 } | 375 } |
371 | 376 |
372 template<class C, class FP> inline | 377 template<class C, void FP(C*)> inline |
373 bool operator==(C* p, const scoped_ptr_malloc<C, FP>& b) { | 378 bool operator==(C* p, const scoped_ptr_malloc<C, FP>& b) { |
374 return p == b.get(); | 379 return p == b.get(); |
375 } | 380 } |
376 | 381 |
377 template<class C, class FP> inline | 382 template<class C, void FP(C*)> inline |
378 bool operator!=(C* p, const scoped_ptr_malloc<C, FP>& b) { | 383 bool operator!=(C* p, const scoped_ptr_malloc<C, FP>& b) { |
379 return p != b.get(); | 384 return p != b.get(); |
380 } | 385 } |
381 | 386 |
382 #endif // BASE_SCOPED_PTR_H_ | 387 #endif // BASE_SCOPED_PTR_H_ |
OLD | NEW |