1 /*
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 // ---------------------------------------------------------------------------
27 namespace android {
28 namespace RSC {
29 
30 class TextOutput;
31 TextOutput& printStrongPointer(TextOutput& to, const void* val);
32 
33 template<typename T> class wp;
34 
35 // ---------------------------------------------------------------------------
36 
37 #define COMPARE(_op_)                                           \
38 inline bool operator _op_ (const sp<T>& o) const {              \
39     return m_ptr _op_ o.m_ptr;                                  \
40 }                                                               \
41 inline bool operator _op_ (const T* o) const {                  \
42     return m_ptr _op_ o;                                        \
43 }                                                               \
44 template<typename U>                                            \
45 inline bool operator _op_ (const sp<U>& o) const {              \
46     return m_ptr _op_ o.m_ptr;                                  \
47 }                                                               \
48 template<typename U>                                            \
49 inline bool operator _op_ (const U* o) const {                  \
50     return m_ptr _op_ o;                                        \
51 }                                                               \
52 inline bool operator _op_ (const wp<T>& o) const {              \
53     return m_ptr _op_ o.m_ptr;                                  \
54 }                                                               \
55 template<typename U>                                            \
56 inline bool operator _op_ (const wp<U>& o) const {              \
57     return m_ptr _op_ o.m_ptr;                                  \
58 }
59 
60 // ---------------------------------------------------------------------------
61 
62 template <typename T>
63 class sp
64 {
65 public:
sp()66     inline sp() : m_ptr(0) { }
67 
68     sp(T* other);  // NOLINT, implicit
69     sp(const sp<T>& other);
70     template<typename U> sp(U* other);  // NOLINT, implicit
71     template<typename U> sp(const sp<U>& other);  // NOLINT, implicit
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;  }
get()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 
105 private:
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 
114 template <typename T>
115 TextOutput& operator<<(TextOutput& to, const sp<T>& val);
116 
117 // ---------------------------------------------------------------------------
118 // No user serviceable parts below here.
119 
120 template<typename T>
sp(T * other)121 sp<T>::sp(T* other)
122 : m_ptr(other)
123   {
124     if (other) other->incStrong(this);
125   }
126 
127 template<typename T>
sp(const sp<T> & other)128 sp<T>::sp(const sp<T>& other)
129 : m_ptr(other.m_ptr)
130   {
131     if (m_ptr) m_ptr->incStrong(this);
132   }
133 
134 template<typename T> template<typename U>
sp(U * other)135 sp<T>::sp(U* other) : m_ptr(other)
136 {
137     if (other) ((T*)other)->incStrong(this);
138 }
139 
140 template<typename T> template<typename U>
sp(const sp<U> & other)141 sp<T>::sp(const sp<U>& other)
142 : m_ptr(other.m_ptr)
143   {
144     if (m_ptr) m_ptr->incStrong(this);
145   }
146 
147 template<typename T>
~sp()148 sp<T>::~sp()
149 {
150     if (m_ptr) m_ptr->decStrong(this);
151 }
152 
153 template<typename T>
154 sp<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 
162 template<typename T>
163 sp<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 
171 template<typename T> template<typename U>
172 sp<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 
181 template<typename T> template<typename U>
182 sp<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 
190 template<typename T>
force_set(T * other)191 void sp<T>::force_set(T* other)
192 {
193     other->forceIncStrong(this);
194     m_ptr = other;
195 }
196 
197 template<typename T>
clear()198 void sp<T>::clear()
199 {
200     if (m_ptr) {
201         m_ptr->decStrong(this);
202         m_ptr = 0;
203     }
204 }
205 
206 template<typename T>
set_pointer(T * ptr)207 void sp<T>::set_pointer(T* ptr) {
208     m_ptr = ptr;
209 }
210 
211 template <typename T>
212 inline 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
223