SkTScopedComPtr.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. #ifndef SkTScopedComPtr_DEFINED
  8. #define SkTScopedComPtr_DEFINED
  9. #include "src/core/SkLeanWindows.h"
  10. #ifdef SK_BUILD_FOR_WIN
  11. template<typename T>
  12. class SkBlockComRef : public T {
  13. private:
  14. virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
  15. virtual ULONG STDMETHODCALLTYPE Release(void) = 0;
  16. virtual ~SkBlockComRef() {}
  17. };
  18. template<typename T> T* SkRefComPtr(T* ptr) {
  19. ptr->AddRef();
  20. return ptr;
  21. }
  22. template<typename T> T* SkSafeRefComPtr(T* ptr) {
  23. if (ptr) {
  24. ptr->AddRef();
  25. }
  26. return ptr;
  27. }
  28. template<typename T>
  29. class SkTScopedComPtr {
  30. private:
  31. T *fPtr;
  32. public:
  33. constexpr SkTScopedComPtr() : fPtr(nullptr) {}
  34. constexpr SkTScopedComPtr(std::nullptr_t) : fPtr(nullptr) {}
  35. explicit SkTScopedComPtr(T *ptr) : fPtr(ptr) {}
  36. SkTScopedComPtr(SkTScopedComPtr&& that) : fPtr(that.release()) {}
  37. SkTScopedComPtr(const SkTScopedComPtr&) = delete;
  38. ~SkTScopedComPtr() { this->reset();}
  39. SkTScopedComPtr& operator=(SkTScopedComPtr&& that) {
  40. this->reset(that.release());
  41. return *this;
  42. }
  43. SkTScopedComPtr& operator=(const SkTScopedComPtr&) = delete;
  44. SkTScopedComPtr& operator=(std::nullptr_t) { this->reset(); return *this; }
  45. T &operator*() const { SkASSERT(fPtr != nullptr); return *fPtr; }
  46. explicit operator bool() const { return fPtr != nullptr; }
  47. SkBlockComRef<T> *operator->() const { return static_cast<SkBlockComRef<T>*>(fPtr); }
  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 == nullptr); return &fPtr; }
  55. T *get() const { return fPtr; }
  56. void reset(T* ptr = nullptr) {
  57. if (fPtr) {
  58. fPtr->Release();
  59. }
  60. fPtr = ptr;
  61. }
  62. void swap(SkTScopedComPtr<T>& that) {
  63. T* temp = this->fPtr;
  64. this->fPtr = that.fPtr;
  65. that.fPtr = temp;
  66. }
  67. T* release() {
  68. T* temp = this->fPtr;
  69. this->fPtr = nullptr;
  70. return temp;
  71. }
  72. };
  73. #endif // SK_BUILD_FOR_WIN
  74. #endif // SkTScopedComPtr_DEFINED