1 // Copyright 2017 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef DAWNNATIVE_REFCOUNTED_H_ 16 #define DAWNNATIVE_REFCOUNTED_H_ 17 18 #include <atomic> 19 #include <cstdint> 20 21 namespace dawn_native { 22 23 class RefCounted { 24 public: 25 RefCounted(); 26 virtual ~RefCounted(); 27 28 uint64_t GetRefCount() const; 29 30 // Dawn API 31 void Reference(); 32 void Release(); 33 34 protected: 35 std::atomic_uint64_t mRefCount = {1}; 36 }; 37 38 template <typename T> 39 class Ref { 40 public: Ref()41 Ref() { 42 } 43 Ref(T * p)44 Ref(T* p) : mPointee(p) { 45 Reference(); 46 } 47 Ref(const Ref<T> & other)48 Ref(const Ref<T>& other) : mPointee(other.mPointee) { 49 Reference(); 50 } 51 Ref<T>& operator=(const Ref<T>& other) { 52 if (&other == this) 53 return *this; 54 55 other.Reference(); 56 Release(); 57 mPointee = other.mPointee; 58 59 return *this; 60 } 61 Ref(Ref<T> && other)62 Ref(Ref<T>&& other) { 63 mPointee = other.mPointee; 64 other.mPointee = nullptr; 65 } 66 Ref<T>& operator=(Ref<T>&& other) { 67 if (&other == this) 68 return *this; 69 70 Release(); 71 mPointee = other.mPointee; 72 other.mPointee = nullptr; 73 74 return *this; 75 } 76 ~Ref()77 ~Ref() { 78 Release(); 79 mPointee = nullptr; 80 } 81 82 operator bool() { 83 return mPointee != nullptr; 84 } 85 86 const T& operator*() const { 87 return *mPointee; 88 } 89 T& operator*() { 90 return *mPointee; 91 } 92 93 const T* operator->() const { 94 return mPointee; 95 } 96 T* operator->() { 97 return mPointee; 98 } 99 Get()100 const T* Get() const { 101 return mPointee; 102 } Get()103 T* Get() { 104 return mPointee; 105 } 106 107 private: Reference()108 void Reference() const { 109 if (mPointee != nullptr) { 110 mPointee->Reference(); 111 } 112 } Release()113 void Release() const { 114 if (mPointee != nullptr) { 115 mPointee->Release(); 116 } 117 } 118 119 // static_assert(std::is_base_of<RefCounted, T>::value, ""); 120 T* mPointee = nullptr; 121 }; 122 123 } // namespace dawn_native 124 125 #endif // DAWNNATIVE_REFCOUNTED_H_ 126