Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright (C) 2011 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef SkTScopedPtr_DEFINED
     18 #define SkTScopedPtr_DEFINED
     19 
     20 #include "SkTypes.h"
     21 
     22 /** \class SkTScopedPtr
     23   A SkTScopedPtr<T> is like a T*, except that the destructor of SkTScopedPtr<T>
     24   automatically deletes the pointer it holds (if any).  That is, SkTScopedPtr<T>
     25   owns the T object that it points to.  Like a T*, a SkTScopedPtr<T> may hold
     26   either NULL or a pointer to a T object.  Also like T*, SkTScopedPtr<T> is
     27   thread-compatible, and once you dereference it, you get the threadsafety
     28   guarantees of T.
     29 
     30   The size of a SkTScopedPtr is small: sizeof(SkTScopedPtr<T>) == sizeof(T*)
     31 */
     32 template <typename T> class SkTScopedPtr : SkNoncopyable {
     33 public:
     34     explicit SkTScopedPtr(T* o = NULL) : fObj(o) {}
     35     ~SkTScopedPtr() {
     36         enum { kTypeMustBeComplete = sizeof(T) };
     37         delete fObj;
     38     }
     39 
     40     /** Delete the current object, if any.  Then take ownership of the
     41         passed object.
     42      */
     43     void reset(T* o = NULL) {
     44         if (o != fObj) {
     45             enum { kTypeMustBeComplete = sizeof(T) };
     46             delete fObj;
     47             fObj = o;
     48         }
     49     }
     50 
     51     /** Without deleting the current object, return it and forget about it.
     52         Similar to calling get() and reset(), but the object is not deleted.
     53      */
     54     T* release() {
     55         T* retVal = fObj;
     56         fObj = NULL;
     57         return retVal;
     58     }
     59 
     60     T& operator*() const {
     61         SkASSERT(fObj != NULL);
     62         return *fObj;
     63     }
     64     T* operator->() const  {
     65         SkASSERT(fObj != NULL);
     66         return fObj;
     67     }
     68     T* get() const { return fObj; }
     69 
     70     bool operator==(T* o) const { return fObj == o; }
     71     bool operator!=(T* o) const { return fObj != o; }
     72 
     73 private:
     74     T* fObj;
     75 
     76     // Forbid comparison of SkTScopedPtr types.  If T2 != T, it doesn't make
     77     // sense, and if T2 == T, it still doesn't make sense because the same
     78     // object can't be owned by two different scoped_ptrs.
     79     template <class T2> bool operator==(SkTScopedPtr<T2> const& o2) const;
     80     template <class T2> bool operator!=(SkTScopedPtr<T2> const& o2) const;
     81 };
     82 
     83 #endif
     84