• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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