QDebug: add nothrow move special member functions

This requires making QDebugStateSaver hold QDebug::Stream directly, not
QDebug by reference, as the referenced object will have been moved from
when ~QDebugStateSaver executes. The stream object, however, will still
be around.

Change-Id: I0ca2eb60cb9b68ea3835d9a9ff5e295d9b1c5fb5
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
Marc Mutz 2019-06-04 12:43:16 +02:00
parent 8c9e41cc78
commit ac608b7bd2
2 changed files with 22 additions and 23 deletions

View File

@ -147,7 +147,7 @@ using QtMiscUtils::fromHex;
// Has been defined in the header / inlined before Qt 5.4
QDebug::~QDebug()
{
if (!--stream->ref) {
if (stream && !--stream->ref) {
if (stream->space && stream->buffer.endsWith(QLatin1Char(' ')))
stream->buffer.chop(1);
if (stream->message_output) {
@ -843,36 +843,34 @@ QDebug &QDebug::resetFormat()
class QDebugStateSaverPrivate
{
public:
QDebugStateSaverPrivate(QDebug &dbg)
: m_dbg(dbg),
m_spaces(dbg.autoInsertSpaces()),
m_flags(0),
m_streamParams(dbg.stream->ts.d_ptr->params)
QDebugStateSaverPrivate(QDebug::Stream *stream)
: m_stream(stream),
m_spaces(stream->space),
m_flags(stream->context.version > 1 ? stream->flags : 0),
m_streamParams(stream->ts.d_ptr->params)
{
if (m_dbg.stream->context.version > 1)
m_flags = m_dbg.stream->flags;
}
void restoreState()
{
const bool currentSpaces = m_dbg.autoInsertSpaces();
const bool currentSpaces = m_stream->space;
if (currentSpaces && !m_spaces)
if (m_dbg.stream->buffer.endsWith(QLatin1Char(' ')))
m_dbg.stream->buffer.chop(1);
if (m_stream->buffer.endsWith(QLatin1Char(' ')))
m_stream->buffer.chop(1);
m_dbg.setAutoInsertSpaces(m_spaces);
m_dbg.stream->ts.d_ptr->params = m_streamParams;
if (m_dbg.stream->context.version > 1)
m_dbg.stream->flags = m_flags;
m_stream->space = m_spaces;
m_stream->ts.d_ptr->params = m_streamParams;
if (m_stream->context.version > 1)
m_stream->flags = m_flags;
if (!currentSpaces && m_spaces)
m_dbg.stream->ts << ' ';
m_stream->ts << ' ';
}
QDebug &m_dbg;
QDebug::Stream *m_stream;
// QDebug state
const bool m_spaces;
int m_flags;
const int m_flags;
// QTextStream state
const QTextStreamPrivate::Params m_streamParams;
@ -886,7 +884,7 @@ public:
\sa QDebug::setAutoInsertSpaces(), QDebug::autoInsertSpaces()
*/
QDebugStateSaver::QDebugStateSaver(QDebug &dbg)
: d(new QDebugStateSaverPrivate(dbg))
: d(new QDebugStateSaverPrivate(dbg.stream))
{
}

View File

@ -65,6 +65,7 @@ QT_BEGIN_NAMESPACE
class Q_CORE_EXPORT QDebug
{
friend class QMessageLogger;
friend class QDebugStateSaver;
friend class QDebugStateSaverPrivate;
struct Stream {
enum { VerbosityShift = 29, VerbosityMask = 0x7 };
@ -114,7 +115,10 @@ public:
inline QDebug(QString *string) : stream(new Stream(string)) {}
inline QDebug(QtMsgType t) : stream(new Stream(t)) {}
inline QDebug(const QDebug &o):stream(o.stream) { ++stream->ref; }
QDebug(QDebug &&other) noexcept : stream{qExchange(other.stream, nullptr)} {}
inline QDebug &operator=(const QDebug &other);
QDebug &operator=(QDebug &&other) noexcept
{ QDebug{std::move(other)}.swap(*this); return *this; }
~QDebug();
inline void swap(QDebug &other) noexcept { qSwap(stream, other.stream); }
@ -203,10 +207,7 @@ public:
inline QDebug &QDebug::operator=(const QDebug &other)
{
if (this != &other) {
QDebug copy(other);
qSwap(stream, copy.stream);
}
QDebug{other}.swap(*this);
return *this;
}