Commit 39b0da2a authored by hjk's avatar hjk
Browse files

qstringbuilder: move free functions back to class specializations

parent 2a1bfc60
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment