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 #ifndef SkTScopedComPtr_DEFINED
10 #define SkTScopedComPtr_DEFINED
11 
12 #include "SkTypes.h"
13 #include "SkTemplates.h"
14 
15 template<typename T>
16 class SkBlockComRef : public T {
17 private:
18     virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
19     virtual ULONG STDMETHODCALLTYPE Release(void) = 0;
20 };
21 
SkRefComPtr(T * ptr)22 template<typename T> T* SkRefComPtr(T* ptr) {
23     ptr->AddRef();
24     return ptr;
25 }
26 
SkSafeRefComPtr(T * ptr)27 template<typename T> T* SkSafeRefComPtr(T* ptr) {
28     if (ptr) {
29         ptr->AddRef();
30     }
31     return ptr;
32 }
33 
34 template<typename T>
35 class SkTScopedComPtr : SkNoncopyable {
36 private:
37     T *fPtr;
38 
39 public:
fPtr(ptr)40     explicit SkTScopedComPtr(T *ptr = NULL) : fPtr(ptr) { }
~SkTScopedComPtr()41     ~SkTScopedComPtr() {
42         this->reset();
43     }
44     T &operator*() const { SkASSERT(fPtr != NULL); return *fPtr; }
45     SkBlockComRef<T> *operator->() const {
46         return static_cast<SkBlockComRef<T>*>(fPtr);
47     }
48     /**
49      * Returns the address of the underlying pointer.
50      * This is dangerous -- it breaks encapsulation and the reference escapes.
51      * Must only be used on instances currently pointing to NULL,
52      * and only to initialize the instance.
53      */
54     T **operator&() { SkASSERT(fPtr == NULL); return &fPtr; }
get()55     T *get() const { return fPtr; }
reset()56     void reset() {
57         if (this->fPtr) {
58             this->fPtr->Release();
59             this->fPtr = NULL;
60         }
61     }
62 
swap(SkTScopedComPtr<T> & that)63     void swap(SkTScopedComPtr<T>& that) {
64         T* temp = this->fPtr;
65         this->fPtr = that.fPtr;
66         that.fPtr = temp;
67     }
68 
release()69     T* release() {
70         T* temp = this->fPtr;
71         this->fPtr = NULL;
72         return temp;
73     }
74 };
75 
76 #endif
77