From f2569c0ff75eb9a8418bb065c33c318f0a44c8ed Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 10 Aug 2015 15:15:07 -0700 Subject: Add QArrayDataOps::moveAppend() Same as copyAppend() but calls the move constructor Change-Id: I7de033f80b0e4431b7f1ffff13f9399e39b5fee4 Reviewed-by: Simon Hausmann --- src/corelib/tools/qarraydataops.h | 56 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'src/corelib/tools/qarraydataops.h') diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h index 5b59221f10..ac7fc7bc4e 100644 --- a/src/corelib/tools/qarraydataops.h +++ b/src/corelib/tools/qarraydataops.h @@ -83,6 +83,9 @@ struct QPodArrayOps this->size += e - b; } + void moveAppend(T *b, T *e) + { copyAppend(b, e); } + void copyAppend(size_t n, parameter_type t) { Q_ASSERT(this->isMutable()); @@ -176,6 +179,20 @@ struct QGenericArrayOps } } + void moveAppend(T *b, T *e) + { + Q_ASSERT(this->isMutable() || b == e); + Q_ASSERT(!this->isShared() || b == e); + Q_ASSERT(b <= e); + Q_ASSERT(size_t(e - b) <= this->allocatedCapacity() - this->size); + + T *iter = this->end(); + for (; b != e; ++iter, ++b) { + new (iter) T(std::move(*b)); + ++this->size; + } + } + void copyAppend(size_t n, parameter_type t) { Q_ASSERT(this->isMutable()); @@ -414,6 +431,45 @@ struct QMovableArrayOps (--e)->~T(); } while (e != b); } + + void moveAppend(T *b, T *e) + { + Q_ASSERT(this->isMutable()); + Q_ASSERT(!this->isShared()); + Q_ASSERT(b <= e); + Q_ASSERT(e <= this->begin() || b > this->end()); // No overlap + Q_ASSERT(size_t(e - b) <= this->allocatedCapacity() - this->size); + + // Provides strong exception safety guarantee, + // provided T::~T() nothrow + + struct CopyConstructor + { + CopyConstructor(T *w) : where(w) {} + + void copy(const T *src, const T *const srcEnd) + { + n = 0; + for (; src != srcEnd; ++src) { + new (where + n) T(std::move(*src)); + ++n; + } + n = 0; + } + + ~CopyConstructor() + { + while (n) + where[--n].~T(); + } + + T *const where; + size_t n; + } copier(this->end()); + + copier.copy(b, e); + this->size += (e - b); + } }; template -- cgit v1.2.3