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// --------------------------------------------------------------------------- 27namespace android { 28 29template<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 58template<typename T> 59class sp { 60public: 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 100private: 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 112template<typename T> 113sp<T>::sp(T* other) 114 : m_ptr(other) { 115 if (other) 116 other->incStrong(this); 117} 118 119template<typename T> 120sp<T>::sp(const sp<T>& other) 121 : m_ptr(other.m_ptr) { 122 if (m_ptr) 123 m_ptr->incStrong(this); 124} 125 126template<typename T> template<typename U> 127sp<T>::sp(U* other) 128 : m_ptr(other) { 129 if (other) 130 ((T*) other)->incStrong(this); 131} 132 133template<typename T> template<typename U> 134sp<T>::sp(const sp<U>& other) 135 : m_ptr(other.m_ptr) { 136 if (m_ptr) 137 m_ptr->incStrong(this); 138} 139 140template<typename T> 141sp<T>::~sp() { 142 if (m_ptr) 143 m_ptr->decStrong(this); 144} 145 146template<typename T> 147sp<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 157template<typename T> 158sp<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 167template<typename T> template<typename U> 168sp<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 178template<typename T> template<typename U> 179sp<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 188template<typename T> 189void sp<T>::force_set(T* other) { 190 other->forceIncStrong(this); 191 m_ptr = other; 192} 193 194template<typename T> 195void sp<T>::clear() { 196 if (m_ptr) { 197 m_ptr->decStrong(this); 198 m_ptr = 0; 199 } 200} 201 202template<typename T> 203void 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