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 0 : explicit SkTScopedPtr(T* o = NULL) : fObj(o) {}
28 0 : ~SkTScopedPtr() {
29 : enum { kTypeMustBeComplete = sizeof(T) };
30 0 : delete fObj;
31 0 : }
32 :
33 : /** Delete the current object, if any. Then take ownership of the
34 : passed object.
35 : */
36 0 : void reset(T* o = NULL) {
37 0 : if (o != fObj) {
38 : enum { kTypeMustBeComplete = sizeof(T) };
39 0 : delete fObj;
40 0 : fObj = o;
41 : }
42 0 : }
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 0 : T* release() {
48 0 : T* retVal = fObj;
49 0 : fObj = NULL;
50 0 : return retVal;
51 : }
52 :
53 : T& operator*() const {
54 : SkASSERT(fObj != NULL);
55 : return *fObj;
56 : }
57 0 : T* operator->() const {
58 0 : SkASSERT(fObj != NULL);
59 0 : return fObj;
60 : }
61 0 : 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
|