QArrayDataPointer: add an allocating constructor
It's by far the most common use, so having to call two things is just cumbersome. Change-Id: I79e700614d034281bf55fffd178f454c4e31929e Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
793cfec941
commit
2fd0996324
@ -685,7 +685,7 @@ QByteArray qCompress(const uchar* data, qsizetype nbytes, int compressionLevel)
|
||||
if (nbytes < SingleAllocLimit) {
|
||||
// use maximum size
|
||||
capacity += compressBound(uLong(nbytes)); // cannot overflow (both times)!
|
||||
return QArrayDataPointer{QTypedArrayData<char>::allocate(capacity)};
|
||||
return QArrayDataPointer<char>(capacity);
|
||||
}
|
||||
|
||||
// for larger buffers, assume it compresses optimally, and
|
||||
@ -695,7 +695,7 @@ QByteArray qCompress(const uchar* data, qsizetype nbytes, int compressionLevel)
|
||||
// but use a nearby power-of-two (faster)
|
||||
capacity += std::max(qsizetype(compressBound(uLong(SingleAllocLimit))),
|
||||
nbytes / MaxCompressionFactor);
|
||||
return QArrayDataPointer{QTypedArrayData<char>::allocate(capacity, QArrayData::Grow)};
|
||||
return QArrayDataPointer<char>(capacity, 0, QArrayData::Grow);
|
||||
}();
|
||||
|
||||
if (out.data() == nullptr) // allocation failed
|
||||
@ -783,7 +783,7 @@ QByteArray qUncompress(const uchar* data, qsizetype nbytes)
|
||||
qsizetype capacity = std::max(qsizetype(expectedSize), // cannot overflow!
|
||||
nbytes);
|
||||
|
||||
QArrayDataPointer d(QTypedArrayData<char>::allocate(capacity, QArrayData::KeepSize));
|
||||
QArrayDataPointer<char> d(capacity);
|
||||
return xxflate(ZLibOp::Decompression, std::move(d), {data + HeaderSize, nbytes - HeaderSize},
|
||||
[] (z_stream *zs) { return inflateInit(zs); },
|
||||
[] (z_stream *zs, size_t) { return inflate(zs, Z_NO_FLUSH); },
|
||||
@ -1793,7 +1793,7 @@ QByteArray::QByteArray(const char *data, qsizetype size)
|
||||
if (!size) {
|
||||
d = DataPointer::fromRawData(&_empty, 0);
|
||||
} else {
|
||||
d = DataPointer(Data::allocate(size), size);
|
||||
d = DataPointer(size, size);
|
||||
Q_CHECK_PTR(d.data());
|
||||
memcpy(d.data(), data, size);
|
||||
d.data()[size] = '\0';
|
||||
@ -1812,7 +1812,7 @@ QByteArray::QByteArray(qsizetype size, char ch)
|
||||
if (size <= 0) {
|
||||
d = DataPointer::fromRawData(&_empty, 0);
|
||||
} else {
|
||||
d = DataPointer(Data::allocate(size), size);
|
||||
d = DataPointer(size, size);
|
||||
Q_CHECK_PTR(d.data());
|
||||
memset(d.data(), ch, size);
|
||||
d.data()[size] = '\0';
|
||||
@ -1828,7 +1828,7 @@ QByteArray::QByteArray(qsizetype size, Qt::Initialization)
|
||||
if (size <= 0) {
|
||||
d = DataPointer::fromRawData(&_empty, 0);
|
||||
} else {
|
||||
d = DataPointer(Data::allocate(size), size);
|
||||
d = DataPointer(size, size);
|
||||
Q_CHECK_PTR(d.data());
|
||||
d.data()[size] = '\0';
|
||||
}
|
||||
@ -1917,7 +1917,7 @@ void QByteArray::reallocData(qsizetype alloc, QArrayData::AllocationOption optio
|
||||
const bool cannotUseReallocate = d.freeSpaceAtBegin() > 0;
|
||||
|
||||
if (d->needsDetach() || cannotUseReallocate) {
|
||||
DataPointer dd(Data::allocate(alloc, option), qMin(alloc, d.size));
|
||||
DataPointer dd(alloc, qMin(alloc, d.size), option);
|
||||
Q_CHECK_PTR(dd.data());
|
||||
if (dd.size > 0)
|
||||
::memcpy(dd.data(), d.data(), dd.size);
|
||||
|
@ -2492,7 +2492,7 @@ QString::QString(const QChar *unicode, qsizetype size)
|
||||
if (!size) {
|
||||
d = DataPointer::fromRawData(&_empty, 0);
|
||||
} else {
|
||||
d = DataPointer(Data::allocate(size), size);
|
||||
d = DataPointer(size, size);
|
||||
Q_CHECK_PTR(d.data());
|
||||
memcpy(d.data(), unicode, size * sizeof(QChar));
|
||||
d.data()[size] = '\0';
|
||||
@ -2511,7 +2511,7 @@ QString::QString(qsizetype size, QChar ch)
|
||||
if (size <= 0) {
|
||||
d = DataPointer::fromRawData(&_empty, 0);
|
||||
} else {
|
||||
d = DataPointer(Data::allocate(size), size);
|
||||
d = DataPointer(size, size);
|
||||
Q_CHECK_PTR(d.data());
|
||||
d.data()[size] = '\0';
|
||||
char16_t *b = d.data();
|
||||
@ -2532,7 +2532,7 @@ QString::QString(qsizetype size, Qt::Initialization)
|
||||
if (size <= 0) {
|
||||
d = DataPointer::fromRawData(&_empty, 0);
|
||||
} else {
|
||||
d = DataPointer(Data::allocate(size), size);
|
||||
d = DataPointer(size, size);
|
||||
Q_CHECK_PTR(d.data());
|
||||
d.data()[size] = '\0';
|
||||
}
|
||||
@ -2550,7 +2550,7 @@ QString::QString(qsizetype size, Qt::Initialization)
|
||||
*/
|
||||
QString::QString(QChar ch)
|
||||
{
|
||||
d = DataPointer(Data::allocate(1), 1);
|
||||
d = DataPointer(1, 1);
|
||||
Q_CHECK_PTR(d.data());
|
||||
d.data()[0] = ch.unicode();
|
||||
d.data()[1] = '\0';
|
||||
@ -2768,7 +2768,7 @@ void QString::reallocData(qsizetype alloc, QArrayData::AllocationOption option)
|
||||
const bool cannotUseReallocate = d.freeSpaceAtBegin() > 0;
|
||||
|
||||
if (d->needsDetach() || cannotUseReallocate) {
|
||||
DataPointer dd(Data::allocate(alloc, option), qMin(alloc, d.size));
|
||||
DataPointer dd(alloc, qMin(alloc, d.size), option);
|
||||
Q_CHECK_PTR(dd.data());
|
||||
if (dd.size > 0)
|
||||
::memcpy(dd.data(), d.data(), dd.size * sizeof(QChar));
|
||||
@ -5717,7 +5717,7 @@ QString QString::fromLatin1(QByteArrayView ba)
|
||||
} else if (ba.size() == 0) {
|
||||
d = DataPointer::fromRawData(&_empty, 0);
|
||||
} else {
|
||||
d = DataPointer(Data::allocate(ba.size()), ba.size());
|
||||
d = DataPointer(ba.size(), ba.size());
|
||||
Q_CHECK_PTR(d.data());
|
||||
d.data()[ba.size()] = '\0';
|
||||
char16_t *dst = d.data();
|
||||
|
@ -236,7 +236,7 @@ public:
|
||||
if (it == end)
|
||||
return result;
|
||||
|
||||
QPodArrayOps<T> other{ Data::allocate(this->size), this->size };
|
||||
QPodArrayOps<T> other(this->size, this->size);
|
||||
Q_CHECK_PTR(other.data());
|
||||
auto dest = other.begin();
|
||||
// std::uninitialized_copy will fallback to ::memcpy/memmove()
|
||||
|
@ -52,6 +52,13 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
Q_NODISCARD_CTOR explicit
|
||||
QArrayDataPointer(qsizetype alloc, qsizetype n = 0,
|
||||
QArrayData::AllocationOption option = QArrayData::KeepSize)
|
||||
: QArrayDataPointer(Data::allocate(alloc, option), n)
|
||||
{
|
||||
}
|
||||
|
||||
Q_NODISCARD_CTOR
|
||||
static QArrayDataPointer fromRawData(const T *rawData, qsizetype length) noexcept
|
||||
{
|
||||
@ -326,11 +333,11 @@ public:
|
||||
if constexpr (IsFwdIt) {
|
||||
const qsizetype n = std::distance(first, last);
|
||||
if (needsDetach() || n > constAllocatedCapacity()) {
|
||||
QArrayDataPointer allocated(Data::allocate(detachCapacity(n)));
|
||||
QArrayDataPointer allocated(detachCapacity(n));
|
||||
swap(allocated);
|
||||
}
|
||||
} else if (needsDetach()) {
|
||||
QArrayDataPointer allocated(Data::allocate(allocatedCapacity()));
|
||||
QArrayDataPointer allocated(allocatedCapacity());
|
||||
swap(allocated);
|
||||
// We don't want to copy data that we know we'll overwrite
|
||||
}
|
||||
|
@ -276,20 +276,20 @@ public:
|
||||
public:
|
||||
QList() = default;
|
||||
explicit QList(qsizetype size)
|
||||
: d(Data::allocate(size))
|
||||
: d(size)
|
||||
{
|
||||
if (size)
|
||||
d->appendInitialize(size);
|
||||
}
|
||||
QList(qsizetype size, parameter_type t)
|
||||
: d(Data::allocate(size))
|
||||
: d(size)
|
||||
{
|
||||
if (size)
|
||||
d->copyAppend(size, t);
|
||||
}
|
||||
|
||||
inline QList(std::initializer_list<T> args)
|
||||
: d(Data::allocate(qsizetype(args.size())))
|
||||
: d(qsizetype(args.size()))
|
||||
{
|
||||
if (args.size())
|
||||
d->copyAppend(args.begin(), args.end());
|
||||
@ -308,7 +308,7 @@ public:
|
||||
} else {
|
||||
const auto distance = std::distance(i1, i2);
|
||||
if (distance) {
|
||||
d = DataPointer(Data::allocate(qsizetype(distance)));
|
||||
d = DataPointer(qsizetype(distance));
|
||||
// appendIteratorRange can deal with contiguous iterators on its own,
|
||||
// this is an optimization for C++17 code.
|
||||
if constexpr (std::is_same_v<std::decay_t<InputIterator>, iterator> ||
|
||||
@ -424,7 +424,7 @@ public:
|
||||
return;
|
||||
if (d->needsDetach()) {
|
||||
// must allocate memory
|
||||
DataPointer detached(Data::allocate(d.allocatedCapacity()));
|
||||
DataPointer detached(d.allocatedCapacity());
|
||||
d.swap(detached);
|
||||
} else {
|
||||
d->truncate(0);
|
||||
@ -747,7 +747,7 @@ void QList<T>::reserve(qsizetype asize)
|
||||
}
|
||||
}
|
||||
|
||||
DataPointer detached(Data::allocate(qMax(asize, size())));
|
||||
DataPointer detached(qMax(asize, size()));
|
||||
detached->copyAppend(d->begin(), d->end());
|
||||
if (detached.d_ptr())
|
||||
detached->setFlag(Data::CapacityReserved);
|
||||
@ -761,7 +761,7 @@ inline void QList<T>::squeeze()
|
||||
return;
|
||||
if (d->needsDetach() || size() < capacity()) {
|
||||
// must allocate memory
|
||||
DataPointer detached(Data::allocate(size()));
|
||||
DataPointer detached(size());
|
||||
if (size()) {
|
||||
if (d.needsDetach())
|
||||
detached->copyAppend(d.data(), d.data() + d.size);
|
||||
@ -890,7 +890,7 @@ inline QList<T> &QList<T>::fill(parameter_type t, qsizetype newSize)
|
||||
newSize = size();
|
||||
if (d->needsDetach() || newSize > capacity()) {
|
||||
// must allocate memory
|
||||
DataPointer detached(Data::allocate(d->detachCapacity(newSize)));
|
||||
DataPointer detached(d->detachCapacity(newSize));
|
||||
detached->copyAppend(newSize, t);
|
||||
d.swap(detached);
|
||||
} else {
|
||||
@ -972,7 +972,7 @@ inline QList<T> QList<T>::mid(qsizetype pos, qsizetype len) const
|
||||
}
|
||||
|
||||
// Allocate memory
|
||||
DataPointer copied(Data::allocate(l));
|
||||
DataPointer copied(l);
|
||||
copied->copyAppend(data() + p, data() + p + l);
|
||||
return copied;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
}
|
||||
|
||||
explicit SimpleVector(size_t n, bool capacityReserved = false)
|
||||
: d(Data::allocate(n))
|
||||
: d(n)
|
||||
{
|
||||
if (n)
|
||||
d->appendInitialize(n);
|
||||
@ -37,7 +37,7 @@ public:
|
||||
}
|
||||
|
||||
SimpleVector(size_t n, const T &t, bool capacityReserved = false)
|
||||
: d(Data::allocate(n))
|
||||
: d(n)
|
||||
{
|
||||
if (n)
|
||||
d->copyAppend(n, t);
|
||||
@ -46,7 +46,7 @@ public:
|
||||
}
|
||||
|
||||
SimpleVector(const T *begin, const T *end, bool capacityReserved = false)
|
||||
: d(Data::allocate(end - begin))
|
||||
: d(end - begin)
|
||||
{
|
||||
if (end - begin)
|
||||
d->copyAppend(begin, end);
|
||||
@ -59,11 +59,6 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
explicit SimpleVector(QPair<Data*, T*> ptr, size_t len = 0)
|
||||
: d(ptr, len)
|
||||
{
|
||||
}
|
||||
|
||||
SimpleVector(const QArrayDataPointer<T> &other)
|
||||
: d(other)
|
||||
{
|
||||
@ -135,7 +130,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
SimpleVector detached(Data::allocate(qMax(n, size())));
|
||||
SimpleVector detached(DataPointer(qMax(n, size())));
|
||||
if (size()) {
|
||||
detached.d->copyAppend(constBegin(), constEnd());
|
||||
detached.d->setFlag(QArrayData::CapacityReserved);
|
||||
@ -149,7 +144,7 @@ public:
|
||||
return;
|
||||
|
||||
if (d->needsDetach() || newSize > capacity()) {
|
||||
SimpleVector detached(Data::allocate(d->detachCapacity(newSize)));
|
||||
SimpleVector detached(DataPointer(d->detachCapacity(newSize)));
|
||||
if (newSize) {
|
||||
if (newSize < size()) {
|
||||
const T *const begin = constBegin();
|
||||
@ -223,7 +218,7 @@ public:
|
||||
const T *const end = begin + d->size;
|
||||
|
||||
if (d->needsDetach()) {
|
||||
SimpleVector detached(Data::allocate(d->detachCapacity(size() - (last - first))));
|
||||
SimpleVector detached(DataPointer(d->detachCapacity(size() - (last - first))));
|
||||
if (first != begin)
|
||||
detached.d->copyAppend(begin, first);
|
||||
detached.d->copyAppend(last, end);
|
||||
|
@ -1116,8 +1116,7 @@ void tst_QArrayData::arrayOpsExtra()
|
||||
|
||||
const auto cloneArrayDataPointer = [] (auto &dataPointer, size_t capacity) {
|
||||
using ArrayPointer = std::decay_t<decltype(dataPointer)>;
|
||||
using Type = std::decay_t<typename ArrayPointer::parameter_type>;
|
||||
ArrayPointer copy(QTypedArrayData<Type>::allocate(qsizetype(capacity)));
|
||||
ArrayPointer copy{qsizetype(capacity)};
|
||||
copy->copyAppend(dataPointer.begin(), dataPointer.end());
|
||||
return copy;
|
||||
};
|
||||
@ -2037,7 +2036,7 @@ void tst_QArrayData::dataPointerAllocate()
|
||||
const auto createDataPointer = [] (qsizetype capacity, auto initValue) {
|
||||
using Type = std::decay_t<decltype(initValue)>;
|
||||
Q_UNUSED(initValue);
|
||||
return QArrayDataPointer<Type>(QTypedArrayData<Type>::allocate(capacity));
|
||||
return QArrayDataPointer<Type>(capacity);
|
||||
};
|
||||
|
||||
const auto testRealloc = [&] (qsizetype capacity, qsizetype newSize, auto initValue) {
|
||||
@ -2453,7 +2452,7 @@ void tst_QArrayData::relocateWithExceptions()
|
||||
};
|
||||
|
||||
const auto createDataPointer = [](qsizetype capacity, qsizetype initSize) {
|
||||
QArrayDataPointer<ThrowingType> qadp(QTypedArrayData<ThrowingType>::allocate(capacity));
|
||||
QArrayDataPointer<ThrowingType> qadp(capacity);
|
||||
qadp->appendInitialize(initSize);
|
||||
int i = 0;
|
||||
std::generate(qadp.begin(), qadp.end(), [&i]() { return ThrowingType(i++); });
|
||||
|
Loading…
x
Reference in New Issue
Block a user