Part 1 of 2: Bug 25495: Implement PassOwnPtr and replace uses of std::auto_ptr
[WebKit-https.git] / JavaScriptCore / wtf / PassOwnPtr.h
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
33 namespace 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
173 using WTF::PassOwnPtr;
174 using WTF::const_pointer_cast;
175 using WTF::static_pointer_cast;
176
177 #endif // WTF_PassOwnPtr_h