blob: 74cd0ead4b6d6966e71c0de7402fdb73e6041319 [file] [log] [blame]
mjscff5e5e2005-09-27 22:37:33 +00001/*
darin@apple.com3beb3002008-04-28 05:59:07 +00002 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
mjscff5e5e2005-09-27 22:37:33 +00003 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
mjscdff33b2006-01-23 21:41:36 +000016 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
mjscff5e5e2005-09-27 22:37:33 +000017 * Boston, MA 02110-1301, USA.
18 *
19 */
20
mjs98cf6e02006-10-19 02:42:55 +000021#ifndef WTF_RefPtr_h
22#define WTF_RefPtr_h
mjscff5e5e2005-09-27 22:37:33 +000023
mjsc9743bc2005-12-23 07:35:00 +000024#include <algorithm>
mjs098cbb42007-10-26 11:46:13 +000025#include "AlwaysInline.h"
eric@webkit.orgbb2a34f2009-06-24 07:53:10 +000026#include "FastAllocBase.h"
mjsc9743bc2005-12-23 07:35:00 +000027
mjsbb863512006-05-09 09:27:55 +000028namespace WTF {
mjscff5e5e2005-09-27 22:37:33 +000029
darina51e5e72007-10-29 04:37:37 +000030 enum PlacementNewAdoptType { PlacementNewAdopt };
31
darine4818f82005-12-22 16:48:08 +000032 template <typename T> class PassRefPtr;
mjs97e2b182005-12-06 09:21:15 +000033
darin@apple.com3beb3002008-04-28 05:59:07 +000034 enum HashTableDeletedValueType { HashTableDeletedValue };
35
eric@webkit.orgbb2a34f2009-06-24 07:53:10 +000036 template <typename T> class RefPtr : public FastAllocBase {
mjscff5e5e2005-09-27 22:37:33 +000037 public:
darin@apple.com3beb3002008-04-28 05:59:07 +000038 RefPtr() : m_ptr(0) { }
darin@apple.com5e49bae2007-12-21 21:54:51 +000039 RefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
40 RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) ptr->ref(); }
mjs1aec3582005-12-25 09:22:35 +000041 // see comment in PassRefPtr.h for why this takes const reference
42 template <typename U> RefPtr(const PassRefPtr<U>&);
mjs97e2b182005-12-06 09:21:15 +000043
darina51e5e72007-10-29 04:37:37 +000044 // Special constructor for cases where we overwrite an object in place.
45 RefPtr(PlacementNewAdoptType) { }
46
darin@apple.com3beb3002008-04-28 05:59:07 +000047 // Hash table deleted values, which are only constructed and never copied or destroyed.
48 RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
49 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
50
darin@apple.com5e49bae2007-12-21 21:54:51 +000051 ~RefPtr() { if (T* ptr = m_ptr) ptr->deref(); }
mjscff5e5e2005-09-27 22:37:33 +000052
darin@apple.com5e49bae2007-12-21 21:54:51 +000053 template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); }
mjscff5e5e2005-09-27 22:37:33 +000054
darin@apple.com5e49bae2007-12-21 21:54:51 +000055 T* get() const { return m_ptr; }
mjscff5e5e2005-09-27 22:37:33 +000056
darin@apple.com5e49bae2007-12-21 21:54:51 +000057 void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; }
ggarenf9a50472005-12-29 11:16:11 +000058 PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; }
59
mjs97e2b182005-12-06 09:21:15 +000060 T& operator*() const { return *m_ptr; }
darin@apple.com3beb3002008-04-28 05:59:07 +000061 ALWAYS_INLINE T* operator->() const { return m_ptr; }
mjscff5e5e2005-09-27 22:37:33 +000062
darin1a465db2005-12-19 20:48:23 +000063 bool operator!() const { return !m_ptr; }
mjsb60792d2005-12-01 08:38:15 +000064
darin1a465db2005-12-19 20:48:23 +000065 // This conversion operator allows implicit conversion to bool but not to other integer types.
hausmann@webkit.org9476dca2008-11-14 17:53:59 +000066#if COMPILER(WINSCW)
67 operator bool() const { return m_ptr; }
68#else
darin@apple.comd7417182008-01-05 22:46:03 +000069 typedef T* RefPtr::*UnspecifiedBoolType;
70 operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; }
hausmann@webkit.org9476dca2008-11-14 17:53:59 +000071#endif
mjscff5e5e2005-09-27 22:37:33 +000072
mjs97e2b182005-12-06 09:21:15 +000073 RefPtr& operator=(const RefPtr&);
darin@apple.com5e49bae2007-12-21 21:54:51 +000074 RefPtr& operator=(T*);
mjs1aec3582005-12-25 09:22:35 +000075 RefPtr& operator=(const PassRefPtr<T>&);
darine4818f82005-12-22 16:48:08 +000076 template <typename U> RefPtr& operator=(const RefPtr<U>&);
mjs1aec3582005-12-25 09:22:35 +000077 template <typename U> RefPtr& operator=(const PassRefPtr<U>&);
mjs97e2b182005-12-06 09:21:15 +000078
mjsed5d76d2005-12-23 01:52:43 +000079 void swap(RefPtr&);
80
mjscff5e5e2005-09-27 22:37:33 +000081 private:
darin@apple.com3beb3002008-04-28 05:59:07 +000082 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
83
darina51e5e72007-10-29 04:37:37 +000084 T* m_ptr;
mjscff5e5e2005-09-27 22:37:33 +000085 };
86
mjs1aec3582005-12-25 09:22:35 +000087 template <typename T> template <typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o)
darine4d34c62006-10-29 06:48:02 +000088 : m_ptr(o.releaseRef())
darine4818f82005-12-22 16:48:08 +000089 {
90 }
91
ggaren7b7949f2006-02-10 18:47:25 +000092 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o)
mjscff5e5e2005-09-27 22:37:33 +000093 {
darinfc3698e2006-01-23 17:10:45 +000094 T* optr = o.get();
mjscff5e5e2005-09-27 22:37:33 +000095 if (optr)
96 optr->ref();
darin983658d2006-01-17 17:28:35 +000097 T* ptr = m_ptr;
mjscff5e5e2005-09-27 22:37:33 +000098 m_ptr = optr;
darin983658d2006-01-17 17:28:35 +000099 if (ptr)
100 ptr->deref();
mjscff5e5e2005-09-27 22:37:33 +0000101 return *this;
102 }
103
ggaren7b7949f2006-02-10 18:47:25 +0000104 template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o)
darine4818f82005-12-22 16:48:08 +0000105 {
darinfc3698e2006-01-23 17:10:45 +0000106 T* optr = o.get();
darine4818f82005-12-22 16:48:08 +0000107 if (optr)
108 optr->ref();
darin983658d2006-01-17 17:28:35 +0000109 T* ptr = m_ptr;
darine4818f82005-12-22 16:48:08 +0000110 m_ptr = optr;
darin983658d2006-01-17 17:28:35 +0000111 if (ptr)
112 ptr->deref();
darine4818f82005-12-22 16:48:08 +0000113 return *this;
114 }
115
116 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr)
mjscff5e5e2005-09-27 22:37:33 +0000117 {
118 if (optr)
119 optr->ref();
darin983658d2006-01-17 17:28:35 +0000120 T* ptr = m_ptr;
mjscff5e5e2005-09-27 22:37:33 +0000121 m_ptr = optr;
darin983658d2006-01-17 17:28:35 +0000122 if (ptr)
123 ptr->deref();
mjscff5e5e2005-09-27 22:37:33 +0000124 return *this;
125 }
mjs97e2b182005-12-06 09:21:15 +0000126
mjs1aec3582005-12-25 09:22:35 +0000127 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>& o)
mjs97e2b182005-12-06 09:21:15 +0000128 {
darin983658d2006-01-17 17:28:35 +0000129 T* ptr = m_ptr;
darine4d34c62006-10-29 06:48:02 +0000130 m_ptr = o.releaseRef();
darin983658d2006-01-17 17:28:35 +0000131 if (ptr)
132 ptr->deref();
mjs97e2b182005-12-06 09:21:15 +0000133 return *this;
134 }
135
mjs1aec3582005-12-25 09:22:35 +0000136 template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<U>& o)
darine4818f82005-12-22 16:48:08 +0000137 {
darin983658d2006-01-17 17:28:35 +0000138 T* ptr = m_ptr;
darine4d34c62006-10-29 06:48:02 +0000139 m_ptr = o.releaseRef();
darin983658d2006-01-17 17:28:35 +0000140 if (ptr)
141 ptr->deref();
darine4818f82005-12-22 16:48:08 +0000142 return *this;
143 }
144
mjsed5d76d2005-12-23 01:52:43 +0000145 template <class T> inline void RefPtr<T>::swap(RefPtr<T>& o)
146 {
mjsc1632f52005-12-23 08:34:42 +0000147 std::swap(m_ptr, o.m_ptr);
mjsed5d76d2005-12-23 01:52:43 +0000148 }
149
150 template <class T> inline void swap(RefPtr<T>& a, RefPtr<T>& b)
151 {
152 a.swap(b);
153 }
154
darine4818f82005-12-22 16:48:08 +0000155 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b)
mjscff5e5e2005-09-27 22:37:33 +0000156 {
157 return a.get() == b.get();
158 }
159
darine4818f82005-12-22 16:48:08 +0000160 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, U* b)
mjscff5e5e2005-09-27 22:37:33 +0000161 {
162 return a.get() == b;
163 }
164
darine4818f82005-12-22 16:48:08 +0000165 template <typename T, typename U> inline bool operator==(T* a, const RefPtr<U>& b)
mjscff5e5e2005-09-27 22:37:33 +0000166 {
167 return a == b.get();
168 }
169
darine4818f82005-12-22 16:48:08 +0000170 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b)
mjscff5e5e2005-09-27 22:37:33 +0000171 {
172 return a.get() != b.get();
173 }
174
darine4818f82005-12-22 16:48:08 +0000175 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, U* b)
mjscff5e5e2005-09-27 22:37:33 +0000176 {
177 return a.get() != b;
178 }
179
darine4818f82005-12-22 16:48:08 +0000180 template <typename T, typename U> inline bool operator!=(T* a, const RefPtr<U>& b)
mjscff5e5e2005-09-27 22:37:33 +0000181 {
182 return a != b.get();
183 }
184
darine4818f82005-12-22 16:48:08 +0000185 template <typename T, typename U> inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p)
mjscff5e5e2005-09-27 22:37:33 +0000186 {
darin@apple.com5e49bae2007-12-21 21:54:51 +0000187 return RefPtr<T>(static_cast<T*>(p.get()));
mjscff5e5e2005-09-27 22:37:33 +0000188 }
189
darine4818f82005-12-22 16:48:08 +0000190 template <typename T, typename U> inline RefPtr<T> const_pointer_cast(const RefPtr<U>& p)
mjscff5e5e2005-09-27 22:37:33 +0000191 {
darin@apple.com5e49bae2007-12-21 21:54:51 +0000192 return RefPtr<T>(const_cast<T*>(p.get()));
mjscff5e5e2005-09-27 22:37:33 +0000193 }
194
darin4786e772006-08-31 00:12:08 +0000195 template <typename T> inline T* getPtr(const RefPtr<T>& p)
196 {
197 return p.get();
198 }
199
mjsbb863512006-05-09 09:27:55 +0000200} // namespace WTF
mjscff5e5e2005-09-27 22:37:33 +0000201
mjsbb863512006-05-09 09:27:55 +0000202using WTF::RefPtr;
203using WTF::static_pointer_cast;
204using WTF::const_pointer_cast;
mjscff5e5e2005-09-27 22:37:33 +0000205
mjs98cf6e02006-10-19 02:42:55 +0000206#endif // WTF_RefPtr_h