summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2009-06-25 18:52:36 (GMT)
committerThiago Macieira <thiago.macieira@nokia.com>2009-07-02 11:48:19 (GMT)
commitfb51a10ee0451274a430227566ae26efb2ac4474 (patch)
tree0c504f7005bbebdadd15df8ce1ce1795b205aa45 /src/corelib/tools
parenta32019f4c2f56a84172bde739d7ea174be0db381 (diff)
downloadQt-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.h47
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>