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// --------------------------------------------------------------------------- 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 223