From 7ee9551b62b050f7e9aefdc19e19bac5ba263507 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 23 May 2012 21:10:31 +0200 Subject: Add support for multiple arguments to QSharedPointer::create() Requires C++11 rvalue references and variadic templates so we can implement perfect forwarding. Change-Id: I62e47d1ffd0c61e8386f9f246aa79031b7430b46 Reviewed-by: Olivier Goffart --- src/corelib/tools/qsharedpointer.cpp | 31 +++++++++++++++++++++++++++++++ src/corelib/tools/qsharedpointer.h | 3 +++ src/corelib/tools/qsharedpointer_impl.h | 27 +++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 167771027e..c9456c44c2 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -604,6 +604,37 @@ \sa qSharedPointerObjectCast() */ +/*! + \fn QSharedPointer QSharedPointer::create() + \since 4.6 + + Creates a QSharedPointer object and allocates a new item of type \tt T. The + QSharedPointer internals and the object are allocated in one single memory + allocation, which could help reduce memory fragmentation in a long-running + application. + + This function calls the default constructor for type \tt T. +*/ + +/*! + \fn QSharedPointer QSharedPointer::create(...) + \overload + \since 5.1 + + Creates a QSharedPointer object and allocates a new item of type \tt T. The + QSharedPointer internals and the object are allocated in one single memory + allocation, which could help reduce memory fragmentation in a long-running + application. + + This function will attempt to call a constructor for type \tt T that can + accept all the arguments passed. Arguments will be perfectly-forwarded. + + \note This function is only available with a C++11 compiler that supports + perfect forwarding of an arbitrary number of arguments. If the compiler + does not support the necessary C++11 features, you must use the overload + that calls the default constructor. +*/ + /*! \fn QWeakPointer QSharedPointer::toWeakRef() const diff --git a/src/corelib/tools/qsharedpointer.h b/src/corelib/tools/qsharedpointer.h index cfc5cadbb0..a430153bca 100644 --- a/src/corelib/tools/qsharedpointer.h +++ b/src/corelib/tools/qsharedpointer.h @@ -95,6 +95,9 @@ public: template QSharedPointer dynamicCast() const; template QSharedPointer constCast() const; template QSharedPointer objectCast() const; + + static inline QSharedPointer create(); + static inline QSharedPointer create(...); }; template diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 6f3e577e55..6393cc3970 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -62,6 +62,10 @@ QT_END_HEADER #include // for qobject_cast #include // for qHash +#if defined(Q_COMPILER_RVALUE_REFS) && defined(Q_COMPILER_VARIADIC_TEMPLATES) +# include // for std::forward +#endif + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -389,6 +393,28 @@ public: QWeakPointer toWeakRef() const; +#if defined(Q_COMPILER_RVALUE_REFS) && defined(Q_COMPILER_VARIADIC_TEMPLATES) + template + static QSharedPointer create(Args && ...arguments) + { + typedef QtSharedPointer::ExternalRefCountWithContiguousData Private; +# ifdef QT_SHAREDPOINTER_TRACK_POINTERS + typename Private::DestroyerFn destroy = &Private::safetyCheckDeleter; +# else + typename Private::DestroyerFn destroy = &Private::deleter; +# endif + QSharedPointer result(Qt::Uninitialized); + result.d = Private::create(&result.value, destroy); + + // now initialize the data + new (result.data()) T(std::forward(arguments)...); + result.d->setQObjectShared(result.value, true); +# ifdef QT_SHAREDPOINTER_TRACK_POINTERS + internalSafetyCheckAdd(result.d, result.value); +# endif + return result; + } +#else static inline QSharedPointer create() { typedef QtSharedPointer::ExternalRefCountWithContiguousData Private; @@ -408,6 +434,7 @@ public: result.d->setQObjectShared(result.value, true); return result; } +#endif private: explicit QSharedPointer(Qt::Initialization) {} -- cgit v1.2.3