1 /* 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 // --------------------------------------------------------------------------- 27 namespace android { 28 29 template<typename T> class wp; 30 31 // --------------------------------------------------------------------------- 32 33 #define COMPARE(_op_) \ 34 inline bool operator _op_ (const sp<T>& o) const { \ 35 return m_ptr _op_ o.m_ptr; \ 36 } \ 37 inline bool operator _op_ (const T* o) const { \ 38 return m_ptr _op_ o; \ 39 } \ 40 template<typename U> \ 41 inline bool operator _op_ (const sp<U>& o) const { \ 42 return m_ptr _op_ o.m_ptr; \ 43 } \ 44 template<typename U> \ 45 inline bool operator _op_ (const U* o) const { \ 46 return m_ptr _op_ o; \ 47 } \ 48 inline bool operator _op_ (const wp<T>& o) const { \ 49 return m_ptr _op_ o.m_ptr; \ 50 } \ 51 template<typename U> \ 52 inline bool operator _op_ (const wp<U>& o) const { \ 53 return m_ptr _op_ o.m_ptr; \ 54 } 55 56 // --------------------------------------------------------------------------- 57 58 template<typename T> 59 class sp { 60 public: 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 100 private: 101 template<typename Y> friend class sp; 102 template<typename Y> friend class wp; 103 void set_pointer(T* ptr); 104 T* m_ptr; 105 }; 106 107 #undef COMPARE 108 109 // --------------------------------------------------------------------------- 110 // No user serviceable parts below here. 111 112 template<typename T> 113 sp<T>::sp(T* other) 114 : m_ptr(other) { 115 if (other) 116 other->incStrong(this); 117 } 118 119 template<typename T> 120 sp<T>::sp(const sp<T>& other) 121 : m_ptr(other.m_ptr) { 122 if (m_ptr) 123 m_ptr->incStrong(this); 124 } 125 126 template<typename T> template<typename U> 127 sp<T>::sp(U* other) 128 : m_ptr(other) { 129 if (other) 130 ((T*) other)->incStrong(this); 131 } 132 133 template<typename T> template<typename U> 134 sp<T>::sp(const sp<U>& other) 135 : m_ptr(other.m_ptr) { 136 if (m_ptr) 137 m_ptr->incStrong(this); 138 } 139 140 template<typename T> 141 sp<T>::~sp() { 142 if (m_ptr) 143 m_ptr->decStrong(this); 144 } 145 146 template<typename T> 147 sp<T>& sp<T>::operator =(const sp<T>& other) { 148 T* otherPtr(other.m_ptr); 149 if (otherPtr) 150 otherPtr->incStrong(this); 151 if (m_ptr) 152 m_ptr->decStrong(this); 153 m_ptr = otherPtr; 154 return *this; 155 } 156 157 template<typename T> 158 sp<T>& sp<T>::operator =(T* other) { 159 if (other) 160 other->incStrong(this); 161 if (m_ptr) 162 m_ptr->decStrong(this); 163 m_ptr = other; 164 return *this; 165 } 166 167 template<typename T> template<typename U> 168 sp<T>& sp<T>::operator =(const sp<U>& other) { 169 T* otherPtr(other.m_ptr); 170 if (otherPtr) 171 otherPtr->incStrong(this); 172 if (m_ptr) 173 m_ptr->decStrong(this); 174 m_ptr = otherPtr; 175 return *this; 176 } 177 178 template<typename T> template<typename U> 179 sp<T>& sp<T>::operator =(U* other) { 180 if (other) 181 ((T*) other)->incStrong(this); 182 if (m_ptr) 183 m_ptr->decStrong(this); 184 m_ptr = other; 185 return *this; 186 } 187 188 template<typename T> 189 void sp<T>::force_set(T* other) { 190 other->forceIncStrong(this); 191 m_ptr = other; 192 } 193 194 template<typename T> 195 void sp<T>::clear() { 196 if (m_ptr) { 197 m_ptr->decStrong(this); 198 m_ptr = 0; 199 } 200 } 201 202 template<typename T> 203 void sp<T>::set_pointer(T* ptr) { 204 m_ptr = ptr; 205 } 206 207 }; // namespace android 208 209 // --------------------------------------------------------------------------- 210 211 #endif // ANDROID_STRONG_POINTER_H 212