• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // CLRefPointer.h: A non-owning intrinsic reference counting smart pointer for CL objects.
7 
8 #ifndef LIBANGLE_CLREFPOINTER_H_
9 #define LIBANGLE_CLREFPOINTER_H_
10 
11 #include <algorithm>
12 
13 namespace cl
14 {
15 
16 template <typename T>
17 class RefPointer
18 {
19   public:
RefPointer()20     RefPointer() noexcept : mCLObject(nullptr) {}
21 
RefPointer(T * object)22     explicit RefPointer(T *object) noexcept : mCLObject(object)
23     {
24         if (mCLObject != nullptr)
25         {
26             mCLObject->retain();
27         }
28     }
~RefPointer()29     ~RefPointer()
30     {
31         if (mCLObject != nullptr && mCLObject->release())
32         {
33             delete mCLObject;
34         }
35     }
36 
RefPointer(std::nullptr_t)37     RefPointer(std::nullptr_t) noexcept : mCLObject(nullptr) {}
38     RefPointer &operator=(std::nullptr_t)
39     {
40         reset();
41         return *this;
42     }
43 
RefPointer(RefPointer && other)44     RefPointer(RefPointer &&other) noexcept : mCLObject(nullptr) { this->swap(other); }
45     RefPointer &operator=(RefPointer &&other)
46     {
47         this->swap(other);
48         return *this;
49     }
50 
RefPointer(const RefPointer<T> & other)51     RefPointer(const RefPointer<T> &other) : mCLObject(other.mCLObject)
52     {
53         if (mCLObject != nullptr)
54         {
55             mCLObject->retain();
56         }
57     }
58     RefPointer &operator=(const RefPointer<T> &other)
59     {
60         if (this != &other)
61         {
62             reset();
63             mCLObject = other.mCLObject;
64             if (mCLObject != nullptr)
65             {
66                 mCLObject->retain();
67             }
68         }
69         return *this;
70     }
71 
72     T *operator->() const { return mCLObject; }
73     T &operator*() const { return *mCLObject; }
74 
get()75     T *get() const { return mCLObject; }
76     explicit operator bool() const { return mCLObject != nullptr; }
77 
release()78     T *release() noexcept
79     {
80         T *const object = mCLObject;
81         mCLObject       = nullptr;
82         return object;
83     }
84 
swap(RefPointer & other)85     void swap(RefPointer &other) noexcept { std::swap(mCLObject, other.mCLObject); }
86 
reset()87     void reset()
88     {
89         if (mCLObject != nullptr)
90         {
91             T *const object = release();
92             object->release();
93         }
94     }
95 
96   private:
97     T *mCLObject;
98 };
99 
100 template <typename T>
swap(RefPointer<T> & left,RefPointer<T> & right)101 void swap(RefPointer<T> &left, RefPointer<T> &right)
102 {
103     left.swap(right);
104 }
105 
106 template <typename T>
107 bool operator==(const RefPointer<T> &ptr, nullptr_t) noexcept
108 {
109     return ptr.get() == nullptr;
110 }
111 
112 template <typename T>
113 bool operator==(nullptr_t, const RefPointer<T> &ptr) noexcept
114 {
115     return ptr.get() == nullptr;
116 }
117 
118 template <typename T>
119 bool operator!=(const RefPointer<T> &ptr, nullptr_t) noexcept
120 {
121     return ptr.get() != nullptr;
122 }
123 
124 template <typename T>
125 bool operator!=(nullptr_t, const RefPointer<T> &ptr) noexcept
126 {
127     return ptr.get() != nullptr;
128 }
129 
130 template <typename T, typename U>
131 bool operator==(const RefPointer<T> &left, const RefPointer<U> &right) noexcept
132 {
133     return left.get() == right.get();
134 }
135 
136 template <typename T, typename U>
137 bool operator!=(const RefPointer<T> &left, const RefPointer<U> &right) noexcept
138 {
139     return left.get() != right.get();
140 }
141 
142 template <typename T, typename U>
143 bool operator==(const RefPointer<T> &left, const U *right) noexcept
144 {
145     return left.get() == right;
146 }
147 
148 template <typename T, typename U>
149 bool operator==(const T *left, const RefPointer<U> &right) noexcept
150 {
151     return left == right.get();
152 }
153 
154 template <typename T, typename U>
155 bool operator!=(const RefPointer<T> &left, const U *right) noexcept
156 {
157     return left.get() != right;
158 }
159 
160 template <typename T, typename U>
161 bool operator!=(const T *left, const RefPointer<U> &right) noexcept
162 {
163     return left != right.get();
164 }
165 
166 }  // namespace cl
167 
168 #endif  // LIBANGLE_CLREFPOINTER_H_
169