File indexing completed on 2024-09-08 09:37:12
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