/* This file is part of the DOM implementation for KDE. Copyright (C) 2005, 2006 Apple Computer, Inc. Copyright (C) 2002 Lars Knoll This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SHARED_H #define SHARED_H namespace tdehtml { template class Shared { public: Shared() { _ref=0; /*counter++;*/ } ~Shared() { /*counter--;*/ } void ref() { _ref++; } void deref() { if(_ref) _ref--; if(!_ref) delete static_cast(this); } bool hasOneRef() { //kdDebug(300) << "ref=" << _ref << endl; return _ref==1; } int refCount() const { return _ref; } // static int counter; protected: unsigned int _ref; }; template class TreeShared { public: TreeShared() { _ref = 0; m_parent = 0; /*counter++;*/ } TreeShared( type *parent ) { _ref=0; m_parent = parent; /*counter++;*/ } ~TreeShared() { /*counter--;*/ } virtual void removedLastRef() { delete static_cast(this); } void ref() { _ref++; } void deref() { if(_ref) _ref--; if(!_ref && !m_parent) { removedLastRef(); } } bool hasOneRef() { //kdDebug(300) << "ref=" << _ref << endl; return _ref==1; } int refCount() const { return _ref; } // static int counter; void setParent(type *parent) { m_parent = parent; } type *parent() const { return m_parent; } private: unsigned int _ref; protected: type *m_parent; }; template class SharedPtr; template bool operator==(const SharedPtr &a, const SharedPtr &b); template bool operator==(const SharedPtr &a, const T *b); template bool operator==(const T *a, const SharedPtr &b); template class SharedPtr { public: SharedPtr() : m_ptr(0) {} explicit SharedPtr(T *ptr) : m_ptr(ptr) { if (m_ptr) m_ptr->ref(); } SharedPtr(const SharedPtr &o) : m_ptr(o.m_ptr) { if (m_ptr) m_ptr->ref(); } ~SharedPtr() { if (m_ptr) m_ptr->deref(); } bool isNull() const { return m_ptr == 0; } bool notNull() const { return m_ptr != 0; } void reset() { if (m_ptr) m_ptr->deref(); m_ptr = 0; } void reset(T *o) { if (o) o->ref(); if (m_ptr) m_ptr->deref(); m_ptr = o; } T * get() const { return m_ptr; } T &operator*() const { return *m_ptr; } T *operator->() const { return m_ptr; } bool operator!() const { return m_ptr == 0; } template friend bool operator==(const SharedPtr &a, const SharedPtr &b); template friend bool operator==(const SharedPtr &a, const C *b); template friend bool operator==(const C *a, const SharedPtr &b); SharedPtr &operator=(const SharedPtr &); private: T* m_ptr; }; template SharedPtr &SharedPtr::operator=(const SharedPtr &o) { if (o.m_ptr) o.m_ptr->ref(); if (m_ptr) m_ptr->deref(); m_ptr = o.m_ptr; return *this; } template inline bool operator==(const SharedPtr &a, const SharedPtr &b) { return a.m_ptr == b.m_ptr; } template inline bool operator==(const SharedPtr &a, const T *b) { return a.m_ptr == b; } template inline bool operator==(const T *a, const SharedPtr &b) { return a == b.m_ptr; } template inline bool operator!=(const SharedPtr &a, const SharedPtr &b) { return !(a==b); } template inline bool operator!=(const SharedPtr &a, const T *b) { return !(a == b); } template inline bool operator!=(const T *a, const SharedPtr &b) { return !(a == b); } template inline SharedPtr static_pointer_cast(const SharedPtr &p) { return SharedPtr(static_cast(p.get())); } template inline SharedPtr const_pointer_cast(const SharedPtr &p) { return SharedPtr(const_cast(p.get())); } //A special pointer for nodes keeping track of the document, //which helps distinguish back links from them to it, in order to break //cycles template class DocPtr { public: DocPtr() : m_ptr(0) {} DocPtr(T *ptr) : m_ptr(ptr) { if (ptr) ptr->selfOnlyRef(); } DocPtr(const DocPtr &o) : m_ptr(o.m_ptr) { if (T *ptr = m_ptr) ptr->selfOnlyRef(); } ~DocPtr() { if (T *ptr = m_ptr) ptr->selfOnlyDeref(); } template DocPtr(const DocPtr &o) : m_ptr(o.get()) { if (T *ptr = m_ptr) ptr->selfOnlyRef(); } void resetSkippingRef(T *o) { m_ptr = o; } T *get() const { return m_ptr; } T &operator*() const { return *m_ptr; } T *operator->() const { return m_ptr; } bool operator!() const { return !m_ptr; } // this type conversion operator allows implicit conversion to // bool but not to other integer types typedef T * (DocPtr::*UnspecifiedBoolType)() const; operator UnspecifiedBoolType() const { return m_ptr ? &DocPtr::get : 0; } DocPtr &operator=(const DocPtr &); DocPtr &operator=(T *); private: T *m_ptr; }; template DocPtr &DocPtr::operator=(const DocPtr &o) { T *optr = o.m_ptr; if (optr) optr->selfOnlyRef(); if (T *ptr = m_ptr) ptr->selfOnlyDeref(); m_ptr = optr; return *this; } template inline DocPtr &DocPtr::operator=(T *optr) { if (optr) optr->selfOnlyRef(); if (T *ptr = m_ptr) ptr->selfOnlyDeref(); m_ptr = optr; return *this; } template inline bool operator==(const DocPtr &a, const DocPtr &b) { return a.get() == b.get(); } template inline bool operator==(const DocPtr &a, const T *b) { return a.get() == b; } template inline bool operator==(const T *a, const DocPtr &b) { return a == b.get(); } template inline bool operator!=(const DocPtr &a, const DocPtr &b) { return a.get() != b.get(); } template inline bool operator!=(const DocPtr &a, const T *b) { return a.get() != b; } template inline bool operator!=(const T *a, const DocPtr &b) { return a != b.get(); } } // namespace #endif