]> git.saurik.com Git - apple/javascriptcore.git/blame - wtf/PassOwnPtr.h
JavaScriptCore-584.tar.gz
[apple/javascriptcore.git] / wtf / PassOwnPtr.h
CommitLineData
ba379fdc
A
1/*
2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef WTF_PassOwnPtr_h
27#define WTF_PassOwnPtr_h
28
29#include "Assertions.h"
30#include "OwnPtrCommon.h"
31#include "TypeTraits.h"
32
33namespace WTF {
34
35 // Unlike most of our smart pointers, PassOwnPtr can take either the pointer type or the pointed-to type.
36
37 template <typename T> class OwnPtr;
38
39 template <typename T> class PassOwnPtr {
40 public:
41 typedef typename RemovePointer<T>::Type ValueType;
42 typedef ValueType* PtrType;
43
44 PassOwnPtr(PtrType ptr = 0) : m_ptr(ptr) { }
45 // It somewhat breaks the type system to allow transfer of ownership out of
46 // a const PassOwnPtr. However, it makes it much easier to work with PassOwnPtr
47 // temporaries, and we don't really have a need to use real const PassOwnPtrs
48 // anyway.
49 PassOwnPtr(const PassOwnPtr& o) : m_ptr(o.release()) { }
50 template <typename U> PassOwnPtr(const PassOwnPtr<U>& o) : m_ptr(o.release()) { }
51
52 ~PassOwnPtr() { deleteOwnedPtr(m_ptr); }
53
54 PtrType get() const { return m_ptr; }
55
56 void clear() { m_ptr = 0; }
57 PtrType release() const { PtrType ptr = m_ptr; m_ptr = 0; return ptr; }
58
59 ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; }
60 PtrType operator->() const { ASSERT(m_ptr); return m_ptr; }
61
62 bool operator!() const { return !m_ptr; }
63
64 // This conversion operator allows implicit conversion to bool but not to other integer types.
65 typedef PtrType PassOwnPtr::*UnspecifiedBoolType;
66 operator UnspecifiedBoolType() const { return m_ptr ? &PassOwnPtr::m_ptr : 0; }
67
68 PassOwnPtr& operator=(T*);
69 PassOwnPtr& operator=(const PassOwnPtr<T>&);
70 template <typename U> PassOwnPtr& operator=(const PassOwnPtr<U>&);
71
72 private:
73 mutable PtrType m_ptr;
74 };
75
76 template <typename T> inline PassOwnPtr<T>& PassOwnPtr<T>::operator=(T* optr)
77 {
78 T* ptr = m_ptr;
79 m_ptr = optr;
80 ASSERT(!ptr || m_ptr != ptr);
81 if (ptr)
82 deleteOwnedPtr(ptr);
83 return *this;
84 }
85
86 template <typename T> inline PassOwnPtr<T>& PassOwnPtr<T>::operator=(const PassOwnPtr<T>& optr)
87 {
88 T* ptr = m_ptr;
89 m_ptr = optr.release();
90 ASSERT(!ptr || m_ptr != ptr);
91 if (ptr)
92 deleteOwnedPtr(ptr);
93 return *this;
94 }
95
96 template <typename T> template <typename U> inline PassOwnPtr<T>& PassOwnPtr<T>::operator=(const PassOwnPtr<U>& optr)
97 {
98 T* ptr = m_ptr;
99 m_ptr = optr.release();
100 ASSERT(!ptr || m_ptr != ptr);
101 if (ptr)
102 deleteOwnedPtr(ptr);
103 return *this;
104 }
105
106 template <typename T, typename U> inline bool operator==(const PassOwnPtr<T>& a, const PassOwnPtr<U>& b)
107 {
108 return a.get() == b.get();
109 }
110
111 template <typename T, typename U> inline bool operator==(const PassOwnPtr<T>& a, const OwnPtr<U>& b)
112 {
113 return a.get() == b.get();
114 }
115
116 template <typename T, typename U> inline bool operator==(const OwnPtr<T>& a, const PassOwnPtr<U>& b)
117 {
118 return a.get() == b.get();
119 }
120
121 template <typename T, typename U> inline bool operator==(const PassOwnPtr<T>& a, U* b)
122 {
123 return a.get() == b;
124 }
125
126 template <typename T, typename U> inline bool operator==(T* a, const PassOwnPtr<U>& b)
127 {
128 return a == b.get();
129 }
130
131 template <typename T, typename U> inline bool operator!=(const PassOwnPtr<T>& a, const PassOwnPtr<U>& b)
132 {
133 return a.get() != b.get();
134 }
135
136 template <typename T, typename U> inline bool operator!=(const PassOwnPtr<T>& a, const OwnPtr<U>& b)
137 {
138 return a.get() != b.get();
139 }
140
141 template <typename T, typename U> inline bool operator!=(const OwnPtr<T>& a, const PassOwnPtr<U>& b)
142 {
143 return a.get() != b.get();
144 }
145
146 template <typename T, typename U> inline bool operator!=(const PassOwnPtr<T>& a, U* b)
147 {
148 return a.get() != b;
149 }
150
151 template <typename T, typename U> inline bool operator!=(T* a, const PassOwnPtr<U>& b)
152 {
153 return a != b.get();
154 }
155
156 template <typename T, typename U> inline PassOwnPtr<T> static_pointer_cast(const PassOwnPtr<U>& p)
157 {
158 return PassOwnPtr<T>(static_cast<T*>(p.release()));
159 }
160
161 template <typename T, typename U> inline PassOwnPtr<T> const_pointer_cast(const PassOwnPtr<U>& p)
162 {
163 return PassOwnPtr<T>(const_cast<T*>(p.release()));
164 }
165
166 template <typename T> inline T* getPtr(const PassOwnPtr<T>& p)
167 {
168 return p.get();
169 }
170
171} // namespace WTF
172
173using WTF::PassOwnPtr;
174using WTF::const_pointer_cast;
175using WTF::static_pointer_cast;
176
177#endif // WTF_PassOwnPtr_h