blob: 5daccf4f096d0748a147720a29433bdca5ba2d7a [file] [log] [blame]
Mathias Agopianb26ea8b2011-02-16 20:23:43 -08001/*
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// ---------------------------------------------------------------------------
27namespace android {
28
29class TextOutput;
30TextOutput& printStrongPointer(TextOutput& to, const void* val);
31
32template<typename T> class wp;
33
34// ---------------------------------------------------------------------------
35
36#define COMPARE(_op_) \
37inline bool operator _op_ (const sp<T>& o) const { \
38 return m_ptr _op_ o.m_ptr; \
39} \
40inline bool operator _op_ (const T* o) const { \
41 return m_ptr _op_ o; \
42} \
43template<typename U> \
44inline bool operator _op_ (const sp<U>& o) const { \
45 return m_ptr _op_ o.m_ptr; \
46} \
47template<typename U> \
48inline bool operator _op_ (const U* o) const { \
49 return m_ptr _op_ o; \
50} \
51inline bool operator _op_ (const wp<T>& o) const { \
52 return m_ptr _op_ o.m_ptr; \
53} \
54template<typename U> \
55inline bool operator _op_ (const wp<U>& o) const { \
56 return m_ptr _op_ o.m_ptr; \
57}
58
59// ---------------------------------------------------------------------------
60
61template <typename T>
62class sp
63{
64public:
65 inline sp() : m_ptr(0) { }
66
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);
71
72 ~sp();
73
74 // Assignment
75
76 sp& operator = (T* other);
77 sp& operator = (const sp<T>& other);
78
79 template<typename U> sp& operator = (const 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; }
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
104private:
105 template<typename Y> friend class sp;
106 template<typename Y> friend class wp;
107
108 // Optimization for wp::promote().
109 sp(T* p, bool);
110
111 T* m_ptr;
112};
113
114#undef COMPARE
115
116template <typename T>
117TextOutput& operator<<(TextOutput& to, const sp<T>& val);
118
119// ---------------------------------------------------------------------------
120// No user serviceable parts below here.
121
122template<typename T>
123sp<T>::sp(T* other)
124: m_ptr(other)
125 {
126 if (other) other->incStrong(this);
127 }
128
129template<typename T>
130sp<T>::sp(const sp<T>& other)
131: m_ptr(other.m_ptr)
132 {
133 if (m_ptr) m_ptr->incStrong(this);
134 }
135
136template<typename T> template<typename U>
137sp<T>::sp(U* other) : m_ptr(other)
138{
139 if (other) other->incStrong(this);
140}
141
142template<typename T> template<typename U>
143sp<T>::sp(const sp<U>& other)
144: m_ptr(other.m_ptr)
145 {
146 if (m_ptr) m_ptr->incStrong(this);
147 }
148
149template<typename T>
150sp<T>::~sp()
151{
152 if (m_ptr) m_ptr->decStrong(this);
153}
154
155template<typename T>
156sp<T>& sp<T>::operator = (const sp<T>& other) {
157 T* otherPtr(other.m_ptr);
158 if (otherPtr) otherPtr->incStrong(this);
159 if (m_ptr) m_ptr->decStrong(this);
160 m_ptr = otherPtr;
161 return *this;
162}
163
164template<typename T>
165sp<T>& sp<T>::operator = (T* other)
166{
167 if (other) other->incStrong(this);
168 if (m_ptr) m_ptr->decStrong(this);
169 m_ptr = other;
170 return *this;
171}
172
173template<typename T> template<typename U>
174sp<T>& sp<T>::operator = (const sp<U>& other)
175{
176 U* otherPtr(other.m_ptr);
177 if (otherPtr) otherPtr->incStrong(this);
178 if (m_ptr) m_ptr->decStrong(this);
179 m_ptr = otherPtr;
180 return *this;
181}
182
183template<typename T> template<typename U>
184sp<T>& sp<T>::operator = (U* other)
185{
186 if (other) other->incStrong(this);
187 if (m_ptr) m_ptr->decStrong(this);
188 m_ptr = other;
189 return *this;
190}
191
192template<typename T>
193void sp<T>::force_set(T* other)
194{
195 other->forceIncStrong(this);
196 m_ptr = other;
197}
198
199template<typename T>
200void sp<T>::clear()
201{
202 if (m_ptr) {
203 m_ptr->decStrong(this);
204 m_ptr = 0;
205 }
206}
207
208template<typename T>
209sp<T>::sp(T* p, bool)
210: m_ptr(p)
211 {
212 }
213
214template <typename T>
215inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
216{
217 return printStrongPointer(to, val.get());
218}
219
220}; // namespace android
221
222// ---------------------------------------------------------------------------
223
224#endif // ANDROID_STRONG_POINTER_H