src/corelib/tools/qstringbuilder.h
changeset 30 5dc02b23752f
parent 18 2f34d5167611
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    98 public:
    98 public:
    99     QStringBuilder(const A &a_, const B &b_) : a(a_), b(b_) {}
    99     QStringBuilder(const A &a_, const B &b_) : a(a_), b(b_) {}
   100 
   100 
   101     operator QString() const
   101     operator QString() const
   102     {
   102     {
   103         QString s(QConcatenable< QStringBuilder<A, B> >::size(*this),
   103         const uint size = QConcatenable< QStringBuilder<A, B> >::size(*this);
   104             Qt::Uninitialized);
   104         QString s(size, Qt::Uninitialized);
   105 
   105 
   106         QChar *d = s.data();
   106         QChar *d = s.data();
       
   107         const QChar * const start = d;
   107         QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d);
   108         QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d);
   108         // this resize is necessary since we allocate a bit too much
   109 
   109         // when dealing with variable sized 8-bit encodings
   110         if (!QConcatenable< QStringBuilder<A, B> >::ExactSize && int(size) != d - start) {
   110         s.resize(d - s.data());
   111             // this resize is necessary since we allocate a bit too much
       
   112             // when dealing with variable sized 8-bit encodings
       
   113             s.resize(d - start);
       
   114         }
   111         return s;
   115         return s;
   112     }
   116     }
   113     QByteArray toLatin1() const { return QString(*this).toLatin1(); }
   117     QByteArray toLatin1() const { return QString(*this).toLatin1(); }
   114 
   118 
   115     const A &a;
   119     const A &a;
   116     const B &b;
   120     const B &b;
   117 };
   121 };
   118 
   122 
       
   123 template <>
       
   124 class QStringBuilder <QString, QString>
       
   125 {
       
   126     public:
       
   127         QStringBuilder(const QString &a_, const QString &b_) : a(a_), b(b_) {}
       
   128 
       
   129         operator QString() const
       
   130         { QString r(a); r += b; return r; }
       
   131         QByteArray toLatin1() const { return QString(*this).toLatin1(); }
       
   132 
       
   133         const QString &a;
       
   134         const QString &b;
       
   135 };
   119 
   136 
   120 template <> struct QConcatenable<char> : private QAbstractConcatenable
   137 template <> struct QConcatenable<char> : private QAbstractConcatenable
   121 {
   138 {
   122     typedef char type;
   139     typedef char type;
       
   140     enum { ExactSize = true };
   123     static int size(const char) { return 1; }
   141     static int size(const char) { return 1; }
   124     static inline void appendTo(const char c, QChar *&out)
   142     static inline void appendTo(const char c, QChar *&out)
   125     {
   143     {
   126         QAbstractConcatenable::convertFromAscii(c, out);
   144         QAbstractConcatenable::convertFromAscii(c, out);
   127     }
   145     }
   128 };
   146 };
   129 
   147 
   130 template <> struct QConcatenable<QLatin1Char>
   148 template <> struct QConcatenable<QLatin1Char>
   131 {
   149 {
   132     typedef QLatin1Char type;
   150     typedef QLatin1Char type;
       
   151     enum { ExactSize = true };
   133     static int size(const QLatin1Char) { return 1; }
   152     static int size(const QLatin1Char) { return 1; }
   134     static inline void appendTo(const QLatin1Char c, QChar *&out)
   153     static inline void appendTo(const QLatin1Char c, QChar *&out)
   135     {
   154     {
   136         *out++ = c;
   155         *out++ = c;
   137     }
   156     }
   138 };
   157 };
   139 
   158 
   140 template <> struct QConcatenable<QChar>
   159 template <> struct QConcatenable<QChar>
   141 {
   160 {
   142     typedef QChar type;
   161     typedef QChar type;
       
   162     enum { ExactSize = true };
   143     static int size(const QChar) { return 1; }
   163     static int size(const QChar) { return 1; }
   144     static inline void appendTo(const QChar c, QChar *&out)
   164     static inline void appendTo(const QChar c, QChar *&out)
   145     {
   165     {
   146         *out++ = c;
   166         *out++ = c;
   147     }
   167     }
   148 };
   168 };
   149 
   169 
   150 template <> struct QConcatenable<QCharRef>
   170 template <> struct QConcatenable<QCharRef>
   151 {
   171 {
   152     typedef QCharRef type;
   172     typedef QCharRef type;
       
   173     enum { ExactSize = true };
   153     static int size(const QCharRef &) { return 1; }
   174     static int size(const QCharRef &) { return 1; }
   154     static inline void appendTo(const QCharRef &c, QChar *&out)
   175     static inline void appendTo(const QCharRef &c, QChar *&out)
   155     {
   176     {
   156         *out++ = QChar(c);
   177         *out++ = QChar(c);
   157     }
   178     }
   158 };
   179 };
   159 
   180 
   160 template <> struct QConcatenable<QLatin1String>
   181 template <> struct QConcatenable<QLatin1String>
   161 {
   182 {
   162     typedef QLatin1String type;
   183     typedef QLatin1String type;
       
   184     enum { ExactSize = true };
   163     static int size(const QLatin1String &a) { return qstrlen(a.latin1()); }
   185     static int size(const QLatin1String &a) { return qstrlen(a.latin1()); }
   164     static inline void appendTo(const QLatin1String &a, QChar *&out)
   186     static inline void appendTo(const QLatin1String &a, QChar *&out)
   165     {
   187     {
   166         for (const char *s = a.latin1(); *s; )
   188         for (const char *s = a.latin1(); *s; )
   167             *out++ = QLatin1Char(*s++);
   189             *out++ = QLatin1Char(*s++);
   170 };
   192 };
   171 
   193 
   172 template <> struct QConcatenable<QLatin1Literal>
   194 template <> struct QConcatenable<QLatin1Literal>
   173 {
   195 {
   174     typedef QLatin1Literal type;
   196     typedef QLatin1Literal type;
       
   197     enum { ExactSize = true };
   175     static int size(const QLatin1Literal &a) { return a.size(); }
   198     static int size(const QLatin1Literal &a) { return a.size(); }
   176     static inline void appendTo(const QLatin1Literal &a, QChar *&out)
   199     static inline void appendTo(const QLatin1Literal &a, QChar *&out)
   177     {
   200     {
   178         for (const char *s = a.data(); *s; )
   201         for (const char *s = a.data(); *s; )
   179             *out++ = QLatin1Char(*s++);
   202             *out++ = QLatin1Char(*s++);
   181 };
   204 };
   182 
   205 
   183 template <> struct QConcatenable<QString>
   206 template <> struct QConcatenable<QString>
   184 {
   207 {
   185     typedef QString type;
   208     typedef QString type;
       
   209     enum { ExactSize = true };
   186     static int size(const QString &a) { return a.size(); }
   210     static int size(const QString &a) { return a.size(); }
   187     static inline void appendTo(const QString &a, QChar *&out)
   211     static inline void appendTo(const QString &a, QChar *&out)
   188     {
   212     {
   189         const int n = a.size();
   213         const int n = a.size();
   190         memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
   214         memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
   193 };
   217 };
   194 
   218 
   195 template <> struct QConcatenable<QStringRef>
   219 template <> struct QConcatenable<QStringRef>
   196 {
   220 {
   197     typedef QStringRef type;
   221     typedef QStringRef type;
       
   222     enum { ExactSize = true };
   198     static int size(const QStringRef &a) { return a.size(); }
   223     static int size(const QStringRef &a) { return a.size(); }
   199     static inline void appendTo(QStringRef a, QChar *&out)
   224     static inline void appendTo(QStringRef a, QChar *&out)
   200     {
   225     {
   201         const int n = a.size();
   226         const int n = a.size();
   202         memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
   227         memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
   206 
   231 
   207 #ifndef QT_NO_CAST_FROM_ASCII
   232 #ifndef QT_NO_CAST_FROM_ASCII
   208 template <int N> struct QConcatenable<char[N]> : private QAbstractConcatenable
   233 template <int N> struct QConcatenable<char[N]> : private QAbstractConcatenable
   209 {
   234 {
   210     typedef char type[N];
   235     typedef char type[N];
       
   236     enum { ExactSize = false };
   211     static int size(const char[N])
   237     static int size(const char[N])
   212     {
   238     {
   213         return N - 1;
   239         return N - 1;
   214     }
   240     }
   215     static inline void appendTo(const char a[N], QChar *&out)
   241     static inline void appendTo(const char a[N], QChar *&out)
   219 };
   245 };
   220 
   246 
   221 template <int N> struct QConcatenable<const char[N]> : private QAbstractConcatenable
   247 template <int N> struct QConcatenable<const char[N]> : private QAbstractConcatenable
   222 {
   248 {
   223     typedef const char type[N];
   249     typedef const char type[N];
       
   250     enum { ExactSize = false };
   224     static int size(const char[N]) { return N - 1; }
   251     static int size(const char[N]) { return N - 1; }
   225     static inline void appendTo(const char a[N], QChar *&out)
   252     static inline void appendTo(const char a[N], QChar *&out)
   226     {
   253     {
   227         QAbstractConcatenable::convertFromAscii(a, N, out);
   254         QAbstractConcatenable::convertFromAscii(a, N, out);
   228     }
   255     }
   229 };
   256 };
   230 
   257 
   231 template <> struct QConcatenable<const char *> : private QAbstractConcatenable
   258 template <> struct QConcatenable<const char *> : private QAbstractConcatenable
   232 {
   259 {
   233     typedef char const *type;
   260     typedef char const *type;
       
   261     enum { ExactSize = false };
   234     static int size(const char *a) { return qstrlen(a); }
   262     static int size(const char *a) { return qstrlen(a); }
   235     static inline void appendTo(const char *a, QChar *&out)
   263     static inline void appendTo(const char *a, QChar *&out)
   236     {
   264     {
   237         QAbstractConcatenable::convertFromAscii(a, -1, out);
   265         QAbstractConcatenable::convertFromAscii(a, -1, out);
   238     }
   266     }
   239 };
   267 };
   240 
   268 
   241 template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
   269 template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
   242 {
   270 {
   243     typedef QByteArray type;
   271     typedef QByteArray type;
       
   272     enum { ExactSize = false };
   244     static int size(const QByteArray &ba) { return qstrnlen(ba.constData(), ba.size()); }
   273     static int size(const QByteArray &ba) { return qstrnlen(ba.constData(), ba.size()); }
   245     static inline void appendTo(const QByteArray &ba, QChar *&out)
   274     static inline void appendTo(const QByteArray &ba, QChar *&out)
   246     {
   275     {
   247         QAbstractConcatenable::convertFromAscii(ba.constData(), -1, out);
   276         QAbstractConcatenable::convertFromAscii(ba.constData(), -1, out);
   248     }
   277     }
   251 
   280 
   252 template <typename A, typename B>
   281 template <typename A, typename B>
   253 struct QConcatenable< QStringBuilder<A, B> >
   282 struct QConcatenable< QStringBuilder<A, B> >
   254 {
   283 {
   255     typedef QStringBuilder<A, B> type;
   284     typedef QStringBuilder<A, B> type;
       
   285     enum { ExactSize = QConcatenable<A>::ExactSize && QConcatenable<B>::ExactSize };
   256     static int size(const type &p)
   286     static int size(const type &p)
   257     {
   287     {
   258         return QConcatenable<A>::size(p.a) + QConcatenable<B>::size(p.b);
   288         return QConcatenable<A>::size(p.a) + QConcatenable<B>::size(p.b);
   259     }
   289     }
   260     static inline void appendTo(const QStringBuilder<A, B> &p, QChar *&out)
   290     static inline void appendTo(const QStringBuilder<A, B> &p, QChar *&out)