blob: aba9577da4fc5deb6e648a76b30878310df411b7 [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
Mathias Agopianb26ea8b2011-02-16 20:23:43 -080029template<typename T> class wp;
30
31// ---------------------------------------------------------------------------
32
33#define COMPARE(_op_) \
34inline bool operator _op_ (const sp<T>& o) const { \
35 return m_ptr _op_ o.m_ptr; \
36} \
37inline bool operator _op_ (const T* o) const { \
38 return m_ptr _op_ o; \
39} \
40template<typename U> \
41inline bool operator _op_ (const sp<U>& o) const { \
42 return m_ptr _op_ o.m_ptr; \
43} \
44template<typename U> \
45inline bool operator _op_ (const U* o) const { \
46 return m_ptr _op_ o; \
47} \
48inline bool operator _op_ (const wp<T>& o) const { \
49 return m_ptr _op_ o.m_ptr; \
50} \
51template<typename U> \
52inline bool operator _op_ (const wp<U>& o) const { \
53 return m_ptr _op_ o.m_ptr; \
54}
55
56// ---------------------------------------------------------------------------
57
Mathias Agopian8db925f2013-05-09 13:04:32 -070058template<typename T>
59class sp {
Mathias Agopianb26ea8b2011-02-16 20:23:43 -080060public:
61 inline sp() : m_ptr(0) { }
62
63 sp(T* other);
64 sp(const sp<T>& other);
65 template<typename U> sp(U* other);
66 template<typename U> sp(const sp<U>& other);
67
68 ~sp();
69
70 // Assignment
71
72 sp& operator = (T* other);
73 sp& operator = (const sp<T>& other);
74
75 template<typename U> sp& operator = (const sp<U>& other);
76 template<typename U> sp& operator = (U* other);
77
78 //! Special optimization for use by ProcessState (and nobody else).
79 void force_set(T* other);
80
81 // Reset
82
83 void clear();
84
85 // Accessors
86
87 inline T& operator* () const { return *m_ptr; }
88 inline T* operator-> () const { return m_ptr; }
89 inline T* get() const { return m_ptr; }
90
91 // Operators
92
93 COMPARE(==)
94 COMPARE(!=)
95 COMPARE(>)
96 COMPARE(<)
97 COMPARE(<=)
98 COMPARE(>=)
99
100private:
101 template<typename Y> friend class sp;
102 template<typename Y> friend class wp;
Mathias Agopian3e0f8752011-02-24 18:12:34 -0800103 void set_pointer(T* ptr);
104 T* m_ptr;
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800105};
106
107#undef COMPARE
108
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800109// ---------------------------------------------------------------------------
110// No user serviceable parts below here.
111
112template<typename T>
113sp<T>::sp(T* other)
Mathias Agopian8db925f2013-05-09 13:04:32 -0700114 : m_ptr(other) {
115 if (other)
116 other->incStrong(this);
117}
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800118
119template<typename T>
120sp<T>::sp(const sp<T>& other)
Mathias Agopian8db925f2013-05-09 13:04:32 -0700121 : m_ptr(other.m_ptr) {
122 if (m_ptr)
123 m_ptr->incStrong(this);
124}
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800125
126template<typename T> template<typename U>
Mathias Agopian8db925f2013-05-09 13:04:32 -0700127sp<T>::sp(U* other)
128 : m_ptr(other) {
129 if (other)
130 ((T*) other)->incStrong(this);
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800131}
132
133template<typename T> template<typename U>
134sp<T>::sp(const sp<U>& other)
Mathias Agopian8db925f2013-05-09 13:04:32 -0700135 : m_ptr(other.m_ptr) {
136 if (m_ptr)
137 m_ptr->incStrong(this);
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800138}
139
140template<typename T>
Mathias Agopian8db925f2013-05-09 13:04:32 -0700141sp<T>::~sp() {
142 if (m_ptr)
143 m_ptr->decStrong(this);
144}
145
146template<typename T>
147sp<T>& sp<T>::operator =(const sp<T>& other) {
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800148 T* otherPtr(other.m_ptr);
Mathias Agopian8db925f2013-05-09 13:04:32 -0700149 if (otherPtr)
150 otherPtr->incStrong(this);
151 if (m_ptr)
152 m_ptr->decStrong(this);
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800153 m_ptr = otherPtr;
154 return *this;
155}
156
157template<typename T>
Mathias Agopian8db925f2013-05-09 13:04:32 -0700158sp<T>& sp<T>::operator =(T* other) {
159 if (other)
160 other->incStrong(this);
161 if (m_ptr)
162 m_ptr->decStrong(this);
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800163 m_ptr = other;
164 return *this;
165}
166
167template<typename T> template<typename U>
Mathias Agopian8db925f2013-05-09 13:04:32 -0700168sp<T>& sp<T>::operator =(const sp<U>& other) {
Mathias Agopian7332f802011-02-25 16:11:44 -0800169 T* otherPtr(other.m_ptr);
Mathias Agopian8db925f2013-05-09 13:04:32 -0700170 if (otherPtr)
171 otherPtr->incStrong(this);
172 if (m_ptr)
173 m_ptr->decStrong(this);
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800174 m_ptr = otherPtr;
175 return *this;
176}
177
178template<typename T> template<typename U>
Mathias Agopian8db925f2013-05-09 13:04:32 -0700179sp<T>& sp<T>::operator =(U* other) {
180 if (other)
181 ((T*) other)->incStrong(this);
182 if (m_ptr)
183 m_ptr->decStrong(this);
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800184 m_ptr = other;
185 return *this;
186}
187
Mathias Agopian8db925f2013-05-09 13:04:32 -0700188template<typename T>
189void sp<T>::force_set(T* other) {
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800190 other->forceIncStrong(this);
191 m_ptr = other;
192}
193
194template<typename T>
Mathias Agopian8db925f2013-05-09 13:04:32 -0700195void sp<T>::clear() {
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800196 if (m_ptr) {
197 m_ptr->decStrong(this);
198 m_ptr = 0;
199 }
200}
201
202template<typename T>
Mathias Agopian3e0f8752011-02-24 18:12:34 -0800203void sp<T>::set_pointer(T* ptr) {
204 m_ptr = ptr;
205}
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800206
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800207}; // namespace android
208
209// ---------------------------------------------------------------------------
210
211#endif // ANDROID_STRONG_POINTER_H