QDebug: reduce template bloat

When streaming non-Q_FLAG QFlags, factor the common code
into a helper function only templated on QFlags<T>::Int
and pass what varies as parameters.

Then overload the helper function for the most common int
type (int) as an out-of-line function, implemented via the
primary template to avoid the two going out of sync.

That leaves the primary helper template only for special
cases (such as future extensions).

Change-Id: I70e0001bcfacab9f8765c9b1075fe80b596223f1
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
Marc Mutz 2015-11-28 10:57:51 +01:00
parent 88d7c8f963
commit ca1f842158
2 changed files with 35 additions and 14 deletions

View File

@ -867,6 +867,19 @@ QDebugStateSaver::~QDebugStateSaver()
d->restoreState(); d->restoreState();
} }
/*!
\internal
Specialization of the primary template in qdebug.h to out-of-line
the common case of QFlags<T>::Int being int.
Just call the generic version so the two don't get out of sync.
*/
void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, int value)
{
qt_QMetaEnum_flagDebugOperator<int>(debug, sizeofT, value);
}
#ifndef QT_NO_QOBJECT #ifndef QT_NO_QOBJECT
/*! /*!
\internal \internal

View File

@ -323,6 +323,27 @@ inline QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache)
return debug.maybeSpace(); return debug.maybeSpace();
} }
Q_CORE_EXPORT void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, int value);
template <typename Int>
void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, Int value)
{
const QDebugStateSaver saver(debug);
debug.resetFormat();
debug.nospace() << "QFlags(" << hex << showbase;
bool needSeparator = false;
for (uint i = 0; i < sizeofT * 8; ++i) {
if (value & (Int(1) << i)) {
if (needSeparator)
debug << '|';
else
needSeparator = true;
debug << (Int(1) << i);
}
}
debug << ')';
}
#if !defined(QT_NO_QOBJECT) && !defined(Q_QDOC) #if !defined(QT_NO_QOBJECT) && !defined(Q_QDOC)
Q_CORE_EXPORT QDebug qt_QMetaEnum_debugOperator(QDebug&, int value, const QMetaObject *meta, const char *name); Q_CORE_EXPORT QDebug qt_QMetaEnum_debugOperator(QDebug&, int value, const QMetaObject *meta, const char *name);
Q_CORE_EXPORT QDebug qt_QMetaEnum_flagDebugOperator(QDebug &dbg, quint64 value, const QMetaObject *meta, const char *name); Q_CORE_EXPORT QDebug qt_QMetaEnum_flagDebugOperator(QDebug &dbg, quint64 value, const QMetaObject *meta, const char *name);
@ -357,20 +378,7 @@ template <class T>
inline QDebug qt_QMetaEnum_flagDebugOperator_helper(QDebug debug, const QFlags<T> &flags) inline QDebug qt_QMetaEnum_flagDebugOperator_helper(QDebug debug, const QFlags<T> &flags)
#endif #endif
{ {
QDebugStateSaver saver(debug); qt_QMetaEnum_flagDebugOperator(debug, sizeof(T), typename QFlags<T>::Int(flags));
debug.resetFormat();
debug.nospace() << "QFlags(" << hex << showbase;
bool needSeparator = false;
for (uint i = 0; i < sizeof(T) * 8; ++i) {
if (flags.testFlag(T(1 << i))) {
if (needSeparator)
debug << '|';
else
needSeparator = true;
debug << (typename QFlags<T>::Int(1) << i);
}
}
debug << ')';
return debug; return debug;
} }