File indexing completed on 2024-05-12 15:43:39

0001 /*
0002  *  Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
0003  *
0004  *  This library is free software; you can redistribute it and/or
0005  *  modify it under the terms of the GNU Library General Public
0006  *  License as published by the Free Software Foundation; either
0007  *  version 2 of the License, or (at your option) any later version.
0008  *
0009  *  This library is distributed in the hope that it will be useful,
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012  *  Library General Public License for more details.
0013  *
0014  *  You should have received a copy of the GNU Library General Public License
0015  *  along with this library; see the file COPYING.LIB.  If not, write to
0016  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  *  Boston, MA 02110-1301, USA.
0018  *
0019  */
0020 
0021 #ifndef WTF_RefPtr_h
0022 #define WTF_RefPtr_h
0023 
0024 #include <algorithm>
0025 #include <wtf/AlwaysInline.h>
0026 #include <wtf/PassRefPtr.h>
0027 
0028 namespace WTF
0029 {
0030 
0031 enum PlacementNewAdoptType { PlacementNewAdopt };
0032 
0033 template <typename T> class PassRefPtr;
0034 
0035 enum HashTableDeletedValueType { HashTableDeletedValue };
0036 
0037 template <typename T> class RefPtr
0038 {
0039 public:
0040     RefPtr() : m_ptr(nullptr) { }
0041     RefPtr(T *ptr) : m_ptr(ptr)
0042     {
0043         if (ptr) {
0044             ptr->ref();
0045         }
0046     }
0047     RefPtr(const RefPtr &o) : m_ptr(o.m_ptr)
0048     {
0049         if (T *ptr = m_ptr) {
0050             ptr->ref();
0051         }
0052     }
0053     // see comment in PassRefPtr.h for why this takes const reference
0054     template <typename U> RefPtr(const PassRefPtr<U> &);
0055 
0056     // Special constructor for cases where we overwrite an object in place.
0057     RefPtr(PlacementNewAdoptType) { }
0058 
0059     // Hash table deleted values, which are only constructed and never copied or destroyed.
0060     RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
0061     bool isHashTableDeletedValue() const
0062     {
0063         return m_ptr == hashTableDeletedValue();
0064     }
0065 
0066     ~RefPtr()
0067     {
0068         if (T *ptr = m_ptr) {
0069             ptr->deref();
0070         }
0071     }
0072 
0073     template <typename U> RefPtr(const RefPtr<U> &o) : m_ptr(o.get())
0074     {
0075         if (T *ptr = m_ptr) {
0076             ptr->ref();
0077         }
0078     }
0079 
0080     T *get() const
0081     {
0082         return m_ptr;
0083     }
0084 
0085     void clear()
0086     {
0087         if (T *ptr = m_ptr) {
0088             ptr->deref();
0089         } m_ptr = nullptr;
0090     }
0091     PassRefPtr<T> release()
0092     {
0093         PassRefPtr<T> tmp = adoptRef(m_ptr);
0094         m_ptr = nullptr;
0095         return tmp;
0096     }
0097 
0098     T &operator*() const
0099     {
0100         return *m_ptr;
0101     }
0102     ALWAYS_INLINE T *operator->() const
0103     {
0104         return m_ptr;
0105     }
0106 
0107     bool operator!() const
0108     {
0109         return !m_ptr;
0110     }
0111 
0112     // This conversion operator allows implicit conversion to bool but not to other integer types.
0113     typedef T *RefPtr::*UnspecifiedBoolType;
0114     operator UnspecifiedBoolType() const
0115     {
0116         return m_ptr ? &RefPtr::m_ptr : nullptr;
0117     }
0118 
0119     RefPtr &operator=(const RefPtr &);
0120     RefPtr &operator=(T *);
0121     RefPtr &operator=(const PassRefPtr<T> &);
0122     template <typename U> RefPtr &operator=(const RefPtr<U> &);
0123     template <typename U> RefPtr &operator=(const PassRefPtr<U> &);
0124 
0125     void swap(RefPtr &);
0126 
0127 private:
0128     static T *hashTableDeletedValue()
0129     {
0130         return reinterpret_cast<T *>(-1);
0131     }
0132 
0133     T *m_ptr;
0134 };
0135 
0136 template <typename T> template <typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U> &o)
0137     : m_ptr(o.releaseRef())
0138 {
0139 }
0140 
0141 template <typename T> inline RefPtr<T> &RefPtr<T>::operator=(const RefPtr<T> &o)
0142 {
0143     T *optr = o.get();
0144     if (optr) {
0145         optr->ref();
0146     }
0147     T *ptr = m_ptr;
0148     m_ptr = optr;
0149     if (ptr) {
0150         ptr->deref();
0151     }
0152     return *this;
0153 }
0154 
0155 template <typename T> template <typename U> inline RefPtr<T> &RefPtr<T>::operator=(const RefPtr<U> &o)
0156 {
0157     T *optr = o.get();
0158     if (optr) {
0159         optr->ref();
0160     }
0161     T *ptr = m_ptr;
0162     m_ptr = optr;
0163     if (ptr) {
0164         ptr->deref();
0165     }
0166     return *this;
0167 }
0168 
0169 template <typename T> inline RefPtr<T> &RefPtr<T>::operator=(T *optr)
0170 {
0171     if (optr) {
0172         optr->ref();
0173     }
0174     T *ptr = m_ptr;
0175     m_ptr = optr;
0176     if (ptr) {
0177         ptr->deref();
0178     }
0179     return *this;
0180 }
0181 
0182 template <typename T> inline RefPtr<T> &RefPtr<T>::operator=(const PassRefPtr<T> &o)
0183 {
0184     T *ptr = m_ptr;
0185     m_ptr = o.releaseRef();
0186     if (ptr) {
0187         ptr->deref();
0188     }
0189     return *this;
0190 }
0191 
0192 template <typename T> template <typename U> inline RefPtr<T> &RefPtr<T>::operator=(const PassRefPtr<U> &o)
0193 {
0194     T *ptr = m_ptr;
0195     m_ptr = o.releaseRef();
0196     if (ptr) {
0197         ptr->deref();
0198     }
0199     return *this;
0200 }
0201 
0202 template <class T> inline void RefPtr<T>::swap(RefPtr<T> &o)
0203 {
0204     std::swap(m_ptr, o.m_ptr);
0205 }
0206 
0207 template <class T> inline void swap(RefPtr<T> &a, RefPtr<T> &b)
0208 {
0209     a.swap(b);
0210 }
0211 
0212 template <typename T, typename U> inline bool operator==(const RefPtr<T> &a, const RefPtr<U> &b)
0213 {
0214     return a.get() == b.get();
0215 }
0216 
0217 template <typename T, typename U> inline bool operator==(const RefPtr<T> &a, U *b)
0218 {
0219     return a.get() == b;
0220 }
0221 
0222 template <typename T, typename U> inline bool operator==(T *a, const RefPtr<U> &b)
0223 {
0224     return a == b.get();
0225 }
0226 
0227 template <typename T, typename U> inline bool operator!=(const RefPtr<T> &a, const RefPtr<U> &b)
0228 {
0229     return a.get() != b.get();
0230 }
0231 
0232 template <typename T, typename U> inline bool operator!=(const RefPtr<T> &a, U *b)
0233 {
0234     return a.get() != b;
0235 }
0236 
0237 template <typename T, typename U> inline bool operator!=(T *a, const RefPtr<U> &b)
0238 {
0239     return a != b.get();
0240 }
0241 
0242 template <typename T, typename U> inline RefPtr<T> static_pointer_cast(const RefPtr<U> &p)
0243 {
0244     return RefPtr<T>(static_cast<T *>(p.get()));
0245 }
0246 
0247 template <typename T, typename U> inline RefPtr<T> const_pointer_cast(const RefPtr<U> &p)
0248 {
0249     return RefPtr<T>(const_cast<T *>(p.get()));
0250 }
0251 
0252 template <typename T> inline T *getPtr(const RefPtr<T> &p)
0253 {
0254     return p.get();
0255 }
0256 
0257 } // namespace WTF
0258 
0259 using WTF::RefPtr;
0260 using WTF::static_pointer_cast;
0261 using WTF::const_pointer_cast;
0262 
0263 #endif // WTF_RefPtr_h