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