00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef QSTRINGBUILDER_H
00043 #define QSTRINGBUILDER_H
00044
00045 #include <QtCore/qstring.h>
00046
00047 #if defined(Q_CC_GNU) && !defined(Q_CC_INTEL)
00048 # if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)
00049 # include <QtCore/qmap.h>
00050 # endif
00051 #endif
00052
00053 #include <string.h>
00054
00055 QT_BEGIN_HEADER
00056
00057 QT_BEGIN_NAMESPACE
00058
00059 QT_MODULE(Core)
00060
00061
00062 class QLatin1Literal
00063 {
00064 public:
00065 int size() const { return m_size; }
00066 const char *data() const { return m_data; }
00067
00068 template <int N>
00069 QLatin1Literal(const char (&str)[N])
00070 : m_size(N - 1), m_data(str) {}
00071
00072 private:
00073 const int m_size;
00074 const char * const m_data;
00075 };
00076
00077 struct Q_CORE_EXPORT QAbstractConcatenable
00078 {
00079 protected:
00080 static void convertFromAscii(const char *a, int len, QChar *&out);
00081
00082 static inline void convertFromAscii(char a, QChar *&out)
00083 {
00084 #ifndef QT_NO_TEXTCODEC
00085 if (QString::codecForCStrings)
00086 *out++ = QChar::fromAscii(a);
00087 else
00088 #endif
00089 *out++ = QLatin1Char(a);
00090 }
00091 };
00092
00093 template <typename T> struct QConcatenable {};
00094
00095 template <typename A, typename B>
00096 class QStringBuilder
00097 {
00098 public:
00099 QStringBuilder(const A &a_, const B &b_) : a(a_), b(b_) {}
00100
00101 operator QString() const
00102 {
00103 const uint size = QConcatenable< QStringBuilder<A, B> >::size(*this);
00104 QString s(size, Qt::Uninitialized);
00105
00106 QChar *d = s.data();
00107 const QChar * const start = d;
00108 QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d);
00109
00110 if (!QConcatenable< QStringBuilder<A, B> >::ExactSize && int(size) != d - start) {
00111
00112
00113 s.resize(d - start);
00114 }
00115 return s;
00116 }
00117 QByteArray toLatin1() const { return QString(*this).toLatin1(); }
00118
00119 const A &a;
00120 const B &b;
00121 };
00122
00123 template <>
00124 class QStringBuilder <QString, QString>
00125 {
00126 public:
00127 QStringBuilder(const QString &a_, const QString &b_) : a(a_), b(b_) {}
00128
00129 operator QString() const
00130 { QString r(a); r += b; return r; }
00131 QByteArray toLatin1() const { return QString(*this).toLatin1(); }
00132
00133 const QString &a;
00134 const QString &b;
00135 };
00136
00137 template <> struct QConcatenable<char> : private QAbstractConcatenable
00138 {
00139 typedef char type;
00140 enum { ExactSize = true };
00141 static int size(const char) { return 1; }
00142 static inline void appendTo(const char c, QChar *&out)
00143 {
00144 QAbstractConcatenable::convertFromAscii(c, out);
00145 }
00146 };
00147
00148 template <> struct QConcatenable<QLatin1Char>
00149 {
00150 typedef QLatin1Char type;
00151 enum { ExactSize = true };
00152 static int size(const QLatin1Char) { return 1; }
00153 static inline void appendTo(const QLatin1Char c, QChar *&out)
00154 {
00155 *out++ = c;
00156 }
00157 };
00158
00159 template <> struct QConcatenable<QChar>
00160 {
00161 typedef QChar type;
00162 enum { ExactSize = true };
00163 static int size(const QChar) { return 1; }
00164 static inline void appendTo(const QChar c, QChar *&out)
00165 {
00166 *out++ = c;
00167 }
00168 };
00169
00170 template <> struct QConcatenable<QCharRef>
00171 {
00172 typedef QCharRef type;
00173 enum { ExactSize = true };
00174 static int size(const QCharRef &) { return 1; }
00175 static inline void appendTo(const QCharRef &c, QChar *&out)
00176 {
00177 *out++ = QChar(c);
00178 }
00179 };
00180
00181 template <> struct QConcatenable<QLatin1String>
00182 {
00183 typedef QLatin1String type;
00184 enum { ExactSize = true };
00185 static int size(const QLatin1String &a) { return qstrlen(a.latin1()); }
00186 static inline void appendTo(const QLatin1String &a, QChar *&out)
00187 {
00188 for (const char *s = a.latin1(); *s; )
00189 *out++ = QLatin1Char(*s++);
00190 }
00191
00192 };
00193
00194 template <> struct QConcatenable<QLatin1Literal>
00195 {
00196 typedef QLatin1Literal type;
00197 enum { ExactSize = true };
00198 static int size(const QLatin1Literal &a) { return a.size(); }
00199 static inline void appendTo(const QLatin1Literal &a, QChar *&out)
00200 {
00201 for (const char *s = a.data(); *s; )
00202 *out++ = QLatin1Char(*s++);
00203 }
00204 };
00205
00206 template <> struct QConcatenable<QString>
00207 {
00208 typedef QString type;
00209 enum { ExactSize = true };
00210 static int size(const QString &a) { return a.size(); }
00211 static inline void appendTo(const QString &a, QChar *&out)
00212 {
00213 const int n = a.size();
00214 memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
00215 out += n;
00216 }
00217 };
00218
00219 template <> struct QConcatenable<QStringRef>
00220 {
00221 typedef QStringRef type;
00222 enum { ExactSize = true };
00223 static int size(const QStringRef &a) { return a.size(); }
00224 static inline void appendTo(QStringRef a, QChar *&out)
00225 {
00226 const int n = a.size();
00227 memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
00228 out += n;
00229 }
00230 };
00231
00232 #ifndef QT_NO_CAST_FROM_ASCII
00233 template <int N> struct QConcatenable<char[N]> : private QAbstractConcatenable
00234 {
00235 typedef char type[N];
00236 enum { ExactSize = false };
00237 static int size(const char[N])
00238 {
00239 return N - 1;
00240 }
00241 static inline void appendTo(const char a[N], QChar *&out)
00242 {
00243 QAbstractConcatenable::convertFromAscii(a, N, out);
00244 }
00245 };
00246
00247 template <int N> struct QConcatenable<const char[N]> : private QAbstractConcatenable
00248 {
00249 typedef const char type[N];
00250 enum { ExactSize = false };
00251 static int size(const char[N]) { return N - 1; }
00252 static inline void appendTo(const char a[N], QChar *&out)
00253 {
00254 QAbstractConcatenable::convertFromAscii(a, N, out);
00255 }
00256 };
00257
00258 template <> struct QConcatenable<const char *> : private QAbstractConcatenable
00259 {
00260 typedef char const *type;
00261 enum { ExactSize = false };
00262 static int size(const char *a) { return qstrlen(a); }
00263 static inline void appendTo(const char *a, QChar *&out)
00264 {
00265 QAbstractConcatenable::convertFromAscii(a, -1, out);
00266 }
00267 };
00268
00269 template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
00270 {
00271 typedef QByteArray type;
00272 enum { ExactSize = false };
00273 static int size(const QByteArray &ba) { return qstrnlen(ba.constData(), ba.size()); }
00274 static inline void appendTo(const QByteArray &ba, QChar *&out)
00275 {
00276 QAbstractConcatenable::convertFromAscii(ba.constData(), -1, out);
00277 }
00278 };
00279 #endif
00280
00281 template <typename A, typename B>
00282 struct QConcatenable< QStringBuilder<A, B> >
00283 {
00284 typedef QStringBuilder<A, B> type;
00285 enum { ExactSize = QConcatenable<A>::ExactSize && QConcatenable<B>::ExactSize };
00286 static int size(const type &p)
00287 {
00288 return QConcatenable<A>::size(p.a) + QConcatenable<B>::size(p.b);
00289 }
00290 static inline void appendTo(const QStringBuilder<A, B> &p, QChar *&out)
00291 {
00292 QConcatenable<A>::appendTo(p.a, out);
00293 QConcatenable<B>::appendTo(p.b, out);
00294 }
00295 };
00296
00297 template <typename A, typename B>
00298 QStringBuilder<typename QConcatenable<A>::type, typename QConcatenable<B>::type>
00299 operator%(const A &a, const B &b)
00300 {
00301 return QStringBuilder<typename QConcatenable<A>::type, typename QConcatenable<B>::type>(a, b);
00302 }
00303
00304 #ifdef QT_USE_FAST_OPERATOR_PLUS
00305 template <typename A, typename B>
00306 QStringBuilder<typename QConcatenable<A>::type, typename QConcatenable<B>::type>
00307 operator+(const A &a, const B &b)
00308 {
00309 return QStringBuilder<typename QConcatenable<A>::type, typename QConcatenable<B>::type>(a, b);
00310 }
00311 #endif
00312
00313 QT_END_NAMESPACE
00314
00315 QT_END_HEADER
00316
00317 #endif // QSTRINGBUILDER_H