blob: 8b12c07e5acc08a675d891bda2e9592d29c6ae7c [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;
Chris Dalton1ef80942017-12-04 12:01:30 -070020 virtual ~SkBlockComRef() {}
bungeman@google.comb29c8832011-10-10 13:19:10 +000021};
22
bungeman@google.com71033442013-05-01 14:21:20 +000023template<typename T> T* SkRefComPtr(T* ptr) {
24 ptr->AddRef();
25 return ptr;
26}
27
bungeman@google.com4bbc5242013-05-02 14:01:36 +000028template<typename T> T* SkSafeRefComPtr(T* ptr) {
29 if (ptr) {
30 ptr->AddRef();
31 }
32 return ptr;
33}
34
bungeman@google.comb29c8832011-10-10 13:19:10 +000035template<typename T>
Hal Canaryb2cd1d72017-01-24 11:11:31 -050036class SkTScopedComPtr {
bungeman@google.com9df621d2011-06-23 21:43:52 +000037private:
38 T *fPtr;
39
40public:
Hal Canary1b2b3fb2017-01-27 08:20:17 -050041 constexpr SkTScopedComPtr() : fPtr(nullptr) {}
42 constexpr SkTScopedComPtr(std::nullptr_t) : fPtr(nullptr) {}
43 explicit SkTScopedComPtr(T *ptr) : fPtr(ptr) {}
44 SkTScopedComPtr(SkTScopedComPtr&& that) : fPtr(that.release()) {}
45 SkTScopedComPtr(const SkTScopedComPtr&) = delete;
bungeman2853f002016-06-16 15:31:42 -070046
47 ~SkTScopedComPtr() { this->reset();}
48
Hal Canaryb2cd1d72017-01-24 11:11:31 -050049 SkTScopedComPtr& operator=(SkTScopedComPtr&& that) {
50 this->reset(that.release());
51 return *this;
52 }
53 SkTScopedComPtr& operator=(const SkTScopedComPtr&) = delete;
Hal Canary1b2b3fb2017-01-27 08:20:17 -050054 SkTScopedComPtr& operator=(std::nullptr_t) { this->reset(); return *this; }
Hal Canaryb2cd1d72017-01-24 11:11:31 -050055
bungeman2853f002016-06-16 15:31:42 -070056 T &operator*() const { SkASSERT(fPtr != nullptr); return *fPtr; }
57
58 explicit operator bool() const { return fPtr != nullptr; }
59
60 SkBlockComRef<T> *operator->() const { return static_cast<SkBlockComRef<T>*>(fPtr); }
61
bungeman@google.com9df621d2011-06-23 21:43:52 +000062 /**
63 * Returns the address of the underlying pointer.
64 * This is dangerous -- it breaks encapsulation and the reference escapes.
65 * Must only be used on instances currently pointing to NULL,
66 * and only to initialize the instance.
67 */
bungeman2853f002016-06-16 15:31:42 -070068 T **operator&() { SkASSERT(fPtr == nullptr); return &fPtr; }
69
bungeman@google.com9df621d2011-06-23 21:43:52 +000070 T *get() const { return fPtr; }
bungeman2853f002016-06-16 15:31:42 -070071
Hal Canarybd81a322016-12-21 08:18:51 -050072 void reset(T* ptr = nullptr) {
73 if (fPtr) {
74 fPtr->Release();
bungeman@google.coma9e586a2011-08-09 19:25:05 +000075 }
Hal Canarybd81a322016-12-21 08:18:51 -050076 fPtr = ptr;
bungeman@google.coma9e586a2011-08-09 19:25:05 +000077 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +000078
bungeman@google.comb29c8832011-10-10 13:19:10 +000079 void swap(SkTScopedComPtr<T>& that) {
80 T* temp = this->fPtr;
81 this->fPtr = that.fPtr;
82 that.fPtr = temp;
83 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +000084
bungeman@google.comb29c8832011-10-10 13:19:10 +000085 T* release() {
86 T* temp = this->fPtr;
bungeman2853f002016-06-16 15:31:42 -070087 this->fPtr = nullptr;
bungeman@google.comb29c8832011-10-10 13:19:10 +000088 return temp;
89 }
bungeman@google.com9df621d2011-06-23 21:43:52 +000090};
91
halcanary0cbe7ee2015-12-01 09:02:49 -080092#endif // SK_BUILD_FOR_WIN
93#endif // SkTScopedComPtr_DEFINED