]> git.saurik.com Git - apple/javascriptcore.git/blame - wtf/PassRefPtr.h
JavaScriptCore-461.tar.gz
[apple/javascriptcore.git] / wtf / PassRefPtr.h
CommitLineData
b37bf2e1
A
1// -*- mode: c++; c-basic-offset: 4 -*-
2/*
3 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22#ifndef WTF_PassRefPtr_h
23#define WTF_PassRefPtr_h
24
25#include "AlwaysInline.h"
26
27namespace WTF {
28
29 template<typename T> class RefPtr;
30 template<typename T> class PassRefPtr;
31 template <typename T> PassRefPtr<T> adoptRef(T*);
32
33 template<typename T> class PassRefPtr {
34 public:
35 PassRefPtr() : m_ptr(0) {}
36 PassRefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
37 // It somewhat breaks the type system to allow transfer of ownership out of
38 // a const PassRefPtr. However, it makes it much easier to work with PassRefPtr
39 // temporaries, and we don't really have a need to use real const PassRefPtrs
40 // anyway.
41 PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef()) {}
42 template <typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { }
43
44 ALWAYS_INLINE ~PassRefPtr() { if (T* ptr = m_ptr) ptr->deref(); }
45
46 template <class U>
47 PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); }
48
49 T* get() const { return m_ptr; }
50
51 void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; }
52 T* releaseRef() const { T* tmp = m_ptr; m_ptr = 0; return tmp; }
53
54 T& operator*() const { return *m_ptr; }
55 T* operator->() const { return m_ptr; }
56
57 bool operator!() const { return !m_ptr; }
58
59 // This conversion operator allows implicit conversion to bool but not to other integer types.
60 typedef T* PassRefPtr::*UnspecifiedBoolType;
61 operator UnspecifiedBoolType() const { return m_ptr ? &PassRefPtr::m_ptr : 0; }
62
63 PassRefPtr& operator=(T*);
64 PassRefPtr& operator=(const PassRefPtr&);
65 template <typename U> PassRefPtr& operator=(const PassRefPtr<U>&);
66 template <typename U> PassRefPtr& operator=(const RefPtr<U>&);
67
68 friend PassRefPtr adoptRef<T>(T*);
69 private:
70 // adopting constructor
71 PassRefPtr(T* ptr, bool) : m_ptr(ptr) {}
72 mutable T* m_ptr;
73 };
74
75 template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<U>& o)
76 {
77 T* optr = o.get();
78 if (optr)
79 optr->ref();
80 T* ptr = m_ptr;
81 m_ptr = optr;
82 if (ptr)
83 ptr->deref();
84 return *this;
85 }
86
87 template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(T* optr)
88 {
89 if (optr)
90 optr->ref();
91 T* ptr = m_ptr;
92 m_ptr = optr;
93 if (ptr)
94 ptr->deref();
95 return *this;
96 }
97
98 template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<T>& ref)
99 {
100 T* ptr = m_ptr;
101 m_ptr = ref.releaseRef();
102 if (ptr)
103 ptr->deref();
104 return *this;
105 }
106
107 template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<U>& ref)
108 {
109 T* ptr = m_ptr;
110 m_ptr = ref.releaseRef();
111 if (ptr)
112 ptr->deref();
113 return *this;
114 }
115
116 template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const PassRefPtr<U>& b)
117 {
118 return a.get() == b.get();
119 }
120
121 template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const RefPtr<U>& b)
122 {
123 return a.get() == b.get();
124 }
125
126 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, const PassRefPtr<U>& b)
127 {
128 return a.get() == b.get();
129 }
130
131 template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, U* b)
132 {
133 return a.get() == b;
134 }
135
136 template <typename T, typename U> inline bool operator==(T* a, const PassRefPtr<U>& b)
137 {
138 return a == b.get();
139 }
140
141 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const PassRefPtr<U>& b)
142 {
143 return a.get() != b.get();
144 }
145
146 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const RefPtr<U>& b)
147 {
148 return a.get() != b.get();
149 }
150
151 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const PassRefPtr<U>& b)
152 {
153 return a.get() != b.get();
154 }
155
156 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, U* b)
157 {
158 return a.get() != b;
159 }
160
161 template <typename T, typename U> inline bool operator!=(T* a, const PassRefPtr<U>& b)
162 {
163 return a != b.get();
164 }
165
166 template <typename T> inline PassRefPtr<T> adoptRef(T* p)
167 {
168 return PassRefPtr<T>(p, true);
169 }
170
171 template <typename T, typename U> inline PassRefPtr<T> static_pointer_cast(const PassRefPtr<U>& p)
172 {
173 return adoptRef(static_cast<T*>(p.releaseRef()));
174 }
175
176 template <typename T, typename U> inline PassRefPtr<T> const_pointer_cast(const PassRefPtr<U>& p)
177 {
178 return adoptRef(const_cast<T*>(p.releaseRef()));
179 }
180
181 template <typename T> inline T* getPtr(const PassRefPtr<T>& p)
182 {
183 return p.get();
184 }
185
186} // namespace WTF
187
188using WTF::PassRefPtr;
189using WTF::adoptRef;
190using WTF::static_pointer_cast;
191using WTF::const_pointer_cast;
192
193#endif // WTF_PassRefPtr_h