File indexing completed on 2024-04-28 15:23:47

0001 /*
0002  * This file is part of the DOM implementation for KDE.
0003  * Copyright (C) 2005, 2006 Apple Computer, Inc.
0004  * Copyright (C) 2002 Lars Knoll <knoll@kde.org>
0005  *
0006  * This library is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU Library General Public
0008  * License as published by the Free Software Foundation; either
0009  * version 2 of the License, or (at your option) any later version.
0010  *
0011  * This library is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014  * Library General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU Library General Public License
0017  * along with this library; see the file COPYING.LIB.  If not, write to
0018  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019  * Boston, MA 02110-1301, USA.
0020  *
0021  */
0022 
0023 #ifndef SHARED_H
0024 #define SHARED_H
0025 
0026 #include <wtf/SharedPtr.h>
0027 
0028 namespace khtml
0029 {
0030 
0031 template<class type> class Shared
0032 {
0033 public:
0034     Shared()
0035     {
0036         _ref = 0; /*counter++;*/
0037     }
0038     ~Shared()
0039     {
0040         /*counter--;*/
0041     }
0042 
0043     void ref()
0044     {
0045         _ref++;
0046     }
0047     void deref()
0048     {
0049         if (_ref) {
0050             _ref--;
0051         }
0052         if (!_ref) {
0053             delete static_cast<type *>(this);
0054         }
0055     }
0056     bool hasOneRef()   //qCDebug(KHTML_LOG) << "ref=" << _ref;
0057     {
0058         return _ref == 1;
0059     }
0060 
0061     int refCount() const
0062     {
0063         return _ref;
0064     }
0065 //    static int counter;
0066 protected:
0067     unsigned int _ref;
0068 
0069 private:
0070     //Avoid the automatic copy constructor
0071     Shared(const Shared &);
0072     Shared &operator= (const Shared &);
0073 };
0074 
0075 template<class type> class TreeShared
0076 {
0077 public:
0078     TreeShared()
0079     {
0080         _ref = 0;
0081         m_parent = nullptr; /*counter++;*/
0082     }
0083     TreeShared(type *parent)
0084     {
0085         _ref = 0;
0086         m_parent = parent; /*counter++;*/
0087     }
0088     virtual ~TreeShared()
0089     {
0090         /*counter--;*/
0091     }
0092 
0093     virtual void removedLastRef()
0094     {
0095         delete static_cast<type *>(this);
0096     }
0097 
0098     void ref()
0099     {
0100         _ref++;
0101     }
0102     void deref()
0103     {
0104         if (_ref) {
0105             _ref--;
0106         }
0107         if (!_ref && !m_parent) {
0108             removedLastRef();
0109         }
0110     }
0111 
0112     // This method decreases the reference count, but never deletes the object.
0113     // It should be used when a method may be passed something with the initial
0114     // reference count of 0, but still needs to guard it.
0115     void derefOnly()
0116     {
0117         _ref--;
0118     }
0119 
0120     bool hasOneRef()   //qCDebug(KHTML_LOG) << "ref=" << _ref;
0121     {
0122         return _ref == 1;
0123     }
0124 
0125     int refCount() const
0126     {
0127         return _ref;
0128     }
0129 //    static int counter;
0130 
0131     void setParent(type *parent)
0132     {
0133         m_parent = parent;
0134     }
0135     type *parent() const
0136     {
0137         return m_parent;
0138     }
0139 private:
0140     //Avoid the automatic copy constructor
0141     TreeShared(const TreeShared &);
0142     TreeShared &operator= (const TreeShared &);
0143 
0144     unsigned int _ref;
0145 protected:
0146     type *m_parent;
0147 };
0148 
0149 //A special pointer for nodes keeping track of the document,
0150 //which helps distinguish back links from them to it, in order to break
0151 //cycles
0152 template <class T> class DocPtr
0153 {
0154 public:
0155     DocPtr() : m_ptr(0) {}
0156     DocPtr(T *ptr) : m_ptr(ptr)
0157     {
0158         if (ptr) {
0159             ptr->selfOnlyRef();
0160         }
0161     }
0162     DocPtr(const DocPtr &o) : m_ptr(o.m_ptr)
0163     {
0164         if (T *ptr = m_ptr) {
0165             ptr->selfOnlyRef();
0166         }
0167     }
0168     ~DocPtr()
0169     {
0170         if (T *ptr = m_ptr) {
0171             ptr->selfOnlyDeref();
0172         }
0173     }
0174 
0175     template <class U> DocPtr(const DocPtr<U> &o) : m_ptr(o.get())
0176     {
0177         if (T *ptr = m_ptr) {
0178             ptr->selfOnlyRef();
0179         }
0180     }
0181 
0182     void resetSkippingRef(T *o)
0183     {
0184         m_ptr = o;
0185     }
0186 
0187     T *get() const
0188     {
0189         return m_ptr;
0190     }
0191 
0192     T &operator*() const
0193     {
0194         return *m_ptr;
0195     }
0196     T *operator->() const
0197     {
0198         return m_ptr;
0199     }
0200 
0201     bool operator!() const
0202     {
0203         return !m_ptr;
0204     }
0205 
0206     // this type conversion operator allows implicit conversion to
0207     // bool but not to other integer types
0208 
0209     typedef T *(DocPtr::*UnspecifiedBoolType)() const;
0210     operator UnspecifiedBoolType() const
0211     {
0212         return m_ptr ? &DocPtr::get : nullptr;
0213     }
0214 
0215     DocPtr &operator=(const DocPtr &);
0216     DocPtr &operator=(T *);
0217 
0218 private:
0219     T *m_ptr;
0220 };
0221 
0222 template <class T> DocPtr<T> &DocPtr<T>::operator=(const DocPtr<T> &o)
0223 {
0224     T *optr = o.m_ptr;
0225     if (optr) {
0226         optr->selfOnlyRef();
0227     }
0228     if (T *ptr = m_ptr) {
0229         ptr->selfOnlyDeref();
0230     }
0231     m_ptr = optr;
0232     return *this;
0233 }
0234 
0235 template <class T> inline DocPtr<T> &DocPtr<T>::operator=(T *optr)
0236 {
0237     if (optr) {
0238         optr->selfOnlyRef();
0239     }
0240     if (T *ptr = m_ptr) {
0241         ptr->selfOnlyDeref();
0242     }
0243     m_ptr = optr;
0244     return *this;
0245 }
0246 
0247 template <class T> inline bool operator==(const DocPtr<T> &a, const DocPtr<T> &b)
0248 {
0249     return a.get() == b.get();
0250 }
0251 
0252 template <class T> inline bool operator==(const DocPtr<T> &a, const T *b)
0253 {
0254     return a.get() == b;
0255 }
0256 
0257 template <class T> inline bool operator==(const T *a, const DocPtr<T> &b)
0258 {
0259     return a == b.get();
0260 }
0261 
0262 template <class T> inline bool operator!=(const DocPtr<T> &a, const DocPtr<T> &b)
0263 {
0264     return a.get() != b.get();
0265 }
0266 
0267 template <class T> inline bool operator!=(const DocPtr<T> &a, const T *b)
0268 {
0269     return a.get() != b;
0270 }
0271 
0272 template <class T> inline bool operator!=(const T *a, const DocPtr<T> &b)
0273 {
0274     return a != b.get();
0275 }
0276 
0277 } // namespace
0278 
0279 #endif