summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qvarlengtharray.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools/qvarlengtharray.h')
-rw-r--r--src/corelib/tools/qvarlengtharray.h126
1 files changed, 54 insertions, 72 deletions
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index 54603bcec1..6ae3cc8308 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -172,6 +172,13 @@ public:
template <typename Predicate>
qsizetype removeIf(Predicate pred);
+ void clear()
+ {
+ if constexpr (QTypeInfo<T>::isComplex)
+ std::destroy_n(data(), size());
+ s = 0;
+ }
+
iterator erase(const_iterator begin, const_iterator end);
iterator erase(const_iterator pos) { return erase(pos, pos + 1); }
@@ -180,11 +187,13 @@ public:
return qHashRange(begin(), end(), seed);
}
protected:
+ void growBy(qsizetype prealloc, void *array, qsizetype increment)
+ { reallocate_impl(prealloc, array, size(), (std::max)(size() * 2, size() + increment)); }
template <typename...Args>
reference emplace_back_impl(qsizetype prealloc, void *array, Args&&...args)
{
if (size() == capacity()) // ie. size() != 0
- reallocate_impl(prealloc, array, size(), size() << 1);
+ growBy(prealloc, array, 1);
reference r = *new (end()) T(std::forward<Args>(args)...);
++s;
return r;
@@ -206,9 +215,32 @@ protected:
}
void append_impl(qsizetype prealloc, void *array, const T *buf, qsizetype n);
- void reallocate_impl(qsizetype prealloc, void *array, qsizetype size, qsizetype alloc, const T *v = nullptr);
- void resize_impl(qsizetype prealloc, void *array, qsizetype sz, const T *v = nullptr)
- { reallocate_impl(prealloc, array, sz, qMax(sz, capacity()), v); }
+ void reallocate_impl(qsizetype prealloc, void *array, qsizetype size, qsizetype alloc);
+ void resize_impl(qsizetype prealloc, void *array, qsizetype sz, const T &v)
+ {
+ if (QtPrivate::q_points_into_range(&v, begin(), end())) {
+ resize_impl(prealloc, array, sz, T(v));
+ return;
+ }
+ reallocate_impl(prealloc, array, sz, qMax(sz, capacity()));
+ while (size() < sz) {
+ new (data() + size()) T(v);
+ ++s;
+ }
+ }
+ void resize_impl(qsizetype prealloc, void *array, qsizetype sz)
+ {
+ reallocate_impl(prealloc, array, sz, qMax(sz, capacity()));
+ if constexpr (QTypeInfo<T>::isComplex) {
+ // call default constructor for new objects (which can throw)
+ while (size() < sz) {
+ new (data() + size()) T;
+ ++s;
+ }
+ } else {
+ s = sz;
+ }
+ }
bool isValidIterator(const const_iterator &i) const
{
@@ -378,8 +410,11 @@ public:
template <typename U = T, if_copyable<U> = true>
#endif
void resize(qsizetype sz, const T &v)
- { Base::resize_impl(Prealloc, this->array, sz, &v); }
+ { Base::resize_impl(Prealloc, this->array, sz, v); }
+ using Base::clear;
+#ifdef Q_QDOC
inline void clear() { resize(0); }
+#endif
void squeeze() { reallocate(size(), size()); }
using Base::capacity;
@@ -695,7 +730,7 @@ Q_OUTOFLINE_TEMPLATE void QVLABase<T>::append_impl(qsizetype prealloc, void *arr
const qsizetype asize = size() + increment;
if (asize >= capacity())
- reallocate_impl(prealloc, array, size(), qMax(size() * 2, asize));
+ growBy(prealloc, array, increment);
if constexpr (QTypeInfo<T>::isComplex)
std::uninitialized_copy_n(abuf, increment, end());
@@ -706,7 +741,7 @@ Q_OUTOFLINE_TEMPLATE void QVLABase<T>::append_impl(qsizetype prealloc, void *arr
}
template <class T>
-Q_OUTOFLINE_TEMPLATE void QVLABase<T>::reallocate_impl(qsizetype prealloc, void *array, qsizetype asize, qsizetype aalloc, const T *v)
+Q_OUTOFLINE_TEMPLATE void QVLABase<T>::reallocate_impl(qsizetype prealloc, void *array, qsizetype asize, qsizetype aalloc)
{
Q_ASSERT(aalloc >= asize);
Q_ASSERT(data());
@@ -747,26 +782,6 @@ Q_OUTOFLINE_TEMPLATE void QVLABase<T>::reallocate_impl(qsizetype prealloc, void
if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != data())
free(oldPtr);
-
- if (v) {
- if constexpr (std::is_copy_constructible_v<T>) {
- while (size() < asize) {
- new (data() + size()) T(*v);
- ++s;
- }
- } else {
- Q_UNREACHABLE();
- }
- } else if constexpr (QTypeInfo<T>::isComplex) {
- // call default constructor for new objects (which can throw)
- while (size() < asize) {
- new (data() + size()) T;
- ++s;
- }
- } else {
- s = asize;
- }
-
}
template <class T>
@@ -834,29 +849,12 @@ Q_OUTOFLINE_TEMPLATE auto QVLABase<T>::emplace_impl(qsizetype prealloc, void *ar
Q_ASSERT(size() <= capacity());
Q_ASSERT(capacity() > 0);
- qsizetype offset = qsizetype(before - cbegin());
- if (size() == capacity())
- reallocate_impl(prealloc, array, size(), size() * 2);
- if constexpr (!QTypeInfo<T>::isRelocatable) {
- T *b = begin() + offset;
- T *i = end();
- T *j = i + 1;
- // 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 = T(std::forward<Args>(args)...);
- } else {
- new (b) T(std::forward<Args>(args)...);
- }
- } else {
- T *b = begin() + offset;
- memmove(static_cast<void *>(b + 1), static_cast<const void *>(b), (size() - offset) * sizeof(T));
- new (b) T(std::forward<Args>(args)...);
- }
- this->s += 1;
- return data() + offset;
+ const qsizetype offset = qsizetype(before - cbegin());
+ emplace_back_impl(prealloc, array, std::forward<Args>(args)...);
+ const auto b = begin() + offset;
+ const auto e = end();
+ QtPrivate::q_rotate(b, e - 1, e);
+ return b;
}
template <class T>
@@ -864,28 +862,12 @@ Q_OUTOFLINE_TEMPLATE auto QVLABase<T>::insert_impl(qsizetype prealloc, void *arr
{
Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid");
- qsizetype offset = qsizetype(before - cbegin());
- if (n != 0) {
- const T copy(t); // `t` could alias an element in [begin(), end()[
- resize_impl(prealloc, array, size() + n);
- if constexpr (!QTypeInfo<T>::isRelocatable) {
- T *b = begin() + offset;
- T *j = end();
- T *i = j - n;
- while (i != b)
- *--j = *--i;
- i = b + n;
- while (i != b)
- *--i = copy;
- } else {
- T *b = begin() + offset;
- T *i = b + n;
- memmove(static_cast<void *>(i), static_cast<const void *>(b), (size() - offset - n) * sizeof(T));
- while (i != b)
- new (--i) T(copy);
- }
- }
- return data() + offset;
+ const qsizetype offset = qsizetype(before - cbegin());
+ resize_impl(prealloc, array, size() + n, t);
+ const auto b = begin() + offset;
+ const auto e = end();
+ QtPrivate::q_rotate(b, e - n, e);
+ return b;
}
template <class T>