|  | /* | 
|  | * Copyright (C) 2005 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | #ifndef ANDROID_STRONG_POINTER_H | 
|  | #define ANDROID_STRONG_POINTER_H | 
|  |  | 
|  | #include <cutils/atomic.h> | 
|  |  | 
|  | #include <stdint.h> | 
|  | #include <sys/types.h> | 
|  | #include <stdlib.h> | 
|  |  | 
|  | // --------------------------------------------------------------------------- | 
|  | namespace android { | 
|  |  | 
|  | template<typename T> class wp; | 
|  |  | 
|  | // --------------------------------------------------------------------------- | 
|  |  | 
|  | #define COMPARE(_op_)                                           \ | 
|  | inline bool operator _op_ (const sp<T>& o) const {              \ | 
|  | return m_ptr _op_ o.m_ptr;                                  \ | 
|  | }                                                               \ | 
|  | inline bool operator _op_ (const T* o) const {                  \ | 
|  | return m_ptr _op_ o;                                        \ | 
|  | }                                                               \ | 
|  | template<typename U>                                            \ | 
|  | inline bool operator _op_ (const sp<U>& o) const {              \ | 
|  | return m_ptr _op_ o.m_ptr;                                  \ | 
|  | }                                                               \ | 
|  | template<typename U>                                            \ | 
|  | inline bool operator _op_ (const U* o) const {                  \ | 
|  | return m_ptr _op_ o;                                        \ | 
|  | }                                                               \ | 
|  | inline bool operator _op_ (const wp<T>& o) const {              \ | 
|  | return m_ptr _op_ o.m_ptr;                                  \ | 
|  | }                                                               \ | 
|  | template<typename U>                                            \ | 
|  | inline bool operator _op_ (const wp<U>& o) const {              \ | 
|  | return m_ptr _op_ o.m_ptr;                                  \ | 
|  | } | 
|  |  | 
|  | // --------------------------------------------------------------------------- | 
|  |  | 
|  | template<typename T> | 
|  | class sp { | 
|  | public: | 
|  | inline sp() : m_ptr(0) { } | 
|  |  | 
|  | sp(T* other); | 
|  | sp(const sp<T>& other); | 
|  | template<typename U> sp(U* other); | 
|  | template<typename U> sp(const sp<U>& other); | 
|  |  | 
|  | ~sp(); | 
|  |  | 
|  | // Assignment | 
|  |  | 
|  | sp& operator = (T* other); | 
|  | sp& operator = (const sp<T>& other); | 
|  |  | 
|  | template<typename U> sp& operator = (const sp<U>& other); | 
|  | template<typename U> sp& operator = (U* other); | 
|  |  | 
|  | //! Special optimization for use by ProcessState (and nobody else). | 
|  | void force_set(T* other); | 
|  |  | 
|  | // Reset | 
|  |  | 
|  | void clear(); | 
|  |  | 
|  | // Accessors | 
|  |  | 
|  | inline  T&      operator* () const  { return *m_ptr; } | 
|  | inline  T*      operator-> () const { return m_ptr;  } | 
|  | inline  T*      get() const         { return m_ptr; } | 
|  |  | 
|  | // Operators | 
|  |  | 
|  | COMPARE(==) | 
|  | COMPARE(!=) | 
|  | COMPARE(>) | 
|  | COMPARE(<) | 
|  | COMPARE(<=) | 
|  | COMPARE(>=) | 
|  |  | 
|  | private: | 
|  | template<typename Y> friend class sp; | 
|  | template<typename Y> friend class wp; | 
|  | void set_pointer(T* ptr); | 
|  | T* m_ptr; | 
|  | }; | 
|  |  | 
|  | #undef COMPARE | 
|  |  | 
|  | // --------------------------------------------------------------------------- | 
|  | // No user serviceable parts below here. | 
|  |  | 
|  | template<typename T> | 
|  | sp<T>::sp(T* other) | 
|  | : m_ptr(other) { | 
|  | if (other) | 
|  | other->incStrong(this); | 
|  | } | 
|  |  | 
|  | template<typename T> | 
|  | sp<T>::sp(const sp<T>& other) | 
|  | : m_ptr(other.m_ptr) { | 
|  | if (m_ptr) | 
|  | m_ptr->incStrong(this); | 
|  | } | 
|  |  | 
|  | template<typename T> template<typename U> | 
|  | sp<T>::sp(U* other) | 
|  | : m_ptr(other) { | 
|  | if (other) | 
|  | ((T*) other)->incStrong(this); | 
|  | } | 
|  |  | 
|  | template<typename T> template<typename U> | 
|  | sp<T>::sp(const sp<U>& other) | 
|  | : m_ptr(other.m_ptr) { | 
|  | if (m_ptr) | 
|  | m_ptr->incStrong(this); | 
|  | } | 
|  |  | 
|  | template<typename T> | 
|  | sp<T>::~sp() { | 
|  | if (m_ptr) | 
|  | m_ptr->decStrong(this); | 
|  | } | 
|  |  | 
|  | template<typename T> | 
|  | sp<T>& sp<T>::operator =(const sp<T>& other) { | 
|  | T* otherPtr(other.m_ptr); | 
|  | if (otherPtr) | 
|  | otherPtr->incStrong(this); | 
|  | if (m_ptr) | 
|  | m_ptr->decStrong(this); | 
|  | m_ptr = otherPtr; | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | template<typename T> | 
|  | sp<T>& sp<T>::operator =(T* other) { | 
|  | if (other) | 
|  | other->incStrong(this); | 
|  | if (m_ptr) | 
|  | m_ptr->decStrong(this); | 
|  | m_ptr = other; | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | template<typename T> template<typename U> | 
|  | sp<T>& sp<T>::operator =(const sp<U>& other) { | 
|  | T* otherPtr(other.m_ptr); | 
|  | if (otherPtr) | 
|  | otherPtr->incStrong(this); | 
|  | if (m_ptr) | 
|  | m_ptr->decStrong(this); | 
|  | m_ptr = otherPtr; | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | template<typename T> template<typename U> | 
|  | sp<T>& sp<T>::operator =(U* other) { | 
|  | if (other) | 
|  | ((T*) other)->incStrong(this); | 
|  | if (m_ptr) | 
|  | m_ptr->decStrong(this); | 
|  | m_ptr = other; | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | template<typename T> | 
|  | void sp<T>::force_set(T* other) { | 
|  | other->forceIncStrong(this); | 
|  | m_ptr = other; | 
|  | } | 
|  |  | 
|  | template<typename T> | 
|  | void sp<T>::clear() { | 
|  | if (m_ptr) { | 
|  | m_ptr->decStrong(this); | 
|  | m_ptr = 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | template<typename T> | 
|  | void sp<T>::set_pointer(T* ptr) { | 
|  | m_ptr = ptr; | 
|  | } | 
|  |  | 
|  | }; // namespace android | 
|  |  | 
|  | // --------------------------------------------------------------------------- | 
|  |  | 
|  | #endif // ANDROID_STRONG_POINTER_H |