xref: /aosp_15_r20/frameworks/rs/cpp/util/StrongPointer.h (revision e1eccf28f96817838ad6867f7f39d2351ec11f56)
1*e1eccf28SAndroid Build Coastguard Worker // COPY OF StrongPointer.h from system/core/libutils/include/utils.
2*e1eccf28SAndroid Build Coastguard Worker /*
3*e1eccf28SAndroid Build Coastguard Worker  * Copyright (C) 2013 The Android Open Source Project
4*e1eccf28SAndroid Build Coastguard Worker  *
5*e1eccf28SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*e1eccf28SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*e1eccf28SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
8*e1eccf28SAndroid Build Coastguard Worker  *
9*e1eccf28SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
10*e1eccf28SAndroid Build Coastguard Worker  *
11*e1eccf28SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*e1eccf28SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*e1eccf28SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*e1eccf28SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*e1eccf28SAndroid Build Coastguard Worker  * limitations under the License.
16*e1eccf28SAndroid Build Coastguard Worker  */
17*e1eccf28SAndroid Build Coastguard Worker 
18*e1eccf28SAndroid Build Coastguard Worker #ifndef RS_STRONG_POINTER_H
19*e1eccf28SAndroid Build Coastguard Worker #define RS_STRONG_POINTER_H
20*e1eccf28SAndroid Build Coastguard Worker 
21*e1eccf28SAndroid Build Coastguard Worker //#include <cutils/atomic.h>
22*e1eccf28SAndroid Build Coastguard Worker 
23*e1eccf28SAndroid Build Coastguard Worker #include <stdint.h>
24*e1eccf28SAndroid Build Coastguard Worker #include <sys/types.h>
25*e1eccf28SAndroid Build Coastguard Worker #include <stdlib.h>
26*e1eccf28SAndroid Build Coastguard Worker 
27*e1eccf28SAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
28*e1eccf28SAndroid Build Coastguard Worker namespace android {
29*e1eccf28SAndroid Build Coastguard Worker namespace RSC {
30*e1eccf28SAndroid Build Coastguard Worker 
31*e1eccf28SAndroid Build Coastguard Worker class TextOutput;
32*e1eccf28SAndroid Build Coastguard Worker TextOutput& printStrongPointer(TextOutput& to, const void* val);
33*e1eccf28SAndroid Build Coastguard Worker 
34*e1eccf28SAndroid Build Coastguard Worker template<typename T> class wp;
35*e1eccf28SAndroid Build Coastguard Worker 
36*e1eccf28SAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
37*e1eccf28SAndroid Build Coastguard Worker 
38*e1eccf28SAndroid Build Coastguard Worker #define COMPARE(_op_)                                           \
39*e1eccf28SAndroid Build Coastguard Worker inline bool operator _op_ (const sp<T>& o) const {              \
40*e1eccf28SAndroid Build Coastguard Worker     return m_ptr _op_ o.m_ptr;                                  \
41*e1eccf28SAndroid Build Coastguard Worker }                                                               \
42*e1eccf28SAndroid Build Coastguard Worker inline bool operator _op_ (const T* o) const {                  \
43*e1eccf28SAndroid Build Coastguard Worker     return m_ptr _op_ o;                                        \
44*e1eccf28SAndroid Build Coastguard Worker }                                                               \
45*e1eccf28SAndroid Build Coastguard Worker template<typename U>                                            \
46*e1eccf28SAndroid Build Coastguard Worker inline bool operator _op_ (const sp<U>& o) const {              \
47*e1eccf28SAndroid Build Coastguard Worker     return m_ptr _op_ o.m_ptr;                                  \
48*e1eccf28SAndroid Build Coastguard Worker }                                                               \
49*e1eccf28SAndroid Build Coastguard Worker template<typename U>                                            \
50*e1eccf28SAndroid Build Coastguard Worker inline bool operator _op_ (const U* o) const {                  \
51*e1eccf28SAndroid Build Coastguard Worker     return m_ptr _op_ o;                                        \
52*e1eccf28SAndroid Build Coastguard Worker }                                                               \
53*e1eccf28SAndroid Build Coastguard Worker inline bool operator _op_ (const wp<T>& o) const {              \
54*e1eccf28SAndroid Build Coastguard Worker     return m_ptr _op_ o.m_ptr;                                  \
55*e1eccf28SAndroid Build Coastguard Worker }                                                               \
56*e1eccf28SAndroid Build Coastguard Worker template<typename U>                                            \
57*e1eccf28SAndroid Build Coastguard Worker inline bool operator _op_ (const wp<U>& o) const {              \
58*e1eccf28SAndroid Build Coastguard Worker     return m_ptr _op_ o.m_ptr;                                  \
59*e1eccf28SAndroid Build Coastguard Worker }
60*e1eccf28SAndroid Build Coastguard Worker 
61*e1eccf28SAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
62*e1eccf28SAndroid Build Coastguard Worker 
63*e1eccf28SAndroid Build Coastguard Worker template <typename T>
64*e1eccf28SAndroid Build Coastguard Worker class sp
65*e1eccf28SAndroid Build Coastguard Worker {
66*e1eccf28SAndroid Build Coastguard Worker public:
sp()67*e1eccf28SAndroid Build Coastguard Worker     inline sp() : m_ptr(0) { }
68*e1eccf28SAndroid Build Coastguard Worker 
69*e1eccf28SAndroid Build Coastguard Worker     sp(T* other);  // NOLINT, implicit
70*e1eccf28SAndroid Build Coastguard Worker     sp(const sp<T>& other);
71*e1eccf28SAndroid Build Coastguard Worker     template<typename U> sp(U* other);  // NOLINT, implicit
72*e1eccf28SAndroid Build Coastguard Worker     template<typename U> sp(const sp<U>& other);  // NOLINT, implicit
73*e1eccf28SAndroid Build Coastguard Worker 
74*e1eccf28SAndroid Build Coastguard Worker     ~sp();
75*e1eccf28SAndroid Build Coastguard Worker 
76*e1eccf28SAndroid Build Coastguard Worker     // Assignment
77*e1eccf28SAndroid Build Coastguard Worker 
78*e1eccf28SAndroid Build Coastguard Worker     sp& operator = (T* other);
79*e1eccf28SAndroid Build Coastguard Worker     sp& operator = (const sp<T>& other);
80*e1eccf28SAndroid Build Coastguard Worker 
81*e1eccf28SAndroid Build Coastguard Worker     template<typename U> sp& operator = (const sp<U>& other);
82*e1eccf28SAndroid Build Coastguard Worker     template<typename U> sp& operator = (U* other);
83*e1eccf28SAndroid Build Coastguard Worker 
84*e1eccf28SAndroid Build Coastguard Worker     //! Special optimization for use by ProcessState (and nobody else).
85*e1eccf28SAndroid Build Coastguard Worker     void force_set(T* other);
86*e1eccf28SAndroid Build Coastguard Worker 
87*e1eccf28SAndroid Build Coastguard Worker     // Reset
88*e1eccf28SAndroid Build Coastguard Worker 
89*e1eccf28SAndroid Build Coastguard Worker     void clear();
90*e1eccf28SAndroid Build Coastguard Worker 
91*e1eccf28SAndroid Build Coastguard Worker     // Accessors
92*e1eccf28SAndroid Build Coastguard Worker 
93*e1eccf28SAndroid Build Coastguard Worker     inline  T&      operator* () const  { return *m_ptr; }
94*e1eccf28SAndroid Build Coastguard Worker     inline  T*      operator-> () const { return m_ptr;  }
get()95*e1eccf28SAndroid Build Coastguard Worker     inline  T*      get() const         { return m_ptr; }
96*e1eccf28SAndroid Build Coastguard Worker 
97*e1eccf28SAndroid Build Coastguard Worker     // Operators
98*e1eccf28SAndroid Build Coastguard Worker 
99*e1eccf28SAndroid Build Coastguard Worker     COMPARE(==)
100*e1eccf28SAndroid Build Coastguard Worker     COMPARE(!=)
101*e1eccf28SAndroid Build Coastguard Worker     COMPARE(>)
102*e1eccf28SAndroid Build Coastguard Worker     COMPARE(<)
103*e1eccf28SAndroid Build Coastguard Worker     COMPARE(<=)
104*e1eccf28SAndroid Build Coastguard Worker     COMPARE(>=)
105*e1eccf28SAndroid Build Coastguard Worker 
106*e1eccf28SAndroid Build Coastguard Worker private:
107*e1eccf28SAndroid Build Coastguard Worker     template<typename Y> friend class sp;
108*e1eccf28SAndroid Build Coastguard Worker     template<typename Y> friend class wp;
109*e1eccf28SAndroid Build Coastguard Worker     void set_pointer(T* ptr);
110*e1eccf28SAndroid Build Coastguard Worker     T* m_ptr;
111*e1eccf28SAndroid Build Coastguard Worker };
112*e1eccf28SAndroid Build Coastguard Worker 
113*e1eccf28SAndroid Build Coastguard Worker #undef COMPARE
114*e1eccf28SAndroid Build Coastguard Worker 
115*e1eccf28SAndroid Build Coastguard Worker template <typename T>
116*e1eccf28SAndroid Build Coastguard Worker TextOutput& operator<<(TextOutput& to, const sp<T>& val);
117*e1eccf28SAndroid Build Coastguard Worker 
118*e1eccf28SAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
119*e1eccf28SAndroid Build Coastguard Worker // No user serviceable parts below here.
120*e1eccf28SAndroid Build Coastguard Worker 
121*e1eccf28SAndroid Build Coastguard Worker template<typename T>
sp(T * other)122*e1eccf28SAndroid Build Coastguard Worker sp<T>::sp(T* other)
123*e1eccf28SAndroid Build Coastguard Worker : m_ptr(other)
124*e1eccf28SAndroid Build Coastguard Worker   {
125*e1eccf28SAndroid Build Coastguard Worker     if (other) other->incStrong(this);
126*e1eccf28SAndroid Build Coastguard Worker   }
127*e1eccf28SAndroid Build Coastguard Worker 
128*e1eccf28SAndroid Build Coastguard Worker template<typename T>
sp(const sp<T> & other)129*e1eccf28SAndroid Build Coastguard Worker sp<T>::sp(const sp<T>& other)
130*e1eccf28SAndroid Build Coastguard Worker : m_ptr(other.m_ptr)
131*e1eccf28SAndroid Build Coastguard Worker   {
132*e1eccf28SAndroid Build Coastguard Worker     if (m_ptr) m_ptr->incStrong(this);
133*e1eccf28SAndroid Build Coastguard Worker   }
134*e1eccf28SAndroid Build Coastguard Worker 
135*e1eccf28SAndroid Build Coastguard Worker template<typename T> template<typename U>
sp(U * other)136*e1eccf28SAndroid Build Coastguard Worker sp<T>::sp(U* other) : m_ptr(other)
137*e1eccf28SAndroid Build Coastguard Worker {
138*e1eccf28SAndroid Build Coastguard Worker     if (other) ((T*)other)->incStrong(this);
139*e1eccf28SAndroid Build Coastguard Worker }
140*e1eccf28SAndroid Build Coastguard Worker 
141*e1eccf28SAndroid Build Coastguard Worker template<typename T> template<typename U>
sp(const sp<U> & other)142*e1eccf28SAndroid Build Coastguard Worker sp<T>::sp(const sp<U>& other)
143*e1eccf28SAndroid Build Coastguard Worker : m_ptr(other.m_ptr)
144*e1eccf28SAndroid Build Coastguard Worker   {
145*e1eccf28SAndroid Build Coastguard Worker     if (m_ptr) m_ptr->incStrong(this);
146*e1eccf28SAndroid Build Coastguard Worker   }
147*e1eccf28SAndroid Build Coastguard Worker 
148*e1eccf28SAndroid Build Coastguard Worker template<typename T>
~sp()149*e1eccf28SAndroid Build Coastguard Worker sp<T>::~sp()
150*e1eccf28SAndroid Build Coastguard Worker {
151*e1eccf28SAndroid Build Coastguard Worker     if (m_ptr) m_ptr->decStrong(this);
152*e1eccf28SAndroid Build Coastguard Worker }
153*e1eccf28SAndroid Build Coastguard Worker 
154*e1eccf28SAndroid Build Coastguard Worker template<typename T>
155*e1eccf28SAndroid Build Coastguard Worker sp<T>& sp<T>::operator = (const sp<T>& other) {
156*e1eccf28SAndroid Build Coastguard Worker     T* otherPtr(other.m_ptr);
157*e1eccf28SAndroid Build Coastguard Worker     if (otherPtr) otherPtr->incStrong(this);
158*e1eccf28SAndroid Build Coastguard Worker     if (m_ptr) m_ptr->decStrong(this);
159*e1eccf28SAndroid Build Coastguard Worker     m_ptr = otherPtr;
160*e1eccf28SAndroid Build Coastguard Worker     return *this;
161*e1eccf28SAndroid Build Coastguard Worker }
162*e1eccf28SAndroid Build Coastguard Worker 
163*e1eccf28SAndroid Build Coastguard Worker template<typename T>
164*e1eccf28SAndroid Build Coastguard Worker sp<T>& sp<T>::operator = (T* other)
165*e1eccf28SAndroid Build Coastguard Worker {
166*e1eccf28SAndroid Build Coastguard Worker     if (other) other->incStrong(this);
167*e1eccf28SAndroid Build Coastguard Worker     if (m_ptr) m_ptr->decStrong(this);
168*e1eccf28SAndroid Build Coastguard Worker     m_ptr = other;
169*e1eccf28SAndroid Build Coastguard Worker     return *this;
170*e1eccf28SAndroid Build Coastguard Worker }
171*e1eccf28SAndroid Build Coastguard Worker 
172*e1eccf28SAndroid Build Coastguard Worker template<typename T> template<typename U>
173*e1eccf28SAndroid Build Coastguard Worker sp<T>& sp<T>::operator = (const sp<U>& other)
174*e1eccf28SAndroid Build Coastguard Worker {
175*e1eccf28SAndroid Build Coastguard Worker     T* otherPtr(other.m_ptr);
176*e1eccf28SAndroid Build Coastguard Worker     if (otherPtr) otherPtr->incStrong(this);
177*e1eccf28SAndroid Build Coastguard Worker     if (m_ptr) m_ptr->decStrong(this);
178*e1eccf28SAndroid Build Coastguard Worker     m_ptr = otherPtr;
179*e1eccf28SAndroid Build Coastguard Worker     return *this;
180*e1eccf28SAndroid Build Coastguard Worker }
181*e1eccf28SAndroid Build Coastguard Worker 
182*e1eccf28SAndroid Build Coastguard Worker template<typename T> template<typename U>
183*e1eccf28SAndroid Build Coastguard Worker sp<T>& sp<T>::operator = (U* other)
184*e1eccf28SAndroid Build Coastguard Worker {
185*e1eccf28SAndroid Build Coastguard Worker     if (other) ((T*)other)->incStrong(this);
186*e1eccf28SAndroid Build Coastguard Worker     if (m_ptr) m_ptr->decStrong(this);
187*e1eccf28SAndroid Build Coastguard Worker     m_ptr = other;
188*e1eccf28SAndroid Build Coastguard Worker     return *this;
189*e1eccf28SAndroid Build Coastguard Worker }
190*e1eccf28SAndroid Build Coastguard Worker 
191*e1eccf28SAndroid Build Coastguard Worker template<typename T>
force_set(T * other)192*e1eccf28SAndroid Build Coastguard Worker void sp<T>::force_set(T* other)
193*e1eccf28SAndroid Build Coastguard Worker {
194*e1eccf28SAndroid Build Coastguard Worker     other->forceIncStrong(this);
195*e1eccf28SAndroid Build Coastguard Worker     m_ptr = other;
196*e1eccf28SAndroid Build Coastguard Worker }
197*e1eccf28SAndroid Build Coastguard Worker 
198*e1eccf28SAndroid Build Coastguard Worker template<typename T>
clear()199*e1eccf28SAndroid Build Coastguard Worker void sp<T>::clear()
200*e1eccf28SAndroid Build Coastguard Worker {
201*e1eccf28SAndroid Build Coastguard Worker     if (m_ptr) {
202*e1eccf28SAndroid Build Coastguard Worker         m_ptr->decStrong(this);
203*e1eccf28SAndroid Build Coastguard Worker         m_ptr = 0;
204*e1eccf28SAndroid Build Coastguard Worker     }
205*e1eccf28SAndroid Build Coastguard Worker }
206*e1eccf28SAndroid Build Coastguard Worker 
207*e1eccf28SAndroid Build Coastguard Worker template<typename T>
set_pointer(T * ptr)208*e1eccf28SAndroid Build Coastguard Worker void sp<T>::set_pointer(T* ptr) {
209*e1eccf28SAndroid Build Coastguard Worker     m_ptr = ptr;
210*e1eccf28SAndroid Build Coastguard Worker }
211*e1eccf28SAndroid Build Coastguard Worker 
212*e1eccf28SAndroid Build Coastguard Worker template <typename T>
213*e1eccf28SAndroid Build Coastguard Worker inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
214*e1eccf28SAndroid Build Coastguard Worker {
215*e1eccf28SAndroid Build Coastguard Worker     return printStrongPointer(to, val.get());
216*e1eccf28SAndroid Build Coastguard Worker }
217*e1eccf28SAndroid Build Coastguard Worker 
218*e1eccf28SAndroid Build Coastguard Worker }; // namespace RSC
219*e1eccf28SAndroid Build Coastguard Worker }; // namespace android
220*e1eccf28SAndroid Build Coastguard Worker 
221*e1eccf28SAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
222*e1eccf28SAndroid Build Coastguard Worker 
223*e1eccf28SAndroid Build Coastguard Worker #endif // RS_STRONG_POINTER_H
224