summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoão Abecasis <joao.abecasis@nokia.com>2011-11-03 12:52:26 +0100
committerQt by Nokia <qt-info@nokia.com>2011-12-14 14:09:53 +0100
commit4da0b5fc02fe3a647d32892905c42928841d6487 (patch)
treed742f15ad2f1e1e6fbceddb92e5f18496a758826 /src
parentbd0b49efe0bf63b359fc315757a9de547d557802 (diff)
QArrayDataOps: generic array operations
This class, the selector and underlying implementations provide specialized operations on QArrayData, while allowing for optimized implementations that benefit from type-specific information. Currently, offering a generic implementation and specializations for PODs (trivial ctor, dtor and move operations) and movable types (can be trivially moved in memory). Change-Id: I2c5829b66c2aea79f12f21debe5c01f7104c7ea3 Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/tools/qarraydataops.h182
-rw-r--r--src/corelib/tools/tools.pri1
2 files changed, 183 insertions, 0 deletions
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h
new file mode 100644
index 0000000000..d62c411511
--- /dev/null
+++ b/src/corelib/tools/qarraydataops.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QARRAYDATAOPS_H
+#define QARRAYDATAOPS_H
+
+#include <QtCore/qarraydata.h>
+
+#include <new>
+#include <string.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+namespace QtPrivate {
+
+template <class T>
+struct QPodArrayOps
+ : QTypedArrayData<T>
+{
+ void copyAppend(const T *b, const T *e)
+ {
+ Q_ASSERT(this->ref == 1);
+ Q_ASSERT(b < e);
+ Q_ASSERT(size_t(e - b) <= this->alloc - uint(this->size));
+
+ ::memcpy(this->end(), b, (e - b) * sizeof(T));
+ this->size += e - b;
+ }
+
+ void copyAppend(size_t n, const T &t)
+ {
+ Q_ASSERT(this->ref == 1);
+ Q_ASSERT(n <= this->alloc - uint(this->size));
+
+ T *iter = this->end();
+ const T *const end = iter + n;
+ for (; iter != end; ++iter)
+ ::memcpy(iter, &t, sizeof(T));
+ this->size += n;
+ }
+
+ void destroyAll() // Call from destructors, ONLY!
+ {
+ Q_ASSERT(this->ref == 0);
+
+ // As this is to be called only from destructor, it doesn't need to be
+ // exception safe; size not updated.
+ }
+};
+
+template <class T>
+struct QGenericArrayOps
+ : QTypedArrayData<T>
+{
+ void copyAppend(const T *b, const T *e)
+ {
+ Q_ASSERT(this->ref == 1);
+ Q_ASSERT(b < e);
+ Q_ASSERT(size_t(e - b) <= this->alloc - uint(this->size));
+
+ T *iter = this->end();
+ for (; b != e; ++iter, ++b) {
+ new (iter) T(*b);
+ ++this->size;
+ }
+ }
+
+ void copyAppend(size_t n, const T &t)
+ {
+ Q_ASSERT(this->ref == 1);
+ Q_ASSERT(n <= this->alloc - uint(this->size));
+
+ T *iter = this->end();
+ const T *const end = iter + n;
+ for (; iter != end; ++iter) {
+ new (iter) T(t);
+ ++this->size;
+ }
+ }
+
+ void destroyAll() // Call from destructors, ONLY
+ {
+ // As this is to be called only from destructor, it doesn't need to be
+ // exception safe; size not updated.
+
+ Q_ASSERT(this->ref == 0);
+
+ const T *const b = this->begin();
+ const T *i = this->end();
+
+ while (i != b)
+ (--i)->~T();
+ }
+};
+
+template <class T>
+struct QMovableArrayOps
+ : QGenericArrayOps<T>
+{
+ // using QGenericArrayOps<T>::copyAppend;
+ // using QGenericArrayOps<T>::destroyAll;
+};
+
+template <class T, class = void>
+struct QArrayOpsSelector
+{
+ typedef QGenericArrayOps<T> Type;
+};
+
+template <class T>
+struct QArrayOpsSelector<T,
+ typename QEnableIf<
+ !QTypeInfo<T>::isComplex && !QTypeInfo<T>::isStatic
+ >::Type>
+{
+ typedef QPodArrayOps<T> Type;
+};
+
+template <class T>
+struct QArrayOpsSelector<T,
+ typename QEnableIf<
+ QTypeInfo<T>::isComplex && !QTypeInfo<T>::isStatic
+ >::Type>
+{
+ typedef QMovableArrayOps<T> Type;
+};
+
+} // namespace QtPrivate
+
+template <class T>
+struct QArrayDataOps
+ : QtPrivate::QArrayOpsSelector<T>::Type
+{
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // include guard
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 199dd85354..2ec32fd9e9 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -3,6 +3,7 @@
HEADERS += \
tools/qalgorithms.h \
tools/qarraydata.h \
+ tools/qarraydataops.h \
tools/qbitarray.h \
tools/qbytearray.h \
tools/qbytearraymatcher.h \