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