Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #ifndef SkTScopedPtr_DEFINED
     11 #define SkTScopedPtr_DEFINED
     12 
     13 #include "SkTypes.h"
     14 
     15 /** \class SkTScopedPtr
     16   A SkTScopedPtr<T> is like a T*, except that the destructor of SkTScopedPtr<T>
     17   automatically deletes the pointer it holds (if any).  That is, SkTScopedPtr<T>
     18   owns the T object that it points to.  Like a T*, a SkTScopedPtr<T> may hold
     19   either NULL or a pointer to a T object.  Also like T*, SkTScopedPtr<T> is
     20   thread-compatible, and once you dereference it, you get the threadsafety
     21   guarantees of T.
     22 
     23   The size of a SkTScopedPtr is small: sizeof(SkTScopedPtr<T>) == sizeof(T*)
     24 */
     25 template <typename T> class SkTScopedPtr : SkNoncopyable {
     26 public:
     27     explicit SkTScopedPtr(T* o = NULL) : fObj(o) {}
     28     ~SkTScopedPtr() {
     29         enum { kTypeMustBeComplete = sizeof(T) };
     30         delete fObj;
     31     }
     32 
     33     /** Delete the current object, if any.  Then take ownership of the
     34         passed object.
     35      */
     36     void reset(T* o = NULL) {
     37         if (o != fObj) {
     38             enum { kTypeMustBeComplete = sizeof(T) };
     39             delete fObj;
     40             fObj = o;
     41         }
     42     }
     43 
     44     /** Without deleting the current object, return it and forget about it.
     45         Similar to calling get() and reset(), but the object is not deleted.
     46      */
     47     T* release() {
     48         T* retVal = fObj;
     49         fObj = NULL;
     50         return retVal;
     51     }
     52 
     53     T& operator*() const {
     54         SkASSERT(fObj != NULL);
     55         return *fObj;
     56     }
     57     T* operator->() const  {
     58         SkASSERT(fObj != NULL);
     59         return fObj;
     60     }
     61     T* get() const { return fObj; }
     62 
     63     bool operator==(T* o) const { return fObj == o; }
     64     bool operator!=(T* o) const { return fObj != o; }
     65 
     66 private:
     67     T* fObj;
     68 
     69     // Forbid comparison of SkTScopedPtr types.  If T2 != T, it doesn't make
     70     // sense, and if T2 == T, it still doesn't make sense because the same
     71     // object can't be owned by two different scoped_ptrs.
     72     template <class T2> bool operator==(SkTScopedPtr<T2> const& o2) const;
     73     template <class T2> bool operator!=(SkTScopedPtr<T2> const& o2) const;
     74 };
     75 
     76 #endif
     77