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