• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009, 2010 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 "NullPtr.h"
31 #include "OwnPtrCommon.h"
32 #include "TypeTraits.h"
33 
34 // Remove this once we make all WebKit code compatible with stricter rules about PassOwnPtr.
35 #define LOOSE_PASS_OWN_PTR
36 
37 namespace WTF {
38 
39     // Unlike most of our smart pointers, PassOwnPtr can take either the pointer type or the pointed-to type.
40 
41     template<typename T> class OwnPtr;
42     template<typename T> class PassOwnPtr;
43     template<typename T> PassOwnPtr<T> adoptPtr(T*);
44 
45     template<typename T> class PassOwnPtr {
46     public:
47         typedef typename RemovePointer<T>::Type ValueType;
48         typedef ValueType* PtrType;
49 
PassOwnPtr()50         PassOwnPtr() : m_ptr(0) { }
51 
52         // It somewhat breaks the type system to allow transfer of ownership out of
53         // a const PassOwnPtr. However, it makes it much easier to work with PassOwnPtr
54         // temporaries, and we don't have a need to use real const PassOwnPtrs anyway.
PassOwnPtr(const PassOwnPtr & o)55         PassOwnPtr(const PassOwnPtr& o) : m_ptr(o.leakPtr()) { }
PassOwnPtr(const PassOwnPtr<U> & o)56         template<typename U> PassOwnPtr(const PassOwnPtr<U>& o) : m_ptr(o.leakPtr()) { }
57 
~PassOwnPtr()58         ~PassOwnPtr() { deleteOwnedPtr(m_ptr); }
59 
get()60         PtrType get() const { return m_ptr; }
61 
62         void clear();
63         PtrType leakPtr() const WARN_UNUSED_RETURN;
64 
65         ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; }
66         PtrType operator->() const { ASSERT(m_ptr); return m_ptr; }
67 
68         bool operator!() const { return !m_ptr; }
69 
70         // This conversion operator allows implicit conversion to bool but not to other integer types.
71         typedef PtrType PassOwnPtr::*UnspecifiedBoolType;
UnspecifiedBoolType()72         operator UnspecifiedBoolType() const { return m_ptr ? &PassOwnPtr::m_ptr : 0; }
73 
74         PassOwnPtr& operator=(const PassOwnPtr<T>&);
75 #if !defined(LOOSE_PASS_OWN_PTR) || !HAVE(NULLPTR)
76         PassOwnPtr& operator=(std::nullptr_t) { clear(); return *this; }
77 #endif
78         template<typename U> PassOwnPtr& operator=(const PassOwnPtr<U>&);
79 
80         template<typename U> friend PassOwnPtr<U> adoptPtr(U*);
81 
82 #ifdef LOOSE_PASS_OWN_PTR
PassOwnPtr(PtrType ptr)83         PassOwnPtr(PtrType ptr) : m_ptr(ptr) { }
84         PassOwnPtr& operator=(PtrType);
85 #endif
86 
87     private:
88 #ifndef LOOSE_PASS_OWN_PTR
PassOwnPtr(PtrType ptr)89         explicit PassOwnPtr(PtrType ptr) : m_ptr(ptr) { }
90 #endif
91 
92         mutable PtrType m_ptr;
93     };
94 
clear()95     template<typename T> inline void PassOwnPtr<T>::clear()
96     {
97         PtrType ptr = m_ptr;
98         m_ptr = 0;
99         deleteOwnedPtr(ptr);
100     }
101 
leakPtr()102     template<typename T> inline typename PassOwnPtr<T>::PtrType PassOwnPtr<T>::leakPtr() const
103     {
104         PtrType ptr = m_ptr;
105         m_ptr = 0;
106         return ptr;
107     }
108 
109 #ifdef LOOSE_PASS_OWN_PTR
110     template<typename T> inline PassOwnPtr<T>& PassOwnPtr<T>::operator=(PtrType optr)
111     {
112         PtrType ptr = m_ptr;
113         m_ptr = optr;
114         ASSERT(!ptr || m_ptr != ptr);
115         if (ptr)
116             deleteOwnedPtr(ptr);
117         return *this;
118     }
119 #endif
120 
121     template<typename T> inline PassOwnPtr<T>& PassOwnPtr<T>::operator=(const PassOwnPtr<T>& optr)
122     {
123         PtrType ptr = m_ptr;
124         m_ptr = optr.leakPtr();
125         ASSERT(!ptr || m_ptr != ptr);
126         if (ptr)
127             deleteOwnedPtr(ptr);
128         return *this;
129     }
130 
131     template<typename T> template<typename U> inline PassOwnPtr<T>& PassOwnPtr<T>::operator=(const PassOwnPtr<U>& optr)
132     {
133         PtrType ptr = m_ptr;
134         m_ptr = optr.leakPtr();
135         ASSERT(!ptr || m_ptr != ptr);
136         if (ptr)
137             deleteOwnedPtr(ptr);
138         return *this;
139     }
140 
141     template<typename T, typename U> inline bool operator==(const PassOwnPtr<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, const OwnPtr<U>& b)
147     {
148         return a.get() == b.get();
149     }
150 
151     template<typename T, typename U> inline bool operator==(const OwnPtr<T>& a, const PassOwnPtr<U>& b)
152     {
153         return a.get() == b.get();
154     }
155 
156     template<typename T, typename U> inline bool operator==(const PassOwnPtr<T>& a, U* b)
157     {
158         return a.get() == b;
159     }
160 
161     template<typename T, typename U> inline bool operator==(T* a, const PassOwnPtr<U>& b)
162     {
163         return a == b.get();
164     }
165 
166     template<typename T, typename U> inline bool operator!=(const PassOwnPtr<T>& a, const PassOwnPtr<U>& b)
167     {
168         return a.get() != b.get();
169     }
170 
171     template<typename T, typename U> inline bool operator!=(const PassOwnPtr<T>& a, const OwnPtr<U>& b)
172     {
173         return a.get() != b.get();
174     }
175 
176     template<typename T, typename U> inline bool operator!=(const OwnPtr<T>& a, const PassOwnPtr<U>& b)
177     {
178         return a.get() != b.get();
179     }
180 
181     template<typename T, typename U> inline bool operator!=(const PassOwnPtr<T>& a, U* b)
182     {
183         return a.get() != b;
184     }
185 
186     template<typename T, typename U> inline bool operator!=(T* a, const PassOwnPtr<U>& b)
187     {
188         return a != b.get();
189     }
190 
adoptPtr(T * ptr)191     template<typename T> inline PassOwnPtr<T> adoptPtr(T* ptr)
192     {
193         return PassOwnPtr<T>(ptr);
194     }
195 
static_pointer_cast(const PassOwnPtr<U> & p)196     template<typename T, typename U> inline PassOwnPtr<T> static_pointer_cast(const PassOwnPtr<U>& p)
197     {
198         return adoptPtr(static_cast<T*>(p.leakPtr()));
199     }
200 
const_pointer_cast(const PassOwnPtr<U> & p)201     template<typename T, typename U> inline PassOwnPtr<T> const_pointer_cast(const PassOwnPtr<U>& p)
202     {
203         return adoptPtr(const_cast<T*>(p.leakPtr()));
204     }
205 
getPtr(const PassOwnPtr<T> & p)206     template<typename T> inline T* getPtr(const PassOwnPtr<T>& p)
207     {
208         return p.get();
209     }
210 
211 } // namespace WTF
212 
213 using WTF::PassOwnPtr;
214 using WTF::adoptPtr;
215 using WTF::const_pointer_cast;
216 using WTF::static_pointer_cast;
217 
218 #endif // WTF_PassOwnPtr_h
219