summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qvector.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools/qvector.h')
-rw-r--r--src/corelib/tools/qvector.h78
1 files changed, 65 insertions, 13 deletions
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 3a3d416775..5ebf7f7435 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -59,8 +59,6 @@
QT_BEGIN_NAMESPACE
-class QRegion;
-
template <typename T>
class QVector
{
@@ -139,7 +137,9 @@ public:
void append(T &&t);
#endif
inline void append(const QVector<T> &l) { *this += l; }
+ void prepend(T &&t);
void prepend(const T &t);
+ void insert(int i, T &&t);
void insert(int i, const T &t);
void insert(int i, int n, const T &t);
void replace(int i, const T &t);
@@ -228,6 +228,7 @@ public:
const_reverse_iterator crend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); }
iterator insert(iterator before, int n, const T &x);
inline iterator insert(iterator before, const T &x) { return insert(before, 1, x); }
+ inline iterator insert(iterator before, T &&x);
iterator erase(iterator begin, iterator end);
inline iterator erase(iterator pos) { return erase(pos, pos+1); }
@@ -259,6 +260,7 @@ public:
inline void push_back(const T &t) { append(t); }
#ifdef Q_COMPILER_RVALUE_REFS
void push_back(T &&t) { append(std::move(t)); }
+ void push_front(T &&t) { prepend(std::move(t)); }
#endif
inline void push_front(const T &t) { prepend(t); }
void pop_back() { removeLast(); }
@@ -291,8 +293,6 @@ public:
inline std::vector<T> toStdVector() const
{ return std::vector<T>(d->begin(), d->end()); }
private:
- friend class QRegion; // Optimization for QRegion::rects()
-
// ### Qt6: remove const from int parameters
void reallocData(const int size, const int alloc, QArrayData::AllocationOptions options = QArrayData::Default);
void reallocData(const int sz) { reallocData(sz, d->alloc); }
@@ -440,6 +440,10 @@ inline void QVector<T>::insert(int i, int n, const T &t)
{ Q_ASSERT_X(i >= 0 && i <= d->size, "QVector<T>::insert", "index out of range");
insert(begin() + i, n, t); }
template <typename T>
+inline void QVector<T>::insert(int i, T &&t)
+{ Q_ASSERT_X(i >= 0 && i <= d->size, "QVector<T>::insert", "index out of range");
+ insert(begin() + i, std::move(t)); }
+template <typename T>
inline void QVector<T>::remove(int i, int n)
{ Q_ASSERT_X(i >= 0 && n >= 0 && i + n <= d->size, "QVector<T>::remove", "index out of range");
erase(d->begin() + i, d->begin() + i + n); }
@@ -450,6 +454,9 @@ inline void QVector<T>::remove(int i)
template <typename T>
inline void QVector<T>::prepend(const T &t)
{ insert(begin(), 1, t); }
+template <typename T>
+inline void QVector<T>::prepend(T &&t)
+{ insert(begin(), std::move(t)); }
template <typename T>
inline void QVector<T>::replace(int i, const T &t)
@@ -562,9 +569,19 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo
T *dst = x->begin();
if (!QTypeInfoQuery<T>::isRelocatable || (isShared && QTypeInfo<T>::isComplex)) {
- // we can not move the data, we need to copy construct it
- while (srcBegin != srcEnd) {
- new (dst++) T(*srcBegin++);
+ QT_TRY {
+ if (isShared || !std::is_nothrow_move_constructible<T>::value) {
+ // we can not move the data, we need to copy construct it
+ while (srcBegin != srcEnd)
+ new (dst++) T(*srcBegin++);
+ } else {
+ while (srcBegin != srcEnd)
+ new (dst++) T(std::move(*srcBegin++));
+ }
+ } QT_CATCH (...) {
+ // destruct already copied objects
+ destruct(x->begin(), dst);
+ QT_RETHROW;
}
} else {
::memcpy(static_cast<void *>(dst), static_cast<void *>(srcBegin), (srcEnd - srcBegin) * sizeof(T));
@@ -577,12 +594,17 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo
if (asize > d->size) {
// construct all new objects when growing
- QT_TRY {
- defaultConstruct(dst, x->end());
- } QT_CATCH (...) {
- // destruct already copied objects
- destruct(x->begin(), dst);
- QT_RETHROW;
+ if (!QTypeInfo<T>::isComplex) {
+ ::memset(static_cast<void *>(dst), 0, (static_cast<T *>(x->end()) - dst) * sizeof(T));
+ } else {
+ QT_TRY {
+ while (dst != x->end())
+ new (dst++) T();
+ } QT_CATCH (...) {
+ // destruct already copied objects
+ destruct(x->begin(), dst);
+ QT_RETHROW;
+ }
}
}
} QT_CATCH (...) {
@@ -735,6 +757,36 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c
}
template <typename T>
+typename QVector<T>::iterator QVector<T>::insert(iterator before, T &&t)
+{
+ Q_ASSERT_X(isValidIterator(before), "QVector::insert", "The specified iterator argument 'before' is invalid");
+
+ const auto offset = std::distance(d->begin(), before);
+ if (!isDetached() || d->size + 1 > int(d->alloc))
+ reallocData(d->size, d->size + 1, QArrayData::Grow);
+ if (!QTypeInfoQuery<T>::isRelocatable) {
+ T *i = d->end();
+ T *j = i + 1;
+ T *b = d->begin() + offset;
+ // The new end-element needs to be constructed, the rest must be move assigned
+ if (i != b) {
+ new (--j) T(std::move(*--i));
+ while (i != b)
+ *--j = std::move(*--i);
+ *b = std::move(t);
+ } else {
+ new (b) T(std::move(t));
+ }
+ } else {
+ T *b = d->begin() + offset;
+ memmove(b + 1, b, (d->size - offset) * sizeof(T));
+ new (b) T(std::move(t));
+ }
+ d->size += 1;
+ return d->begin() + offset;
+}
+
+template <typename T>
typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
{
Q_ASSERT_X(isValidIterator(abegin), "QVector::erase", "The specified iterator argument 'abegin' is invalid");