Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /*
2 * Copyright (C) 2005 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 */
17 #ifndef ANDROID_STRONG_POINTER_H
18 #define ANDROID_STRONG_POINTER_H
20 #include <cutils/atomic.h>
22 #include <stdint.h>
23 #include <sys/types.h>
24 #include <stdlib.h>
26 // ---------------------------------------------------------------------------
27 namespace android {
29 class TextOutput;
30 TextOutput& printStrongPointer(TextOutput& to, const void* val);
32 template<typename T> class wp;
34 // ---------------------------------------------------------------------------
36 #define COMPARE(_op_) \
37 inline bool operator _op_ (const sp<T>& o) const { \
38 return m_ptr _op_ o.m_ptr; \
39 } \
40 inline bool operator _op_ (const T* o) const { \
41 return m_ptr _op_ o; \
42 } \
43 template<typename U> \
44 inline bool operator _op_ (const sp<U>& o) const { \
45 return m_ptr _op_ o.m_ptr; \
46 } \
47 template<typename U> \
48 inline bool operator _op_ (const U* o) const { \
49 return m_ptr _op_ o; \
50 } \
51 inline bool operator _op_ (const wp<T>& o) const { \
52 return m_ptr _op_ o.m_ptr; \
53 } \
54 template<typename U> \
55 inline bool operator _op_ (const wp<U>& o) const { \
56 return m_ptr _op_ o.m_ptr; \
57 }
59 // ---------------------------------------------------------------------------
61 template <typename T>
62 class sp
63 {
64 public:
65 inline sp() : m_ptr(0) { }
67 sp(T* other);
68 sp(const sp<T>& other);
69 template<typename U> sp(U* other);
70 template<typename U> sp(const sp<U>& other);
72 ~sp();
74 // Assignment
76 sp& operator = (T* other);
77 sp& operator = (const sp<T>& other);
79 template<typename U> sp& operator = (const sp<U>& other);
80 template<typename U> sp& operator = (U* other);
82 //! Special optimization for use by ProcessState (and nobody else).
83 void force_set(T* other);
85 // Reset
87 void clear();
89 // Accessors
91 inline T& operator* () const { return *m_ptr; }
92 inline T* operator-> () const { return m_ptr; }
93 inline T* get() const { return m_ptr; }
95 // Operators
97 COMPARE(==)
98 COMPARE(!=)
99 COMPARE(>)
100 COMPARE(<)
101 COMPARE(<=)
102 COMPARE(>=)
104 private:
105 template<typename Y> friend class sp;
106 template<typename Y> friend class wp;
107 void set_pointer(T* ptr);
108 T* m_ptr;
109 };
111 #undef COMPARE
113 template <typename T>
114 TextOutput& operator<<(TextOutput& to, const sp<T>& val);
116 // ---------------------------------------------------------------------------
117 // No user serviceable parts below here.
119 template<typename T>
120 sp<T>::sp(T* other)
121 : m_ptr(other)
122 {
123 if (other) other->incStrong(this);
124 }
126 template<typename T>
127 sp<T>::sp(const sp<T>& other)
128 : m_ptr(other.m_ptr)
129 {
130 if (m_ptr) m_ptr->incStrong(this);
131 }
133 template<typename T> template<typename U>
134 sp<T>::sp(U* other) : m_ptr(other)
135 {
136 if (other) ((T*)other)->incStrong(this);
137 }
139 template<typename T> template<typename U>
140 sp<T>::sp(const sp<U>& other)
141 : m_ptr(other.m_ptr)
142 {
143 if (m_ptr) m_ptr->incStrong(this);
144 }
146 template<typename T>
147 sp<T>::~sp()
148 {
149 if (m_ptr) m_ptr->decStrong(this);
150 }
152 template<typename T>
153 sp<T>& sp<T>::operator = (const sp<T>& other) {
154 T* otherPtr(other.m_ptr);
155 if (otherPtr) otherPtr->incStrong(this);
156 if (m_ptr) m_ptr->decStrong(this);
157 m_ptr = otherPtr;
158 return *this;
159 }
161 template<typename T>
162 sp<T>& sp<T>::operator = (T* other)
163 {
164 if (other) other->incStrong(this);
165 if (m_ptr) m_ptr->decStrong(this);
166 m_ptr = other;
167 return *this;
168 }
170 template<typename T> template<typename U>
171 sp<T>& sp<T>::operator = (const sp<U>& other)
172 {
173 T* otherPtr(other.m_ptr);
174 if (otherPtr) otherPtr->incStrong(this);
175 if (m_ptr) m_ptr->decStrong(this);
176 m_ptr = otherPtr;
177 return *this;
178 }
180 template<typename T> template<typename U>
181 sp<T>& sp<T>::operator = (U* other)
182 {
183 if (other) ((T*)other)->incStrong(this);
184 if (m_ptr) m_ptr->decStrong(this);
185 m_ptr = other;
186 return *this;
187 }
189 template<typename T>
190 void sp<T>::force_set(T* other)
191 {
192 other->forceIncStrong(this);
193 m_ptr = other;
194 }
196 template<typename T>
197 void sp<T>::clear()
198 {
199 if (m_ptr) {
200 m_ptr->decStrong(this);
201 m_ptr = 0;
202 }
203 }
205 template<typename T>
206 void sp<T>::set_pointer(T* ptr) {
207 m_ptr = ptr;
208 }
210 template <typename T>
211 inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
212 {
213 return printStrongPointer(to, val.get());
214 }
216 }; // namespace android
218 // ---------------------------------------------------------------------------
220 #endif // ANDROID_STRONG_POINTER_H