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