• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
16 
17 #ifndef ANDROID_STRONG_POINTER_H
18 #define ANDROID_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 
29 template<typename T> class wp;
30 
31 // ---------------------------------------------------------------------------
32 
33 #define COMPARE(_op_)                                           \
34 inline bool operator _op_ (const sp<T>& o) const {              \
35     return m_ptr _op_ o.m_ptr;                                  \
36 }                                                               \
37 inline bool operator _op_ (const T* o) const {                  \
38     return m_ptr _op_ o;                                        \
39 }                                                               \
40 template<typename U>                                            \
41 inline bool operator _op_ (const sp<U>& o) const {              \
42     return m_ptr _op_ o.m_ptr;                                  \
43 }                                                               \
44 template<typename U>                                            \
45 inline bool operator _op_ (const U* o) const {                  \
46     return m_ptr _op_ o;                                        \
47 }                                                               \
48 inline bool operator _op_ (const wp<T>& o) const {              \
49     return m_ptr _op_ o.m_ptr;                                  \
50 }                                                               \
51 template<typename U>                                            \
52 inline bool operator _op_ (const wp<U>& o) const {              \
53     return m_ptr _op_ o.m_ptr;                                  \
54 }
55 
56 // ---------------------------------------------------------------------------
57 
58 template<typename T>
59 class sp {
60 public:
sp()61     inline sp() : m_ptr(0) { }
62 
63     sp(T* other);
64     sp(const sp<T>& other);
65     sp(sp<T>&& other);
66     template<typename U> sp(U* other);
67     template<typename U> sp(const sp<U>& other);
68     template<typename U> sp(sp<U>&& other);
69 
70     ~sp();
71 
72     // Assignment
73 
74     sp& operator = (T* other);
75     sp& operator = (const sp<T>& other);
76     sp& operator = (sp<T>&& other);
77 
78     template<typename U> sp& operator = (const sp<U>& other);
79     template<typename U> sp& operator = (sp<U>&& other);
80     template<typename U> sp& operator = (U* other);
81 
82     //! Special optimization for use by ProcessState (and nobody else).
83     void force_set(T* other);
84 
85     // Reset
86 
87     void clear();
88 
89     // Accessors
90 
91     inline  T&      operator* () const  { return *m_ptr; }
92     inline  T*      operator-> () const { return m_ptr;  }
get()93     inline  T*      get() const         { return m_ptr; }
94 
95     // Operators
96 
97     COMPARE(==)
98     COMPARE(!=)
99     COMPARE(>)
100     COMPARE(<)
101     COMPARE(<=)
102     COMPARE(>=)
103 
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 };
110 
111 #undef COMPARE
112 
113 // ---------------------------------------------------------------------------
114 // No user serviceable parts below here.
115 
116 template<typename T>
sp(T * other)117 sp<T>::sp(T* other)
118         : m_ptr(other) {
119     if (other)
120         other->incStrong(this);
121 }
122 
123 template<typename T>
sp(const sp<T> & other)124 sp<T>::sp(const sp<T>& other)
125         : m_ptr(other.m_ptr) {
126     if (m_ptr)
127         m_ptr->incStrong(this);
128 }
129 
130 template<typename T>
sp(sp<T> && other)131 sp<T>::sp(sp<T>&& other)
132         : m_ptr(other.m_ptr) {
133     other.m_ptr = nullptr;
134 }
135 
136 template<typename T> template<typename U>
sp(U * other)137 sp<T>::sp(U* other)
138         : m_ptr(other) {
139     if (other)
140         ((T*) other)->incStrong(this);
141 }
142 
143 template<typename T> template<typename U>
sp(const sp<U> & other)144 sp<T>::sp(const sp<U>& other)
145         : m_ptr(other.m_ptr) {
146     if (m_ptr)
147         m_ptr->incStrong(this);
148 }
149 
150 template<typename T> template<typename U>
sp(sp<U> && other)151 sp<T>::sp(sp<U>&& other)
152         : m_ptr(other.m_ptr) {
153     other.m_ptr = nullptr;
154 }
155 
156 template<typename T>
~sp()157 sp<T>::~sp() {
158     if (m_ptr)
159         m_ptr->decStrong(this);
160 }
161 
162 template<typename T>
163 sp<T>& sp<T>::operator =(const sp<T>& other) {
164     T* otherPtr(other.m_ptr);
165     if (otherPtr)
166         otherPtr->incStrong(this);
167     if (m_ptr)
168         m_ptr->decStrong(this);
169     m_ptr = otherPtr;
170     return *this;
171 }
172 
173 template<typename T>
174 sp<T>& sp<T>::operator =(sp<T>&& other) {
175     if (m_ptr)
176         m_ptr->decStrong(this);
177     m_ptr = other.m_ptr;
178     other.m_ptr = nullptr;
179     return *this;
180 }
181 
182 template<typename T>
183 sp<T>& sp<T>::operator =(T* other) {
184     if (other)
185         other->incStrong(this);
186     if (m_ptr)
187         m_ptr->decStrong(this);
188     m_ptr = other;
189     return *this;
190 }
191 
192 template<typename T> template<typename U>
193 sp<T>& sp<T>::operator =(const sp<U>& other) {
194     T* otherPtr(other.m_ptr);
195     if (otherPtr)
196         otherPtr->incStrong(this);
197     if (m_ptr)
198         m_ptr->decStrong(this);
199     m_ptr = otherPtr;
200     return *this;
201 }
202 
203 template<typename T> template<typename U>
204 sp<T>& sp<T>::operator =(sp<U>&& other) {
205     if (m_ptr)
206         m_ptr->decStrong(this);
207     m_ptr = other.m_ptr;
208     other.m_ptr = nullptr;
209     return *this;
210 }
211 
212 template<typename T> template<typename U>
213 sp<T>& sp<T>::operator =(U* other) {
214     if (other)
215         ((T*) other)->incStrong(this);
216     if (m_ptr)
217         m_ptr->decStrong(this);
218     m_ptr = other;
219     return *this;
220 }
221 
222 template<typename T>
force_set(T * other)223 void sp<T>::force_set(T* other) {
224     other->forceIncStrong(this);
225     m_ptr = other;
226 }
227 
228 template<typename T>
clear()229 void sp<T>::clear() {
230     if (m_ptr) {
231         m_ptr->decStrong(this);
232         m_ptr = 0;
233     }
234 }
235 
236 template<typename T>
set_pointer(T * ptr)237 void sp<T>::set_pointer(T* ptr) {
238     m_ptr = ptr;
239 }
240 
241 }; // namespace android
242 
243 // ---------------------------------------------------------------------------
244 
245 #endif // ANDROID_STRONG_POINTER_H
246