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); 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; } 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)121sp<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)128sp<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)135sp<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)141sp<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()148sp<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)191void sp<T>::force_set(T* other) 192 { 193 other->forceIncStrong(this); 194 m_ptr = other; 195 } 196 197 template<typename T> clear()198void 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)207void 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