blob: a8c989749b60983c83ecd895a54fa4c1cec2b31e [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;
Mathias Agopian3e0f8752011-02-24 18:12:34 -0800107 void set_pointer(T* ptr);
108 T* m_ptr;
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800109};
110
111#undef COMPARE
112
113template <typename T>
114TextOutput& operator<<(TextOutput& to, const sp<T>& val);
115
116// ---------------------------------------------------------------------------
117// No user serviceable parts below here.
118
119template<typename T>
120sp<T>::sp(T* other)
121: m_ptr(other)
122 {
123 if (other) other->incStrong(this);
124 }
125
126template<typename T>
127sp<T>::sp(const sp<T>& other)
128: m_ptr(other.m_ptr)
129 {
130 if (m_ptr) m_ptr->incStrong(this);
131 }
132
133template<typename T> template<typename U>
134sp<T>::sp(U* other) : m_ptr(other)
135{
136 if (other) other->incStrong(this);
137}
138
139template<typename T> template<typename U>
140sp<T>::sp(const sp<U>& other)
141: m_ptr(other.m_ptr)
142 {
143 if (m_ptr) m_ptr->incStrong(this);
144 }
145
146template<typename T>
147sp<T>::~sp()
148{
149 if (m_ptr) m_ptr->decStrong(this);
150}
151
152template<typename T>
153sp<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}
160
161template<typename T>
162sp<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}
169
170template<typename T> template<typename U>
171sp<T>& sp<T>::operator = (const sp<U>& other)
172{
173 U* 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}
179
180template<typename T> template<typename U>
181sp<T>& sp<T>::operator = (U* other)
182{
183 if (other) other->incStrong(this);
184 if (m_ptr) m_ptr->decStrong(this);
185 m_ptr = other;
186 return *this;
187}
188
189template<typename T>
190void sp<T>::force_set(T* other)
191{
192 other->forceIncStrong(this);
193 m_ptr = other;
194}
195
196template<typename T>
197void sp<T>::clear()
198{
199 if (m_ptr) {
200 m_ptr->decStrong(this);
201 m_ptr = 0;
202 }
203}
204
205template<typename T>
Mathias Agopian3e0f8752011-02-24 18:12:34 -0800206void sp<T>::set_pointer(T* ptr) {
207 m_ptr = ptr;
208}
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800209
210template <typename T>
211inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
212{
213 return printStrongPointer(to, val.get());
214}
215
216}; // namespace android
217
218// ---------------------------------------------------------------------------
219
220#endif // ANDROID_STRONG_POINTER_H