+2013-10-16 Darin Adler <darin@apple.com>
+
+ Add PassRef and createRefCounted so we can improve creation of RefCounted objects
+ https://bugs.webkit.org/show_bug.cgi?id=122904
+
+ Reviewed by Anders Carlsson.
+
+ * GNUmakefile.list.am: Added PassRef.h.
+ * WTF.vcxproj/WTF.vcxproj: Ditto.
+ * WTF.vcxproj/WTF.vcxproj.filters: Ditto.
+ * WTF.xcodeproj/project.pbxproj: Ditto.
+ * wtf/CMakeLists.txt: Ditto.
+
+ * wtf/Forward.h: Added PassRef. Also re-sorted and un-indented to match what
+ the style-checking script expects.
+
+ * wtf/PassRef.h: Added. Includes the createRefCounted function template, which
+ is analogous to make_unique, but is for reference counted objects, and also
+ assumes that new will never return null. Also includes an overload of adoptRef
+ that takes a reference rather than a pointer.
+
+ * wtf/PassRefPtr.h: Include "PassRef.h" so we can share the adopted function.
+ Got rid of declarations that duplicate ones in there.
+ (WTF::refIfNotNull): Use nullptr.
+ (WTF::derefIfNotNull): Use nullptr.
+ (WTF::PassRefPtr::PassRefPtr): Use nullptr. Added an overload that takes a PassRef.
+ (WTF::PassRefPtr::operator UnspecifiedBoolType): Use nullptr.
+ (WTF::PassRefPtr::operator=): Made this deleted instead of compile time assertion.
+ (WTF::PassRefPtr::PassRefPtr): Made adopting constructor use an adopt tag instead
+ of an unused boolean.
+ (WTF::PassRefPtr::leakRef): Use nullptr.
+ (WTF::adoptRef): Use the adopt tag.
+
+ * wtf/Ref.h: Use Noncopyable instead of rolling our own.
+ (WTF::Ref::Ref): Add an overload that takes a PassRef.
+ (WTF::Ref::operator=): Ditto.
+
+ * wtf/RefPtr.h: Removed unneeded forward declaration of PassRefPtr.
+ (WTF::RefPtr::RefPtr): Use nullptr. Added overload that takes a PassRef.
+ (WTF::RefPtr::release): Use nullptr.
+ (WTF::RefPtr::operator UnspecifiedBoolType): Use nullptr.
+ (WTF::RefPtr::operator=): Added overload that takes a PassRef.
+ (WTF::RefPtr::clear): Use nullptr.
+
+ * wtf/StdLibExtras.h: Added inline keyword to isPointerTypeAlignmentOkay,
+ reinterpret_cast_ptr, and make_unique. Seems like a simple oversight that these
+ were missing before.
+
2013-10-15 Dean Jackson <dino@apple.com>
Add ENABLE_WEB_ANIMATIONS flag
Source/WTF/wtf/ParallelJobsLibdispatch.h \
Source/WTF/wtf/ParallelJobsOpenMP.h \
Source/WTF/wtf/PassOwnPtr.h \
+ Source/WTF/wtf/PassRef.h \
Source/WTF/wtf/PassRefPtr.h \
Source/WTF/wtf/Platform.h \
Source/WTF/wtf/PossiblyNull.h \
<ClInclude Include="..\wtf\ParallelJobsLibdispatch.h" />\r
<ClInclude Include="..\wtf\ParallelJobsOpenMP.h" />\r
<ClInclude Include="..\wtf\PassOwnPtr.h" />\r
+ <ClInclude Include="..\wtf\PassRef.h" />\r
<ClInclude Include="..\wtf\PassRefPtr.h" />\r
<ClInclude Include="..\wtf\Platform.h" />\r
<ClInclude Include="..\wtf\PossiblyNull.h" />\r
<ClInclude Include="..\wtf\PassOwnPtr.h">\r
<Filter>wtf</Filter>\r
</ClInclude>\r
+ <ClInclude Include="..\wtf\PassRef.h">\r
+ <Filter>wtf</Filter>\r
+ </ClInclude>\r
<ClInclude Include="..\wtf\PassRefPtr.h">\r
<Filter>wtf</Filter>\r
</ClInclude>\r
7E29C33E15FFD79B00516D61 /* ObjcRuntimeExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E29C33D15FFD79B00516D61 /* ObjcRuntimeExtras.h */; };
8134013815B092FD001FF0B8 /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8134013615B092FD001FF0B8 /* Base64.cpp */; };
8134013915B092FD001FF0B8 /* Base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 8134013715B092FD001FF0B8 /* Base64.h */; };
+ 93B1AA80180E5AF3004A2F05 /* PassRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B1AA7F180E5AF3004A2F05 /* PassRef.h */; };
974CFC8E16A4F327006D5404 /* WeakPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 974CFC8D16A4F327006D5404 /* WeakPtr.h */; };
9BC70F05176C379D00101DEC /* AtomicStringTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BC70F04176C379D00101DEC /* AtomicStringTable.cpp */; };
9BD8F40B176C2B470002D865 /* AtomicStringTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BD8F40A176C2AD80002D865 /* AtomicStringTable.h */; };
7E29C33D15FFD79B00516D61 /* ObjcRuntimeExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjcRuntimeExtras.h; sourceTree = "<group>"; };
8134013615B092FD001FF0B8 /* Base64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Base64.cpp; sourceTree = "<group>"; };
8134013715B092FD001FF0B8 /* Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64.h; sourceTree = "<group>"; };
+ 93B1AA7F180E5AF3004A2F05 /* PassRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PassRef.h; sourceTree = "<group>"; };
974CFC8D16A4F327006D5404 /* WeakPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakPtr.h; sourceTree = "<group>"; };
9BC70F04176C379D00101DEC /* AtomicStringTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AtomicStringTable.cpp; sourceTree = "<group>"; };
9BD8F40A176C2AD80002D865 /* AtomicStringTable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AtomicStringTable.h; sourceTree = "<group>"; };
A8A472CE151A825B004123FF /* MetaAllocator.h */,
A8A472CF151A825B004123FF /* MetaAllocatorHandle.h */,
1A3F6BE6174ADA2100B2EEA7 /* NeverDestroyed.h */,
- 26299B6D17A9E5B800ADEBE5 /* Ref.h */,
0F0D85B317234CB100338210 /* NoLock.h */,
A8A472D0151A825B004123FF /* Noncopyable.h */,
A8A472D5151A825B004123FF /* NumberOfCores.cpp */,
A8A472E6151A825B004123FF /* ParallelJobs.h */,
A8A472E9151A825B004123FF /* ParallelJobsLibdispatch.h */,
A8A472EC151A825B004123FF /* PassOwnPtr.h */,
+ 93B1AA7F180E5AF3004A2F05 /* PassRef.h */,
A8A472ED151A825B004123FF /* PassRefPtr.h */,
A876DBD7151816E500DADB95 /* Platform.h */,
A8A472F3151A825B004123FF /* PossiblyNull.h */,
A8A472FD151A825B004123FF /* RandomNumberSeed.h */,
0F87105916643F190090B0AD /* RawPointer.h */,
A8A472FE151A825B004123FF /* RedBlackTree.h */,
+ 26299B6D17A9E5B800ADEBE5 /* Ref.h */,
A8A472FF151A825B004123FF /* RefCounted.h */,
A8A47300151A825B004123FF /* RefCountedArray.h */,
A8A47301151A825B004123FF /* RefCountedLeakCounter.cpp */,
A8A473E3151A825B004123FF /* Locker.h in Headers */,
A8A473E6151A825B004123FF /* MainThread.h in Headers */,
A8A473E8151A825B004123FF /* MathExtras.h in Headers */,
+ 93B1AA80180E5AF3004A2F05 /* PassRef.h in Headers */,
A8A473EA151A825B004123FF /* MD5.h in Headers */,
CD5497AD15857D0300B5BC30 /* MediaTime.h in Headers */,
A8A473EB151A825B004123FF /* MessageQueue.h in Headers */,
ParallelJobsLibdispatch.h
ParallelJobsOpenMP.h
PassOwnPtr.h
+ PassRef.h
PassRefPtr.h
Platform.h
PossiblyNull.h
namespace WTF {
- template<typename T> class Function;
- template<typename T> class OwnPtr;
- template<typename T> class PassOwnPtr;
- template<typename T> class PassRefPtr;
- template<typename T> class RefPtr;
- template<typename T> class Ref;
- template<typename T, size_t inlineCapacity, typename OverflowHandler> class Vector;
+template<typename T> class Function;
+template<typename T> class OwnPtr;
+template<typename T> class PassOwnPtr;
+template<typename T> class PassRef;
+template<typename T> class PassRefPtr;
+template<typename T> class RefPtr;
+template<typename T> class Ref;
+template<typename T> class StringBuffer;
- class AtomicString;
- class AtomicStringImpl;
- class BinarySemaphore;
- class CString;
- class Decoder;
- class Encoder;
- class FunctionDispatcher;
- class PrintStream;
- class String;
- template <typename T> class StringBuffer;
- class StringBuilder;
- class StringImpl;
-}
+template<typename T, size_t inlineCapacity, typename OverflowHandler> class Vector;
-using WTF::Function;
-using WTF::OwnPtr;
-using WTF::PassOwnPtr;
-using WTF::PassRefPtr;
-using WTF::RefPtr;
-using WTF::Ref;
-using WTF::Vector;
+class AtomicString;
+class AtomicStringImpl;
+class BinarySemaphore;
+class CString;
+class Decoder;
+class Encoder;
+class FunctionDispatcher;
+class PrintStream;
+class String;
+class StringBuilder;
+class StringImpl;
+
+}
using WTF::AtomicString;
using WTF::AtomicStringImpl;
using WTF::BinarySemaphore;
using WTF::CString;
-using WTF::Encoder;
using WTF::Decoder;
+using WTF::Encoder;
+using WTF::Function;
using WTF::FunctionDispatcher;
+using WTF::OwnPtr;
+using WTF::PassOwnPtr;
+using WTF::PassRef;
+using WTF::PassRefPtr;
using WTF::PrintStream;
+using WTF::Ref;
+using WTF::RefPtr;
using WTF::String;
using WTF::StringBuffer;
using WTF::StringBuilder;
using WTF::StringImpl;
+using WTF::Vector;
#endif // WTF_Forward_h
--- /dev/null
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef WTF_PassRef_h
+#define WTF_PassRef_h
+
+#include "Assertions.h"
+#include <cstddef>
+
+namespace WTF {
+
+template<typename T> class PassRef;
+template<typename T> class PassRefPtr;
+template<typename T> class Ref;
+template<typename T> class RefPtr;
+
+template<typename T> PassRef<T> adoptRef(T&);
+
+inline void adopted(const void*) { }
+
+template<typename T> class PassRef {
+public:
+ PassRef(T&);
+ PassRef(PassRef&&);
+ template<typename U> PassRef(PassRef<U>);
+
+#ifndef NDEBUG
+ ~PassRef();
+#endif
+
+private:
+ friend PassRef adoptRef<T>(T&);
+
+ template<typename U> friend class PassRef;
+ template<typename U> friend class PassRefPtr;
+ template<typename U> friend class Ref;
+ template<typename U> friend class RefPtr;
+
+ enum AdoptTag { Adopt };
+ PassRef(T&, AdoptTag);
+
+ T& takeReference();
+
+ T& m_reference;
+
+#ifndef NDEBUG
+ bool m_gaveUpReference;
+#endif
+};
+
+template<typename T> inline PassRef<T>::PassRef(T& reference)
+ : m_reference(reference)
+#ifndef NDEBUG
+ , m_gaveUpReference(false)
+#endif
+{
+ reference.ref();
+}
+
+template<typename T> inline PassRef<T>::PassRef(PassRef&& other)
+ : m_reference(other.takeReference())
+#ifndef NDEBUG
+ , m_gaveUpReference(false)
+#endif
+{
+}
+
+template<typename T> template<typename U> inline PassRef<T>::PassRef(PassRef<U> other)
+ : m_reference(other.takeReference())
+#ifndef NDEBUG
+ , m_gaveUpReference(false)
+#endif
+{
+}
+
+#ifndef NDEBUG
+
+template<typename T> PassRef<T>::~PassRef()
+{
+ ASSERT(m_gaveUpReference);
+}
+
+#endif
+
+template<typename T> inline T& PassRef<T>::takeReference()
+{
+#ifndef NDEBUG
+ ASSERT(!m_gaveUpReference);
+ m_gaveUpReference = true;
+#endif
+ return m_reference;
+}
+
+template<typename T> inline PassRef<T>::PassRef(T& reference, AdoptTag)
+ : m_reference(reference)
+#ifndef NDEBUG
+ , m_gaveUpReference(false)
+#endif
+{
+}
+
+template<typename T> inline PassRef<T> adoptRef(T& reference)
+{
+ adopted(&reference);
+ return PassRef<T>(reference, PassRef<T>::Adopt);
+}
+
+#if COMPILER_SUPPORTS(CXX_VARIADIC_TEMPLATES)
+
+template<typename T, typename... Args> inline PassRef<T> createRefCounted(Args&&... args)
+{
+ return adoptRef(*new T(std::forward<Args>(args)...));
+}
+
+#else
+
+template<typename T> inline PassRef<T> createRefCounted()
+{
+ return adoptRef(*new T);
+}
+
+template<typename T, typename A1> inline PassRef<T> createRefCounted(A1&& a1)
+{
+ return adoptRef(*new T(std::forward<A1>(a1)));
+}
+
+template<typename T, typename A1, typename A2> inline PassRef<T> createRefCounted(A1&& a1, A2&& a2)
+{
+ return adoptRef(*new T(std::forward<A1>(a1), std::forward<A2>(a2)));
+}
+
+template<typename T, typename A1, typename A2, typename A3> inline PassRef<T> createRefCounted(A1&& a1, A2&& a2, A3&& a3)
+{
+ return adoptRef(*new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3)));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4> inline PassRef<T> createRefCounted(A1&& a1, A2&& a2, A3&& a3, A4&& a4)
+{
+ return adoptRef(*new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4)));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5> inline PassRef<T> createRefCounted(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5)
+{
+ return adoptRef(*new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4), std::forward<A5>(a5)));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> inline PassRef<T> createRefCounted(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6)
+{
+ return adoptRef(*new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4), std::forward<A5>(a5), std::forward<A6>(a6)));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> inline PassRef<T> createRefCounted(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7)
+{
+ return adoptRef(*new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4), std::forward<A5>(a5), std::forward<A6>(a6), std::forward<A7>(a7)));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8> inline PassRef<T> createRefCounted(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7, A8&& a8)
+{
+ return adoptRef(*new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4), std::forward<A5>(a5), std::forward<A6>(a6), std::forward<A7>(a7), std::forward<A8>(a8)));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> inline PassRef<T> createRefCounted(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7, A8&& a8, A9&& a9)
+{
+ return adoptRef(*new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4), std::forward<A5>(a5), std::forward<A6>(a6), std::forward<A7>(a7), std::forward<A8>(a8), std::forward<A9>(a9)));
+}
+
+template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10> inline PassRef<T> createRefCounted(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7, A8&& a8, A9&& a9, A10&& a10)
+{
+ return adoptRef(*new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4), std::forward<A5>(a5), std::forward<A6>(a6), std::forward<A7>(a7), std::forward<A8>(a8), std::forward<A9>(a9), std::forward<A10>(a10)));
+}
+
+#endif
+
+} // namespace WTF
+
+using WTF::PassRef;
+using WTF::adoptRef;
+using WTF::createRefCounted;
+
+#endif // WTF_PassRef_h
#ifndef WTF_PassRefPtr_h
#define WTF_PassRefPtr_h
-#include <cstddef>
-#include <wtf/Assertions.h>
+#include "PassRef.h"
namespace WTF {
- template<typename T> class RefPtr;
- template<typename T> class PassRefPtr;
template<typename T> PassRefPtr<T> adoptRef(T*);
- inline void adopted(const void*) { }
-
template<typename T> ALWAYS_INLINE void refIfNotNull(T* ptr)
{
- if (LIKELY(ptr != 0))
+ if (LIKELY(ptr != nullptr))
ptr->ref();
}
template<typename T> ALWAYS_INLINE void derefIfNotNull(T* ptr)
{
- if (LIKELY(ptr != 0))
+ if (LIKELY(ptr != nullptr))
ptr->deref();
}
template<typename T> class PassRefPtr {
public:
- PassRefPtr() : m_ptr(0) { }
+ PassRefPtr() : m_ptr(nullptr) { }
PassRefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); }
// It somewhat breaks the type system to allow transfer of ownership out of
// a const PassRefPtr. However, it makes it much easier to work with PassRefPtr
ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull(m_ptr); }
template<typename U> PassRefPtr(const RefPtr<U>&);
-
+ template<typename U> PassRefPtr(PassRef<U> reference) : m_ptr(&reference.takeReference()) { }
+
T* get() const { return m_ptr; }
T* leakRef() const WARN_UNUSED_RETURN;
// This conversion operator allows implicit conversion to bool but not to other integer types.
typedef T* (PassRefPtr::*UnspecifiedBoolType);
- operator UnspecifiedBoolType() const { return m_ptr ? &PassRefPtr::m_ptr : 0; }
-
- PassRefPtr& operator=(const PassRefPtr&) { COMPILE_ASSERT(!sizeof(T*), PassRefPtr_should_never_be_assigned_to); return *this; }
+ operator UnspecifiedBoolType() const { return m_ptr ? &PassRefPtr::m_ptr : nullptr; }
friend PassRefPtr adoptRef<T>(T*);
private:
- // adopting constructor
- PassRefPtr(T* ptr, bool) : m_ptr(ptr) { }
+ PassRefPtr& operator=(const PassRefPtr&) WTF_DELETED_FUNCTION;
+
+ enum AdoptTag { Adopt };
+ PassRefPtr(T* ptr, AdoptTag) : m_ptr(ptr) { }
mutable T* m_ptr;
};
template<typename T> inline T* PassRefPtr<T>::leakRef() const
{
T* ptr = m_ptr;
- m_ptr = 0;
+ m_ptr = nullptr;
return ptr;
}
template<typename T> inline PassRefPtr<T> adoptRef(T* p)
{
adopted(p);
- return PassRefPtr<T>(p, true);
+ return PassRefPtr<T>(p, PassRefPtr<T>::Adopt);
}
template<typename T, typename U> inline PassRefPtr<T> static_pointer_cast(const PassRefPtr<U>& p)
#ifndef WTF_Ref_h
#define WTF_Ref_h
-#include <wtf/Compiler.h>
+#include "Noncopyable.h"
namespace WTF {
+template<typename T> class PassRef;
+
template<typename T> class Ref {
+ WTF_MAKE_NONCOPYABLE(Ref)
public:
Ref(T& object) : m_ptr(&object) { m_ptr->ref(); }
+ template<typename U> Ref(PassRef<U> reference) : m_ptr(&reference.takeReference()) { }
+
+ ~Ref() { m_ptr->deref(); }
+
Ref& operator=(T& object)
{
object.ref();
m_ptr = &object;
return *this;
}
-
- ~Ref() { m_ptr->deref(); }
+ template<typename U> Ref& operator=(PassRef<U> reference)
+ {
+ m_ptr->deref();
+ m_ptr = &reference.takeReference();
+ return *this;
+ }
const T* operator->() const { return m_ptr; }
T* operator->() { return m_ptr; }
T& get() { return *m_ptr; }
private:
- Ref(const Ref&);
- Ref& operator=(const Ref<T>&);
-
T* m_ptr;
};
#ifndef WTF_RefPtr_h
#define WTF_RefPtr_h
+#include "FastMalloc.h"
+#include "PassRefPtr.h"
#include <algorithm>
#include <utility>
-#include <wtf/FastMalloc.h>
-#include <wtf/PassRefPtr.h>
namespace WTF {
- template<typename T> class PassRefPtr;
-
enum HashTableDeletedValueType { HashTableDeletedValue };
template<typename T> class RefPtr {
WTF_MAKE_FAST_ALLOCATED;
public:
- ALWAYS_INLINE RefPtr() : m_ptr(0) { }
+ ALWAYS_INLINE RefPtr() : m_ptr(nullptr) { }
ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); }
ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { refIfNotNull(m_ptr); }
template<typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { refIfNotNull(m_ptr); }
// See comments in PassRefPtr.h for an explanation of why this takes a const reference.
template<typename U> RefPtr(const PassRefPtr<U>&);
+ template<typename U> RefPtr(PassRef<U>);
+
// Hash table deleted values, which are only constructed and never copied or destroyed.
RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
T* get() const { return m_ptr; }
void clear();
- PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; }
+ PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = nullptr; return tmp; }
T& operator*() const { return *m_ptr; }
ALWAYS_INLINE T* operator->() const { return m_ptr; }
// This conversion operator allows implicit conversion to bool but not to other integer types.
typedef T* (RefPtr::*UnspecifiedBoolType);
- operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; }
+ operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : nullptr; }
RefPtr& operator=(const RefPtr&);
RefPtr& operator=(T*);
template<typename U> RefPtr& operator=(const PassRefPtr<U>&);
RefPtr& operator=(RefPtr&&);
template<typename U> RefPtr& operator=(RefPtr<U>&&);
+ template<typename U> RefPtr& operator=(PassRef<U>);
+
void swap(RefPtr&);
static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
{
}
+ template<typename T> template<typename U> inline RefPtr<T>::RefPtr(PassRef<U> reference)
+ : m_ptr(&reference.takeReference())
+ {
+ }
+
template<typename T> inline void RefPtr<T>::clear()
{
T* ptr = m_ptr;
- m_ptr = 0;
+ m_ptr = nullptr;
derefIfNotNull(ptr);
}
return *this;
}
+ template<typename T> template<typename U> inline RefPtr<T>& RefPtr<T>::operator=(PassRef<U> reference)
+ {
+ RefPtr ptr = reference;
+ swap(ptr);
+ return *this;
+ }
+
template<class T> inline void RefPtr<T>::swap(RefPtr& o)
{
std::swap(m_ptr, o.m_ptr);
*/
#if (CPU(ARM) || CPU(MIPS)) && COMPILER(GCC)
template<typename Type>
-bool isPointerTypeAlignmentOkay(Type* ptr)
+inline bool isPointerTypeAlignmentOkay(Type* ptr)
{
return !(reinterpret_cast<intptr_t>(ptr) % __alignof__(Type));
}
template<typename TypePtr>
-TypePtr reinterpret_cast_ptr(void* ptr)
+inline TypePtr reinterpret_cast_ptr(void* ptr)
{
ASSERT(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr)));
return reinterpret_cast<TypePtr>(ptr);
}
template<typename TypePtr>
-TypePtr reinterpret_cast_ptr(const void* ptr)
+inline TypePtr reinterpret_cast_ptr(const void* ptr)
{
ASSERT(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr)));
return reinterpret_cast<TypePtr>(ptr);
}
#else
template<typename Type>
-bool isPointerTypeAlignmentOkay(Type*)
+inline bool isPointerTypeAlignmentOkay(Type*)
{
return true;
}
};
#if COMPILER_SUPPORTS(CXX_VARIADIC_TEMPLATES)
- template<class T, class... Args> typename _Unique_if<T>::_Single_object
+ template<class T, class... Args> inline typename _Unique_if<T>::_Single_object
make_unique(Args&&... args)
{
return unique_ptr<T>(new T(std::forward<Args>(args)...));
}
#else
- template<class T> typename _Unique_if<T>::_Single_object
+ template<class T> inline typename _Unique_if<T>::_Single_object
make_unique()
{
return unique_ptr<T>(new T);
}
- template<class T, class A1> typename _Unique_if<T>::_Single_object
+ template<class T, class A1> inline typename _Unique_if<T>::_Single_object
make_unique(A1&& a1)
{
return unique_ptr<T>(new T(std::forward<A1>(a1)));
}
- template<class T, class A1, class A2> typename _Unique_if<T>::_Single_object
+ template<class T, class A1, class A2> inline typename _Unique_if<T>::_Single_object
make_unique(A1&& a1, A2&& a2)
{
return unique_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2)));
}
- template<class T, class A1, class A2, class A3> typename _Unique_if<T>::_Single_object
+ template<class T, class A1, class A2, class A3> inline typename _Unique_if<T>::_Single_object
make_unique(A1&& a1, A2&& a2, A3&& a3)
{
return unique_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3)));
}
- template<class T, class A1, class A2, class A3, class A4> typename _Unique_if<T>::_Single_object
+ template<class T, class A1, class A2, class A3, class A4> inline typename _Unique_if<T>::_Single_object
make_unique(A1&& a1, A2&& a2, A3&& a3, A4&& a4)
{
return unique_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4)));
}
- template<class T, class A1, class A2, class A3, class A4, class A5> typename _Unique_if<T>::_Single_object
+ template<class T, class A1, class A2, class A3, class A4, class A5> inline typename _Unique_if<T>::_Single_object
make_unique(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5)
{
return unique_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4), std::forward<A5>(a5)));
}
- template<class T, class A1, class A2, class A3, class A4, class A5, class A6> typename _Unique_if<T>::_Single_object
+ template<class T, class A1, class A2, class A3, class A4, class A5, class A6> inline typename _Unique_if<T>::_Single_object
make_unique(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6)
{
return unique_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4), std::forward<A5>(a5), std::forward<A6>(a6)));
}
- template<class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7> typename _Unique_if<T>::_Single_object
+ template<class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7> inline typename _Unique_if<T>::_Single_object
make_unique(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7)
{
return unique_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4), std::forward<A5>(a5), std::forward<A6>(a6), std::forward<A7>(a7)));
}
- template<class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> typename _Unique_if<T>::_Single_object
+ template<class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> inline typename _Unique_if<T>::_Single_object
make_unique(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7, A8&& a8)
{
return unique_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4), std::forward<A5>(a5), std::forward<A6>(a6), std::forward<A7>(a7), std::forward<A8>(a8)));
}
- template<class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> typename _Unique_if<T>::_Single_object
+ template<class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> inline typename _Unique_if<T>::_Single_object
make_unique(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7, A8&& a8, A9&& a9)
{
return unique_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4), std::forward<A5>(a5), std::forward<A6>(a6), std::forward<A7>(a7), std::forward<A8>(a8), std::forward<A9>(a9)));
}
- template<class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> typename _Unique_if<T>::_Single_object
+ template<class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> inline typename _Unique_if<T>::_Single_object
make_unique(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6, A7&& a7, A8&& a8, A9&& a9, A10&& a10)
{
return unique_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4), std::forward<A5>(a5), std::forward<A6>(a6), std::forward<A7>(a7), std::forward<A8>(a8), std::forward<A9>(a9), std::forward<A10>(a10)));
}
#endif
- template<class T> typename _Unique_if<T>::_Unknown_bound
+ template<class T> inline typename _Unique_if<T>::_Unknown_bound
make_unique(size_t n)
{
typedef typename remove_extent<T>::type U;
+2013-10-16 Darin Adler <darin@apple.com>
+
+ Add PassRef and createRefCounted so we can improve creation of RefCounted objects
+ https://bugs.webkit.org/show_bug.cgi?id=122904
+
+ Reviewed by Anders Carlsson.
+
+ * TestWebKitAPI/Tests/WTF/Ref.cpp: Added some basic tests for adoptRef and PassRef.
+
2013-10-16 Darin Adler <darin@apple.com>
Need tests for RefPtr self-assignment and self-move-assignment.
#include "config.h"
#include "RefLogger.h"
+#include <wtf/PassRef.h>
#include <wtf/Ref.h>
+#include <wtf/RefPtr.h>
namespace TestWebKitAPI {
ASSERT_EQ(&a.name, &ptr->name);
}
ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ Ref<RefLogger> ptr(adoptRef(a));
+ ASSERT_EQ(&a, &ptr.get());
+ ASSERT_EQ(&a.name, &ptr->name);
+ }
+ ASSERT_STREQ("deref(a) ", takeLogStr().c_str());
}
TEST(WTF_Ref, Assignment)
log() << "| ";
}
ASSERT_STREQ("ref(a) | ref(c) deref(a) | deref(c) ", takeLogStr().c_str());
+
+ {
+ Ref<RefLogger> ptr(a);
+ ASSERT_EQ(&a, &ptr.get());
+ log() << "| ";
+ ptr = adoptRef(b);
+ ASSERT_EQ(&b, &ptr.get());
+ log() << "| ";
+ }
+ ASSERT_STREQ("ref(a) | deref(a) | deref(b) ", takeLogStr().c_str());
+
+ {
+ Ref<RefLogger> ptr(a);
+ ASSERT_EQ(&a, &ptr.get());
+ log() << "| ";
+ ptr = adoptRef(c);
+ ASSERT_EQ(&c, &ptr.get());
+ log() << "| ";
+ }
+ ASSERT_STREQ("ref(a) | deref(a) | deref(c) ", takeLogStr().c_str());
+}
+
+PassRef<RefLogger> passWithPassRef(PassRef<RefLogger> reference)
+{
+ return reference;
+}
+
+RefPtr<RefLogger> passWithPassRefPtr(PassRefPtr<RefLogger> reference)
+{
+ return reference;
+}
+
+TEST(WTF_Ref, ReturnValue)
+{
+ DerivedRefLogger a("a");
+ RefLogger b("b");
+ DerivedRefLogger c("c");
+
+ {
+ Ref<RefLogger> ptr(passWithPassRef(a));
+ ASSERT_EQ(&a, &ptr.get());
+ }
+ ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ Ref<RefLogger> ptr(a);
+ ASSERT_EQ(&a, &ptr.get());
+ log() << "| ";
+ ptr = passWithPassRef(b);
+ ASSERT_EQ(&b, &ptr.get());
+ log() << "| ";
+ }
+ ASSERT_STREQ("ref(a) | ref(b) deref(a) | deref(b) ", takeLogStr().c_str());
+
+ {
+ RefPtr<RefLogger> ptr(passWithPassRef(a));
+ ASSERT_EQ(&a, ptr.get());
+ }
+ ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
+
+ {
+ RefPtr<RefLogger> ptr(passWithPassRefPtr(passWithPassRef(a)));
+ ASSERT_EQ(&a, ptr.get());
+ }
+ ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
}
} // namespace TestWebKitAPI