QByteArray/QVarLengthArray: add missing resize(n, v) overloads
QList and QString had them, so add them to QByteArray and QVarLengthArray, too. In the QVLA case, we need to jump though a hoop or two to avoid having to duplicate all the reallocation logic. Nothing a few template tricks cannot solve. [ChangeLog][QtCore][QByteArray] Added resize(n, ch) overload. [ChangeLog][QtCore][QVarLengthArray] Added resize(n, v) overload. Fixes: QTBUG-102270 Change-Id: I0d281ae5b574f440f682e4a62427b434dcf5b687 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>bb10
parent
2fb7c94f63
commit
a00a1d8806
|
|
@ -1759,6 +1759,31 @@ void QByteArray::resize(qsizetype size)
|
|||
d.data()[size] = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.4
|
||||
|
||||
Sets the size of the byte array to \a newSize bytes.
|
||||
|
||||
If \a newSize is greater than the current size, the byte array is
|
||||
extended to make it \a newSize bytes with the extra bytes added to
|
||||
the end. The new bytes are initialized to \a c.
|
||||
|
||||
If \a newSize is less than the current size, bytes beyond position
|
||||
\a newSize are excluded from the byte array.
|
||||
|
||||
\note While resize() will grow the capacity if needed, it never shrinks
|
||||
capacity. To shed excess capacity, use squeeze().
|
||||
|
||||
\sa size(), truncate(), squeeze()
|
||||
*/
|
||||
void QByteArray::resize(qsizetype newSize, char c)
|
||||
{
|
||||
const auto old = d.size;
|
||||
resize(newSize);
|
||||
if (old < d.size)
|
||||
memset(d.data() + old, c, d.size - old);
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets every byte in the byte array to \a ch. If \a size is different from -1
|
||||
(the default), the byte array is resized to size \a size beforehand.
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ public:
|
|||
|
||||
bool isEmpty() const noexcept { return size() == 0; }
|
||||
void resize(qsizetype size);
|
||||
void resize(qsizetype size, char c);
|
||||
|
||||
QByteArray &fill(char c, qsizetype size = -1);
|
||||
|
||||
|
|
|
|||
|
|
@ -237,9 +237,9 @@ protected:
|
|||
}
|
||||
|
||||
void append_impl(qsizetype prealloc, void *array, const T *buf, qsizetype n);
|
||||
void reallocate_impl(qsizetype prealloc, void *array, qsizetype size, qsizetype alloc);
|
||||
void resize_impl(qsizetype prealloc, void *array, qsizetype sz)
|
||||
{ reallocate_impl(prealloc, array, sz, qMax(sz, capacity())); }
|
||||
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); }
|
||||
|
||||
bool isValidIterator(const const_iterator &i) const
|
||||
{
|
||||
|
|
@ -393,6 +393,14 @@ public:
|
|||
}
|
||||
bool isEmpty() const { return empty(); }
|
||||
void resize(qsizetype sz) { Base::resize_impl(Prealloc, this->array, sz); }
|
||||
#ifdef Q_QDOC
|
||||
void
|
||||
#else
|
||||
template <typename U = T>
|
||||
std::enable_if_t<std::is_copy_constructible_v<U>>
|
||||
#endif
|
||||
resize(qsizetype sz, const T &v)
|
||||
{ Base::resize_impl(Prealloc, this->array, sz, &v); }
|
||||
inline void clear() { resize(0); }
|
||||
void squeeze() { reallocate(size(), size()); }
|
||||
|
||||
|
|
@ -720,7 +728,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)
|
||||
Q_OUTOFLINE_TEMPLATE void QVLABase<T>::reallocate_impl(qsizetype prealloc, void *array, qsizetype asize, qsizetype aalloc, const T *v)
|
||||
{
|
||||
Q_ASSERT(aalloc >= asize);
|
||||
Q_ASSERT(data());
|
||||
|
|
@ -765,7 +773,16 @@ Q_OUTOFLINE_TEMPLATE void QVLABase<T>::reallocate_impl(qsizetype prealloc, void
|
|||
if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != data())
|
||||
free(oldPtr);
|
||||
|
||||
if constexpr (QTypeInfo<T>::isComplex) {
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -245,6 +245,19 @@
|
|||
\sa size(), squeeze()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template<class T, qsizetype Prealloc> void QVarLengthArray<T, Prealloc>::resize(qsizetype size, const T &v)
|
||||
\since 6.4
|
||||
|
||||
Sets the size of the array to \a size. If \a size is greater than
|
||||
the current size, copies of \a v are added to the end. If \a size is
|
||||
less than the current size, elements are removed from the end.
|
||||
|
||||
\note This function is only available when \c T is copy-constructible.
|
||||
|
||||
\sa size(), squeeze()
|
||||
*/
|
||||
|
||||
/*! \fn template<class T, qsizetype Prealloc> qsizetype QVarLengthArray<T, Prealloc>::capacity() const
|
||||
|
||||
Returns the maximum number of elements that can be stored in the
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ private slots:
|
|||
void reserve();
|
||||
void reserveExtended_data();
|
||||
void reserveExtended();
|
||||
void resize();
|
||||
void movablity_data();
|
||||
void movablity();
|
||||
void literals();
|
||||
|
|
@ -2091,6 +2092,23 @@ void tst_QByteArray::reserveExtended()
|
|||
QCOMPARE(array.capacity(), array.size());
|
||||
}
|
||||
|
||||
void tst_QByteArray::resize()
|
||||
{
|
||||
QByteArray ba;
|
||||
ba.resize(15);
|
||||
QCOMPARE(ba.size(), qsizetype(15));
|
||||
ba.resize(10);
|
||||
QCOMPARE(ba.size(), 10);
|
||||
ba.resize(0);
|
||||
QCOMPARE(ba.size(), 0);
|
||||
ba.resize(5, 'a');
|
||||
QCOMPARE(ba.size(), 5);
|
||||
QCOMPARE(ba, "aaaaa");
|
||||
ba.resize(10, 'b');
|
||||
QCOMPARE(ba.size(), 10);
|
||||
QCOMPARE(ba, "aaaaabbbbb");
|
||||
}
|
||||
|
||||
void tst_QByteArray::movablity_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("array");
|
||||
|
|
|
|||
|
|
@ -345,6 +345,17 @@ private Q_SLOTS:
|
|||
void ranged_ctor_QMultiHash_Movable() { ranged_ctor_associative_impl<QMultiHash<Movable, int>>(); }
|
||||
void ranged_ctor_QMultiHash_Complex() { ranged_ctor_associative_impl<QMultiHash<Complex, int>>(); }
|
||||
|
||||
private:
|
||||
template <typename Container>
|
||||
void resize_impl() const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void resize_std_vector() { resize_impl<std::vector<int>>(); }
|
||||
void resize_QList() { resize_impl<QList<qintptr>>(); }
|
||||
void resize_QVarLengthArray() { resize_impl<QVarLengthArray<int>>(); }
|
||||
void resize_QString() { resize_impl<QString>(); }
|
||||
void resize_QByteArray() { resize_impl<QByteArray>(); }
|
||||
|
||||
private:
|
||||
template <typename Container>
|
||||
void front_back_impl() const;
|
||||
|
|
@ -729,6 +740,18 @@ template <> QByteArray make(int size) { return QByteArray("\1\2\3\4\5\6\7", s
|
|||
template <typename T> T clean(T &&t) { return std::forward<T>(t); }
|
||||
inline char clean(QLatin1Char ch) { return ch.toLatin1(); }
|
||||
|
||||
template <typename Container>
|
||||
void tst_ContainerApiSymmetry::resize_impl() const
|
||||
{
|
||||
using V = typename Container::value_type;
|
||||
using S = typename Container::size_type;
|
||||
auto c = make<Container>(3);
|
||||
QCOMPARE(c.size(), S(3));
|
||||
c.resize(4, V(5));
|
||||
QCOMPARE(c.size(), S(4));
|
||||
QCOMPARE(c.back(), V(5));
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
void tst_ContainerApiSymmetry::front_back_impl() const
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue