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