blob: 105b6017da2f825019c1f07d1357fe428910acad [file] [log] [blame]
bungeman@google.com9df621d2011-06-23 21:43:52 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
bungeman@google.com9df621d2011-06-23 21:43:52 +00006 */
7
commit-bot@chromium.orge0294402013-08-29 22:14:04 +00008#ifndef SkTScopedComPtr_DEFINED
9#define SkTScopedComPtr_DEFINED
bungeman@google.com9df621d2011-06-23 21:43:52 +000010
bungeman2853f002016-06-16 15:31:42 -070011#include "SkLeanWindows.h"
bungeman@google.com9df621d2011-06-23 21:43:52 +000012
halcanary0cbe7ee2015-12-01 09:02:49 -080013#ifdef SK_BUILD_FOR_WIN
14
bungeman@google.com9df621d2011-06-23 21:43:52 +000015template<typename T>
bungeman@google.comb29c8832011-10-10 13:19:10 +000016class SkBlockComRef : public T {
17private:
18 virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
19 virtual ULONG STDMETHODCALLTYPE Release(void) = 0;
20};
21
bungeman@google.com71033442013-05-01 14:21:20 +000022template<typename T> T* SkRefComPtr(T* ptr) {
23 ptr->AddRef();
24 return ptr;
25}
26
bungeman@google.com4bbc5242013-05-02 14:01:36 +000027template<typename T> T* SkSafeRefComPtr(T* ptr) {
28 if (ptr) {
29 ptr->AddRef();
30 }
31 return ptr;
32}
33
bungeman@google.comb29c8832011-10-10 13:19:10 +000034template<typename T>
bungeman@google.com9df621d2011-06-23 21:43:52 +000035class SkTScopedComPtr : SkNoncopyable {
36private:
37 T *fPtr;
38
39public:
bungeman2853f002016-06-16 15:31:42 -070040 explicit SkTScopedComPtr(T *ptr = nullptr) : fPtr(ptr) { }
41
42 ~SkTScopedComPtr() { this->reset();}
43
44 T &operator*() const { SkASSERT(fPtr != nullptr); return *fPtr; }
45
46 explicit operator bool() const { return fPtr != nullptr; }
47
48 SkBlockComRef<T> *operator->() const { return static_cast<SkBlockComRef<T>*>(fPtr); }
49
bungeman@google.com9df621d2011-06-23 21:43:52 +000050 /**
51 * Returns the address of the underlying pointer.
52 * This is dangerous -- it breaks encapsulation and the reference escapes.
53 * Must only be used on instances currently pointing to NULL,
54 * and only to initialize the instance.
55 */
bungeman2853f002016-06-16 15:31:42 -070056 T **operator&() { SkASSERT(fPtr == nullptr); return &fPtr; }
57
bungeman@google.com9df621d2011-06-23 21:43:52 +000058 T *get() const { return fPtr; }
bungeman2853f002016-06-16 15:31:42 -070059
Hal Canarybd81a322016-12-21 08:18:51 -050060 void reset(T* ptr = nullptr) {
61 if (fPtr) {
62 fPtr->Release();
bungeman@google.coma9e586a2011-08-09 19:25:05 +000063 }
Hal Canarybd81a322016-12-21 08:18:51 -050064 fPtr = ptr;
bungeman@google.coma9e586a2011-08-09 19:25:05 +000065 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +000066
bungeman@google.comb29c8832011-10-10 13:19:10 +000067 void swap(SkTScopedComPtr<T>& that) {
68 T* temp = this->fPtr;
69 this->fPtr = that.fPtr;
70 that.fPtr = temp;
71 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +000072
bungeman@google.comb29c8832011-10-10 13:19:10 +000073 T* release() {
74 T* temp = this->fPtr;
bungeman2853f002016-06-16 15:31:42 -070075 this->fPtr = nullptr;
bungeman@google.comb29c8832011-10-10 13:19:10 +000076 return temp;
77 }
bungeman@google.com9df621d2011-06-23 21:43:52 +000078};
79
halcanary0cbe7ee2015-12-01 09:02:49 -080080#endif // SK_BUILD_FOR_WIN
81#endif // SkTScopedComPtr_DEFINED