blob: d90b788b17928822ca117ee69a73e507121e3419 [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
Chih-Hung Hsieh2a929962016-08-02 12:14:47 -070063 sp(T* other); // NOLINT(implicit)
Mathias Agopianb26ea8b2011-02-16 20:23:43 -080064 sp(const sp<T>& other);
John Reckd69089a2015-10-28 15:36:33 -070065 sp(sp<T>&& other);
Chih-Hung Hsieh2a929962016-08-02 12:14:47 -070066 template<typename U> sp(U* other); // NOLINT(implicit)
67 template<typename U> sp(const sp<U>& other); // NOLINT(implicit)
68 template<typename U> sp(sp<U>&& other); // NOLINT(implicit)
Mathias Agopianb26ea8b2011-02-16 20:23:43 -080069
70 ~sp();
71
72 // Assignment
73
74 sp& operator = (T* other);
75 sp& operator = (const sp<T>& other);
John Reckd69089a2015-10-28 15:36:33 -070076 sp& operator = (sp<T>&& other);
Mathias Agopianb26ea8b2011-02-16 20:23:43 -080077
78 template<typename U> sp& operator = (const sp<U>& other);
John Reckd69089a2015-10-28 15:36:33 -070079 template<typename U> sp& operator = (sp<U>&& other);
Mathias Agopianb26ea8b2011-02-16 20:23:43 -080080 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
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800113// ---------------------------------------------------------------------------
114// No user serviceable parts below here.
115
116template<typename T>
117sp<T>::sp(T* other)
Mathias Agopian8db925f2013-05-09 13:04:32 -0700118 : m_ptr(other) {
119 if (other)
120 other->incStrong(this);
121}
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800122
123template<typename T>
124sp<T>::sp(const sp<T>& other)
Mathias Agopian8db925f2013-05-09 13:04:32 -0700125 : m_ptr(other.m_ptr) {
126 if (m_ptr)
127 m_ptr->incStrong(this);
128}
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800129
John Reckd69089a2015-10-28 15:36:33 -0700130template<typename T>
131sp<T>::sp(sp<T>&& other)
132 : m_ptr(other.m_ptr) {
133 other.m_ptr = nullptr;
134}
135
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800136template<typename T> template<typename U>
Mathias Agopian8db925f2013-05-09 13:04:32 -0700137sp<T>::sp(U* other)
138 : m_ptr(other) {
139 if (other)
140 ((T*) other)->incStrong(this);
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800141}
142
143template<typename T> template<typename U>
144sp<T>::sp(const sp<U>& other)
Mathias Agopian8db925f2013-05-09 13:04:32 -0700145 : m_ptr(other.m_ptr) {
146 if (m_ptr)
147 m_ptr->incStrong(this);
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800148}
149
John Reckd69089a2015-10-28 15:36:33 -0700150template<typename T> template<typename U>
151sp<T>::sp(sp<U>&& other)
152 : m_ptr(other.m_ptr) {
153 other.m_ptr = nullptr;
154}
155
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800156template<typename T>
Mathias Agopian8db925f2013-05-09 13:04:32 -0700157sp<T>::~sp() {
158 if (m_ptr)
159 m_ptr->decStrong(this);
160}
161
162template<typename T>
163sp<T>& sp<T>::operator =(const sp<T>& other) {
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800164 T* otherPtr(other.m_ptr);
Mathias Agopian8db925f2013-05-09 13:04:32 -0700165 if (otherPtr)
166 otherPtr->incStrong(this);
167 if (m_ptr)
168 m_ptr->decStrong(this);
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800169 m_ptr = otherPtr;
170 return *this;
171}
172
173template<typename T>
John Reckd69089a2015-10-28 15:36:33 -0700174sp<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
182template<typename T>
Mathias Agopian8db925f2013-05-09 13:04:32 -0700183sp<T>& sp<T>::operator =(T* other) {
184 if (other)
185 other->incStrong(this);
186 if (m_ptr)
187 m_ptr->decStrong(this);
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800188 m_ptr = other;
189 return *this;
190}
191
192template<typename T> template<typename U>
Mathias Agopian8db925f2013-05-09 13:04:32 -0700193sp<T>& sp<T>::operator =(const sp<U>& other) {
Mathias Agopian7332f802011-02-25 16:11:44 -0800194 T* otherPtr(other.m_ptr);
Mathias Agopian8db925f2013-05-09 13:04:32 -0700195 if (otherPtr)
196 otherPtr->incStrong(this);
197 if (m_ptr)
198 m_ptr->decStrong(this);
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800199 m_ptr = otherPtr;
200 return *this;
201}
202
203template<typename T> template<typename U>
John Reckd69089a2015-10-28 15:36:33 -0700204sp<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
212template<typename T> template<typename U>
Mathias Agopian8db925f2013-05-09 13:04:32 -0700213sp<T>& sp<T>::operator =(U* other) {
214 if (other)
215 ((T*) other)->incStrong(this);
216 if (m_ptr)
217 m_ptr->decStrong(this);
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800218 m_ptr = other;
219 return *this;
220}
221
Mathias Agopian8db925f2013-05-09 13:04:32 -0700222template<typename T>
223void sp<T>::force_set(T* other) {
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800224 other->forceIncStrong(this);
225 m_ptr = other;
226}
227
228template<typename T>
Mathias Agopian8db925f2013-05-09 13:04:32 -0700229void sp<T>::clear() {
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800230 if (m_ptr) {
231 m_ptr->decStrong(this);
232 m_ptr = 0;
233 }
234}
235
236template<typename T>
Mathias Agopian3e0f8752011-02-24 18:12:34 -0800237void sp<T>::set_pointer(T* ptr) {
238 m_ptr = ptr;
239}
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800240
Mathias Agopianb26ea8b2011-02-16 20:23:43 -0800241}; // namespace android
242
243// ---------------------------------------------------------------------------
244
245#endif // ANDROID_STRONG_POINTER_H