Home | History | Annotate | Download | only in win
      1 /*
      2  * 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.
      6  */
      7 
      8 #ifndef SkTScopedComPtr_DEFINED
      9 #define SkTScopedComPtr_DEFINED
     10 
     11 #include "SkLeanWindows.h"
     12 
     13 #ifdef SK_BUILD_FOR_WIN
     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 
     22 template<typename T> T* SkRefComPtr(T* ptr) {
     23     ptr->AddRef();
     24     return ptr;
     25 }
     26 
     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 {
     36 private:
     37     T *fPtr;
     38 
     39 public:
     40     constexpr SkTScopedComPtr() : fPtr(nullptr) {}
     41     constexpr SkTScopedComPtr(std::nullptr_t) : fPtr(nullptr) {}
     42     explicit SkTScopedComPtr(T *ptr) : fPtr(ptr) {}
     43     SkTScopedComPtr(SkTScopedComPtr&& that) : fPtr(that.release()) {}
     44     SkTScopedComPtr(const SkTScopedComPtr&) = delete;
     45 
     46     ~SkTScopedComPtr() { this->reset();}
     47 
     48     SkTScopedComPtr& operator=(SkTScopedComPtr&& that) {
     49         this->reset(that.release());
     50         return *this;
     51     }
     52     SkTScopedComPtr& operator=(const SkTScopedComPtr&) = delete;
     53     SkTScopedComPtr& operator=(std::nullptr_t) { this->reset(); return *this; }
     54 
     55     T &operator*() const { SkASSERT(fPtr != nullptr); return *fPtr; }
     56 
     57     explicit operator bool() const { return fPtr != nullptr; }
     58 
     59     SkBlockComRef<T> *operator->() const { return static_cast<SkBlockComRef<T>*>(fPtr); }
     60 
     61     /**
     62      * Returns the address of the underlying pointer.
     63      * This is dangerous -- it breaks encapsulation and the reference escapes.
     64      * Must only be used on instances currently pointing to NULL,
     65      * and only to initialize the instance.
     66      */
     67     T **operator&() { SkASSERT(fPtr == nullptr); return &fPtr; }
     68 
     69     T *get() const { return fPtr; }
     70 
     71     void reset(T* ptr = nullptr) {
     72         if (fPtr) {
     73             fPtr->Release();
     74         }
     75         fPtr = ptr;
     76     }
     77 
     78     void swap(SkTScopedComPtr<T>& that) {
     79         T* temp = this->fPtr;
     80         this->fPtr = that.fPtr;
     81         that.fPtr = temp;
     82     }
     83 
     84     T* release() {
     85         T* temp = this->fPtr;
     86         this->fPtr = nullptr;
     87         return temp;
     88     }
     89 };
     90 
     91 #endif  // SK_BUILD_FOR_WIN
     92 #endif  // SkTScopedComPtr_DEFINED
     93