QPainter: make Private::d_ptrs a QVLA<unique_ptr>
This way, we remove the impedance mismatch between QPainter::d_ptr (which already is a unique_ptr) and Private::d_ptrs, which still dealt in raw pointers, simplifying the code. Since we're now owning the objects in d_ptrs, add an assertion that d_ptrs is empty on QPainter destruction. Coverity-Id: 425479 Change-Id: I849e80752b4bc5a71aef8d47663c6ffc9fdca9f7 Reviewed-by: Matthias Rauter <matthias.rauter@qt.io> Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
This commit is contained in:
parent
e670a6d77b
commit
3e98657898
@ -247,11 +247,7 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev)
|
|||||||
// the current d_ptr to the shared painter's d_ptr.
|
// the current d_ptr to the shared painter's d_ptr.
|
||||||
sp->save();
|
sp->save();
|
||||||
++sp->d_ptr->refcount;
|
++sp->d_ptr->refcount;
|
||||||
{
|
sp->d_ptr->d_ptrs.push_back(std::move(q->d_ptr));
|
||||||
// ensure realloc happens before the unique_ptr::release():
|
|
||||||
auto &p = sp->d_ptr->d_ptrs.emplace_back();
|
|
||||||
p = q->d_ptr.release();
|
|
||||||
}
|
|
||||||
q->d_ptr.reset(sp->d_ptr.get());
|
q->d_ptr.reset(sp->d_ptr.get());
|
||||||
|
|
||||||
Q_ASSERT(q->d_ptr->state);
|
Q_ASSERT(q->d_ptr->state);
|
||||||
@ -296,19 +292,19 @@ void QPainterPrivate::detachPainterPrivate(QPainter *q)
|
|||||||
Q_ASSERT(q);
|
Q_ASSERT(q);
|
||||||
|
|
||||||
--refcount;
|
--refcount;
|
||||||
QPainterPrivate *original = d_ptrs.back();
|
auto original = std::move(d_ptrs.back());
|
||||||
d_ptrs.pop_back();
|
d_ptrs.pop_back();
|
||||||
if (inDestructor) {
|
if (inDestructor) {
|
||||||
inDestructor = false;
|
inDestructor = false;
|
||||||
if (original)
|
if (original)
|
||||||
original->inDestructor = true;
|
original->inDestructor = true;
|
||||||
} else if (!original) {
|
} else if (!original) {
|
||||||
original = new QPainterPrivate(q);
|
original = std::make_unique<QPainterPrivate>(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
q->restore();
|
q->restore();
|
||||||
Q_UNUSED(q->d_ptr.release());
|
Q_UNUSED(q->d_ptr.release());
|
||||||
q->d_ptr.reset(original);
|
q->d_ptr = std::move(original);
|
||||||
|
|
||||||
if (emulationEngine) {
|
if (emulationEngine) {
|
||||||
extended = emulationEngine->real_engine;
|
extended = emulationEngine->real_engine;
|
||||||
@ -1488,6 +1484,7 @@ QPainter::~QPainter()
|
|||||||
Q_ASSERT(d_ptr->inDestructor);
|
Q_ASSERT(d_ptr->inDestructor);
|
||||||
d_ptr->inDestructor = false;
|
d_ptr->inDestructor = false;
|
||||||
Q_ASSERT(d_ptr->refcount == 1);
|
Q_ASSERT(d_ptr->refcount == 1);
|
||||||
|
Q_ASSERT(d_ptr->d_ptrs.empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ public:
|
|||||||
// redirections within the same paintEvent(), which should be enough
|
// redirections within the same paintEvent(), which should be enough
|
||||||
// in 99% of all cases). E.g: A renders B which renders C which renders D.
|
// in 99% of all cases). E.g: A renders B which renders C which renders D.
|
||||||
static constexpr qsizetype NDPtrs = 4;
|
static constexpr qsizetype NDPtrs = 4;
|
||||||
QVarLengthArray<QPainterPrivate*, NDPtrs> d_ptrs;
|
QVarLengthArray<std::unique_ptr<QPainterPrivate>, NDPtrs> d_ptrs;
|
||||||
|
|
||||||
std::unique_ptr<QPainterState> state;
|
std::unique_ptr<QPainterState> state;
|
||||||
template <typename T, std::size_t N = 8>
|
template <typename T, std::size_t N = 8>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user