diff options
author | Thiago Macieira <thiago.macieira@nokia.com> | 2009-06-25 18:52:36 (GMT) |
---|---|---|
committer | Thiago Macieira <thiago.macieira@nokia.com> | 2009-07-02 11:48:19 (GMT) |
commit | fb51a10ee0451274a430227566ae26efb2ac4474 (patch) | |
tree | 0c504f7005bbebdadd15df8ce1ce1795b205aa45 /src/corelib/tools | |
parent | a32019f4c2f56a84172bde739d7ea174be0db381 (diff) | |
download | Qt-fb51a10ee0451274a430227566ae26efb2ac4474.zip Qt-fb51a10ee0451274a430227566ae26efb2ac4474.tar.gz Qt-fb51a10ee0451274a430227566ae26efb2ac4474.tar.bz2 |
Add support for creating the object alongside the Data structure in
one go.
This avoids one memory allocation. Currently, we only support calling
the default constructors. I will *NOT* implement argument passing for
C++03. I will implement it with rvalue references for C++0x-capable
compilers.
Diffstat (limited to 'src/corelib/tools')
-rw-r--r-- | src/corelib/tools/qsharedpointer_impl.h | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index df31fec..cb78f29 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -48,6 +48,7 @@ #pragma qt_sync_stop_processing #endif +#include <new> #include <QtCore/qatomic.h> #include <QtCore/qobject.h> // for qobject_cast @@ -190,6 +191,34 @@ namespace QtSharedPointer { }; template <class T> + struct ExternalRefCountWithContiguousData: public ExternalRefCountData + { +#ifdef Q_DECL_ALIGN +# ifdef Q_ALIGNOF +# define QSP_ALIGNOF(T) Q_ALIGNOF(T) +# else +# define QSP_ALIGNOF(T) (sizeof(T) >= 16 ? 16 : sizeof(T) >= 8 ? 8 : sizeof(T) >= 4 ? 4 : sizeof(T) >= 2 ? 2 : 1) +# endif + + char data[sizeof(T)] Q_DECL_ALIGN(QSP_ALIGNOF(T)); + inline T *pointer() { return reinterpret_cast<T *>(data); } + +# undef QSP_ALIGNOF +#else + union { + char data[sizeof(T) + 16]; + double dummy1; +# ifndef Q_OS_DARWIN + long double dummy2; +# endif + }; + inline T *pointer() { return reinterpret_cast<T *>(data + 16 - (quintptr(data) & 0xf)); } +#endif + + inline bool destroy() { this->pointer()->~T(); return true; } + }; + + template <class T> class ExternalRefCount: public Basic<T> { typedef ExternalRefCountData Data; @@ -220,6 +249,16 @@ namespace QtSharedPointer { d = new ExternalRefCountWithSpecializedDeleter<T, Deleter>(ptr, deleter); } + inline void internalCreate() + { + ExternalRefCountWithContiguousData<T> *dd = new ExternalRefCountWithContiguousData<T>; + T *ptr = dd->pointer(); + new (ptr) T(); // create + + Basic<T>::internalConstruct(ptr); + d = dd; + } + inline ExternalRefCount() : d(0) { } inline ~ExternalRefCount() { if (d && !deref()) delete d; } inline ExternalRefCount(const ExternalRefCount<T> &other) : Basic<T>(other), d(other.d) @@ -347,6 +386,14 @@ public: inline void clear() { *this = QSharedPointer<T>(); } QWeakPointer<T> toWeakRef() const; + +public: + static QSharedPointer<T> create() + { + QSharedPointer<T> result; + result.internalCreate(); + return result; + } }; template <class T> |