blob: 0f68615c7ee5afec5d999154e7c73a9e8d836e90 [file] [log] [blame]
Tim Murray89daad62013-07-29 14:30:02 -07001/*
2 * Copyright (C) 2013 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 RS_STRONG_POINTER_H
18#define RS_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 {
28namespace RSC {
29
30class TextOutput;
31TextOutput& printStrongPointer(TextOutput& to, const void* val);
32
33template<typename T> class wp;
34
35// ---------------------------------------------------------------------------
36
37#define COMPARE(_op_) \
38inline bool operator _op_ (const sp<T>& o) const { \
39 return m_ptr _op_ o.m_ptr; \
40} \
41inline bool operator _op_ (const T* o) const { \
42 return m_ptr _op_ o; \
43} \
44template<typename U> \
45inline bool operator _op_ (const sp<U>& o) const { \
46 return m_ptr _op_ o.m_ptr; \
47} \
48template<typename U> \
49inline bool operator _op_ (const U* o) const { \
50 return m_ptr _op_ o; \
51} \
52inline bool operator _op_ (const wp<T>& o) const { \
53 return m_ptr _op_ o.m_ptr; \
54} \
55template<typename U> \
56inline bool operator _op_ (const wp<U>& o) const { \
57 return m_ptr _op_ o.m_ptr; \
58}
59
60// ---------------------------------------------------------------------------
61
62template <typename T>
63class sp
64{
65public:
66 inline sp() : m_ptr(0) { }
67
68 sp(T* other);
69 sp(const sp<T>& other);
70 template<typename U> sp(U* other);
71 template<typename U> sp(const sp<U>& other);
72
73 ~sp();
74
75 // Assignment
76
77 sp& operator = (T* other);
78 sp& operator = (const sp<T>& other);
79
80 template<typename U> sp& operator = (const sp<U>& other);
81 template<typename U> sp& operator = (U* other);
82
83 //! Special optimization for use by ProcessState (and nobody else).
84 void force_set(T* other);
85
86 // Reset
87
88 void clear();
89
90 // Accessors
91
92 inline T& operator* () const { return *m_ptr; }
93 inline T* operator-> () const { return m_ptr; }
94 inline T* get() const { return m_ptr; }
95
96 // Operators
97
98 COMPARE(==)
99 COMPARE(!=)
100 COMPARE(>)
101 COMPARE(<)
102 COMPARE(<=)
103 COMPARE(>=)
104
105private:
106 template<typename Y> friend class sp;
107 template<typename Y> friend class wp;
108 void set_pointer(T* ptr);
109 T* m_ptr;
110};
111
112#undef COMPARE
113
114template <typename T>
115TextOutput& operator<<(TextOutput& to, const sp<T>& val);
116
117// ---------------------------------------------------------------------------
118// No user serviceable parts below here.
119
120template<typename T>
121sp<T>::sp(T* other)
122: m_ptr(other)
123 {
124 if (other) other->incStrong(this);
125 }
126
127template<typename T>
128sp<T>::sp(const sp<T>& other)
129: m_ptr(other.m_ptr)
130 {
131 if (m_ptr) m_ptr->incStrong(this);
132 }
133
134template<typename T> template<typename U>
135sp<T>::sp(U* other) : m_ptr(other)
136{
137 if (other) ((T*)other)->incStrong(this);
138}
139
140template<typename T> template<typename U>
141sp<T>::sp(const sp<U>& other)
142: m_ptr(other.m_ptr)
143 {
144 if (m_ptr) m_ptr->incStrong(this);
145 }
146
147template<typename T>
148sp<T>::~sp()
149{
150 if (m_ptr) m_ptr->decStrong(this);
151}
152
153template<typename T>
154sp<T>& sp<T>::operator = (const sp<T>& other) {
155 T* otherPtr(other.m_ptr);
156 if (otherPtr) otherPtr->incStrong(this);
157 if (m_ptr) m_ptr->decStrong(this);
158 m_ptr = otherPtr;
159 return *this;
160}
161
162template<typename T>
163sp<T>& sp<T>::operator = (T* other)
164{
165 if (other) other->incStrong(this);
166 if (m_ptr) m_ptr->decStrong(this);
167 m_ptr = other;
168 return *this;
169}
170
171template<typename T> template<typename U>
172sp<T>& sp<T>::operator = (const sp<U>& other)
173{
174 T* otherPtr(other.m_ptr);
175 if (otherPtr) otherPtr->incStrong(this);
176 if (m_ptr) m_ptr->decStrong(this);
177 m_ptr = otherPtr;
178 return *this;
179}
180
181template<typename T> template<typename U>
182sp<T>& sp<T>::operator = (U* other)
183{
184 if (other) ((T*)other)->incStrong(this);
185 if (m_ptr) m_ptr->decStrong(this);
186 m_ptr = other;
187 return *this;
188}
189
190template<typename T>
191void sp<T>::force_set(T* other)
192{
193 other->forceIncStrong(this);
194 m_ptr = other;
195}
196
197template<typename T>
198void sp<T>::clear()
199{
200 if (m_ptr) {
201 m_ptr->decStrong(this);
202 m_ptr = 0;
203 }
204}
205
206template<typename T>
207void sp<T>::set_pointer(T* ptr) {
208 m_ptr = ptr;
209}
210
211template <typename T>
212inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
213{
214 return printStrongPointer(to, val.get());
215}
216
217}; // namespace RSC
218}; // namespace android
219
220// ---------------------------------------------------------------------------
221
222#endif // RS_STRONG_POINTER_H