Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / wtf / PassRefPtr.h
1 /*
2  *  Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
3  *
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
16  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  *  Boston, MA 02110-1301, USA.
18  *
19  */
20
21 #ifndef WTF_PassRefPtr_h
22 #define WTF_PassRefPtr_h
23
24 #include "wtf/Assertions.h"
25 #include "wtf/NullPtr.h"
26 #include "wtf/RawPtr.h"
27 #include "wtf/TypeTraits.h"
28
29 namespace WTF {
30
31     template<typename T> class RefPtr;
32     template<typename T> class PassRefPtr;
33     template<typename T> PassRefPtr<T> adoptRef(T*);
34
35     inline void adopted(const void*) { }
36
37     // requireAdoption() is not overloaded for WTF::RefCounted, which has a
38     // built-in assumption that adoption is required. requireAdoption() is
39     // for bootstrapping alternate reference count classes that are compatible
40     // with ReftPtr/PassRefPtr but cannot have adoption checks enabled
41     // by default, such as skia's SkRefCnt. The purpose of requireAdoption()
42     // is to enable adoption checks only once it is known that the object will
43     // be used with RefPtr/PassRefPtr.
44     inline void requireAdoption(const void*) { }
45
46     template<typename T> ALWAYS_INLINE void refIfNotNull(T* ptr)
47     {
48         if (LIKELY(ptr != 0)) {
49             requireAdoption(ptr);
50             ptr->ref();
51         }
52     }
53
54     template<typename T> ALWAYS_INLINE void derefIfNotNull(T* ptr)
55     {
56         if (LIKELY(ptr != 0))
57             ptr->deref();
58     }
59
60     template<typename T> class PassRefPtr {
61         WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(PassRefPtr);
62     public:
63         PassRefPtr() : m_ptr(0) { }
64         PassRefPtr(std::nullptr_t) : m_ptr(0) { }
65         PassRefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); }
66         template<typename U> PassRefPtr(const RawPtr<U>& ptr, EnsurePtrConvertibleArgDecl(U, T)) : m_ptr(ptr.get()) { refIfNotNull(m_ptr); }
67         explicit PassRefPtr(T& ptr) : m_ptr(&ptr) { m_ptr->ref(); }
68         // It somewhat breaks the type system to allow transfer of ownership out of
69         // a const PassRefPtr. However, it makes it much easier to work with PassRefPtr
70         // temporaries, and we don't have a need to use real const PassRefPtrs anyway.
71         PassRefPtr(const PassRefPtr& o) : m_ptr(o.leakRef()) { }
72         template<typename U> PassRefPtr(const PassRefPtr<U>& o, EnsurePtrConvertibleArgDecl(U, T)) : m_ptr(o.leakRef()) { }
73
74         ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull(m_ptr); }
75
76         template<typename U> PassRefPtr(const RefPtr<U>&, EnsurePtrConvertibleArgDecl(U, T));
77
78         T* get() const { return m_ptr; }
79
80         T* leakRef() const WARN_UNUSED_RETURN;
81
82         T& operator*() const { return *m_ptr; }
83         T* operator->() const { return m_ptr; }
84
85         bool operator!() const { return !m_ptr; }
86
87         // This conversion operator allows implicit conversion to bool but not to other integer types.
88         typedef T* (PassRefPtr::*UnspecifiedBoolType);
89         operator UnspecifiedBoolType() const { return m_ptr ? &PassRefPtr::m_ptr : 0; }
90
91         friend PassRefPtr adoptRef<T>(T*);
92
93     private:
94         enum AdoptRefTag { AdoptRef };
95         PassRefPtr(T* ptr, AdoptRefTag) : m_ptr(ptr) { }
96
97         PassRefPtr& operator=(const PassRefPtr&) { COMPILE_ASSERT(!sizeof(T*), PassRefPtr_should_never_be_assigned_to); return *this; }
98
99         mutable T* m_ptr;
100     };
101
102     template<typename T> template<typename U> inline PassRefPtr<T>::PassRefPtr(const RefPtr<U>& o, EnsurePtrConvertibleArgDefn(U, T))
103         : m_ptr(o.get())
104     {
105         T* ptr = m_ptr;
106         refIfNotNull(ptr);
107     }
108
109     template<typename T> inline T* PassRefPtr<T>::leakRef() const
110     {
111         T* ptr = m_ptr;
112         m_ptr = 0;
113         return ptr;
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 RawPtr<U>& b)
142     {
143         return a.get() == b.get();
144     }
145
146     template<typename T, typename U> inline bool operator==(const RawPtr<T>& a, const PassRefPtr<U>& b)
147     {
148         return a.get() == b.get();
149     }
150
151     template<typename T, typename U> inline bool operator!=(const PassRefPtr<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, const RefPtr<U>& b)
157     {
158         return a.get() != b.get();
159     }
160
161     template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const PassRefPtr<U>& b)
162     {
163         return a.get() != b.get();
164     }
165
166     template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, U* b)
167     {
168         return a.get() != b;
169     }
170
171     template<typename T, typename U> inline bool operator!=(T* a, const PassRefPtr<U>& b)
172     {
173         return a != b.get();
174     }
175
176     template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const RawPtr<U>& b)
177     {
178         return a.get() != b.get();
179     }
180
181     template<typename T, typename U> inline bool operator!=(const RawPtr<T>& a, const PassRefPtr<U>& b)
182     {
183         return a.get() != b.get();
184     }
185
186     template<typename T> PassRefPtr<T> adoptRef(T* p)
187     {
188         adopted(p);
189         return PassRefPtr<T>(p, PassRefPtr<T>::AdoptRef);
190     }
191
192     template<typename T, typename U> inline PassRefPtr<T> static_pointer_cast(const PassRefPtr<U>& p)
193     {
194         return adoptRef(static_cast<T*>(p.leakRef()));
195     }
196
197     template<typename T> inline T* getPtr(const PassRefPtr<T>& p)
198     {
199         return p.get();
200     }
201
202 } // namespace WTF
203
204 using WTF::PassRefPtr;
205 using WTF::adoptRef;
206 using WTF::static_pointer_cast;
207
208 #endif // WTF_PassRefPtr_h