summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2009-07-24 21:05:34 (GMT)
committerThiago Macieira <thiago.macieira@nokia.com>2009-07-24 21:05:34 (GMT)
commit25c5de7f168652ff5c3e6e49d09567d3ef4b41fd (patch)
tree3345735961a08f5e0fa657681aa51153d11d3d01
parent585d01e0c2833e16899a502d53bfd62a32573b35 (diff)
downloadQt-25c5de7f168652ff5c3e6e49d09567d3ef4b41fd.zip
Qt-25c5de7f168652ff5c3e6e49d09567d3ef4b41fd.tar.gz
Qt-25c5de7f168652ff5c3e6e49d09567d3ef4b41fd.tar.bz2
Adapt the contiguous-creator code to use the new custom deleter code.
We use the same trick as the custom deleter: we allocate memory for an object of class ExternalRefCountWithContiguousData<T>, but we do that only to be certain of the alignment requirements for T. We initialise the d-pointer via placement new and the T object is left for initialisation by the outermost function. The reason for that last trick is to support passing parameters in the future with the least amount of template functions necessary. I still plan on supporting arguments only with C++0x (maybe up to one without).
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h53
1 files changed, 27 insertions, 26 deletions
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index 98f225b..2c9cd95 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -232,31 +232,31 @@ namespace QtSharedPointer {
};
template <class T>
- struct ExternalRefCountWithContiguousData: public ExternalRefCountData
+ struct ExternalRefCountWithContiguousData: public ExternalRefCountWithDestroyFn
{
-#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
+ typedef ExternalRefCountWithDestroyFn Parent;
+ typedef ExternalRefCountWithContiguousData Self;
+ T data;
- char data[sizeof(T)] Q_DECL_ALIGN(QSP_ALIGNOF(T));
- inline T *pointer() { return reinterpret_cast<T *>(data); }
+ static void deleter(ExternalRefCountData *self)
+ {
+ ExternalRefCountWithContiguousData *that =
+ static_cast<ExternalRefCountWithContiguousData *>(self);
+ that->data.~T();
+ }
-# 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
+ static inline ExternalRefCountData *create(T **ptr)
+ {
+ DestroyerFn destroy = &deleter;
+ Self *d = static_cast<Self *>(::operator new(sizeof(Self)));
+
+ // initialize the d-pointer sub-object
+ // leave d->data uninitialized
+ new (d) Parent(destroy); // can't throw
- inline bool destroy() { this->pointer()->~T(); return true; }
+ *ptr = &d->data;
+ return d;
+ }
};
template <class T>
@@ -292,12 +292,10 @@ namespace QtSharedPointer {
inline void internalCreate()
{
- ExternalRefCountWithContiguousData<T> *dd = new ExternalRefCountWithContiguousData<T>;
- T *ptr = dd->pointer();
- new (ptr) T(); // create
+ T *ptr;
+ d = ExternalRefCountWithContiguousData<T>::create(&ptr);
Basic<T>::internalConstruct(ptr);
- d = dd;
}
inline ExternalRefCount() : d(0) { }
@@ -429,10 +427,13 @@ public:
QWeakPointer<T> toWeakRef() const;
public:
- static QSharedPointer<T> create()
+ static inline QSharedPointer<T> create()
{
QSharedPointer<T> result;
result.internalCreate();
+
+ // now initialize the data
+ new (result.data()) T();
return result;
}
};