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