diff --git a/src/libs/utils/qstringbuilder.h b/src/libs/utils/qstringbuilder.h index 7d2f166d711282f13ba7bcf31c4008a4782410c6..7a12ba6c38673ce226fdbf53ea99263133a55d92 100644 --- a/src/libs/utils/qstringbuilder.h +++ b/src/libs/utils/qstringbuilder.h @@ -66,20 +66,6 @@ public: inline int size() const { return m_size; } inline const char *data() const { return m_data; } - operator QString() const - { -#ifdef USE_CHANGED_QSTRING - QString s(m_size, QChar(-1)); -#else - QString s; - s.resize(m_size); -#endif - QChar *d = s.data(); - for (const char *s = m_data; *s; ) - *d++ = QLatin1Char(*s++); - return s; - } - private: const int m_size; const char *m_data; @@ -100,93 +86,106 @@ public: const B &b; }; +// make sure the operator% defined below acts only on types we want to handle. +template <typename T> struct QConcatenable {}; -inline int qStringBuilderSize(const char) { return 1; } - -inline int qStringBuilderSize(const QLatin1Char) { return 1; } - -inline int qStringBuilderSize(const QLatin1String &a) { return qstrlen(a.latin1()); } - -inline int qStringBuilderSize(const QLatin1Literal &a) { return a.size(); } - -inline int qStringBuilderSize(const QString &a) { return a.size(); } - -inline int qStringBuilderSize(const QStringRef &a) { return a.size(); } template <typename A, typename B> -inline int qStringBuilderSize(const QStringBuilder<A, B> &p) +QStringBuilder<A, B>::operator QString() const { - return qStringBuilderSize(p.a) + qStringBuilderSize(p.b); +#ifdef USE_CHANGED_QSTRING + QString s(this->size(), QChar(-1)); +#else + QString s; + s.resize(QConcatenable< QStringBuilder<A, B> >::size(*this)); +#endif + QChar *d = s.data(); + QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d); + return s; } - -inline void qStringBuilderAppend(const char c, QChar *&out) +template <> struct QConcatenable<char> { - *out++ = QLatin1Char(c); -} + typedef char type; + static int size(const char) { return 1; } + static inline void appendTo(const char c, QChar *&out) + { + *out++ = QLatin1Char(c); + } +}; -inline void qStringBuilderAppend(const QLatin1Char c, QChar *&out) +template <> struct QConcatenable<QLatin1Char> { - *out++ = c; -} + typedef QLatin1Char type; + static int size(const QLatin1Char) { return 1; } + static inline void appendTo(const QLatin1Char c, QChar *&out) + { + *out++ = c; + } +}; -inline void qStringBuilderAppend(const QLatin1String &a, QChar *&out) +template <> struct QConcatenable<QLatin1String> { - for (const char *s = a.latin1(); *s; ) - *out++ = QLatin1Char(*s++); -} + typedef QLatin1String type; + static int size(const QLatin1String &a) { return qstrlen(a.latin1()); } + static inline void appendTo(const QLatin1String &a, QChar *&out) + { + for (const char *s = a.latin1(); *s; ) + *out++ = QLatin1Char(*s++); + } -inline void qStringBuilderAppend(QStringRef a, QChar *&out) -{ - const int n = a.size(); - memcpy(out, (char*)a.constData(), sizeof(QChar) * n); - out += n; -} +}; -inline void qStringBuilderAppend(const QString &a, QChar *&out) +template <> struct QConcatenable<QLatin1Literal> { - const int n = a.size(); - memcpy(out, (char*)a.constData(), sizeof(QChar) * n); - out += n; -} + typedef QLatin1Literal type; + static int size(const QLatin1Literal &a) { return a.size(); } + static inline void appendTo(const QLatin1Literal &a, QChar *&out) + { + for (const char *s = a.data(); *s; ) + *out++ = QLatin1Char(*s++); + } +}; -inline void qStringBuilderAppend(const QLatin1Literal &a, QChar *&out) +template <> struct QConcatenable<QString> { - for (const char *s = a.data(); *s; ) - *out++ = QLatin1Char(*s++); -} + typedef QString type; + static int size(const QString &a) { return a.size(); } + static inline void appendTo(const QString &a, QChar *&out) + { + const int n = a.size(); + memcpy(out, (char*)a.constData(), sizeof(QChar) * n); + out += n; + } +}; -template <typename A, typename B> -inline void qStringBuilderAppend(const QStringBuilder<A, B> &p, QChar *&out) +template <> struct QConcatenable<QStringRef> { - qStringBuilderAppend(p.a, out); - qStringBuilderAppend(p.b, out); -} + typedef QStringRef type; + static int size(const QStringRef &a) { return a.size(); } + static inline void appendTo(QStringRef a, QChar *&out) + { + const int n = a.size(); + memcpy(out, (char*)a.constData(), sizeof(QChar) * n); + out += n; + } +}; template <typename A, typename B> -QStringBuilder<A, B>::operator QString() const +struct QConcatenable< QStringBuilder<A, B> > { -#ifdef USE_CHANGED_QSTRING - QString s(this->size(), QChar(-1)); -#else - QString s; - s.resize(qStringBuilderSize(*this)); -#endif - QChar *d = s.data(); - qStringBuilderAppend(*this, d); - return s; -} - -// make sure the operator% defined below acts only on types we want to handle. -template <typename T> struct QConcatenable {}; -template <> struct QConcatenable<QString> { typedef QString type; }; -template <> struct QConcatenable<QLatin1String> { typedef QLatin1String type; }; -template <> struct QConcatenable<QLatin1Literal> { typedef QLatin1Literal type; }; -template <> struct QConcatenable<QLatin1Char> { typedef QLatin1Char type; }; -template <> struct QConcatenable<QStringRef> { typedef QStringRef type; }; -template <typename A, typename B> -struct QConcatenable< QStringBuilder<A, B> > { typedef QStringBuilder<A, B> type; }; + typedef QStringBuilder<A, B> type; + static int size(const type &p) + { + return QConcatenable<A>::size(p.a) + QConcatenable<B>::size(p.b); + } + static inline void appendTo(const QStringBuilder<A, B> &p, QChar *&out) + { + QConcatenable<A>::appendTo(p.a, out); + QConcatenable<B>::appendTo(p.b, out); + } +}; } // namespace