From 89fb2271f377d1194f3311124daef97504e6ead9 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 3 Apr 2014 09:36:03 +0200 Subject: [PATCH] QSharedPointer: allow one create() argument in C++98, too Survey says that most uses of QSharedPointer(T*) in Qt that could benefit from variadic create() pass only a single argument. In order to prevent all such uses from #ifdef'ing on the complex condition that enables the variadic version, provide a single-argument version (for lvalues only, obviously) for C++98, too. Change-Id: I22ad251a20bbf80867cc31eaa3bcec677bde4359 Reviewed-by: Thiago Macieira --- src/corelib/tools/qsharedpointer.cpp | 12 +++++++++--- src/corelib/tools/qsharedpointer_impl.h | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 2ced3d6a7c..58a9a021d0 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -630,9 +630,15 @@ 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 + \note This function is only fully 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, + then a restricted version is available since Qt 5.4: you may pass + one (but just one) argument, and it will always be passed by const + reference. + + If you target Qt before version 5.4, you must use the overload that calls the default constructor. */ diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index f70e398cfe..f3df32469f 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -437,6 +437,27 @@ public: new (result.data()) T(); # ifdef QT_SHAREDPOINTER_TRACK_POINTERS internalSafetyCheckAdd(result.d, result.value); +# endif + result.d->setQObjectShared(result.value, true); + return result; + } + + template + static inline QSharedPointer create(const Arg &arg) + { + 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(arg); +# ifdef QT_SHAREDPOINTER_TRACK_POINTERS + internalSafetyCheckAdd(result.d, result.value); # endif result.d->setQObjectShared(result.value, true); return result;