- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files
- Directories
- Examples

- File List
- File Members

# qstringbuilder.h

Go to the documentation of this file.

    00001 /****************************************************************************
    00002 **
    00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    00004 ** All rights reserved.
    00005 ** Contact: Nokia Corporation (qt-info@nokia.com)
    00006 **
    00007 ** This file is part of the QtCore module of the Qt Toolkit.
    00008 **
    00009 ** $QT_BEGIN_LICENSE:LGPL$
    00010 ** Commercial Usage
    00011 ** Licensees holding valid Qt Commercial licenses may use this file in
    00012 ** accordance with the Qt Commercial License Agreement provided with the
    00013 ** Software or, alternatively, in accordance with the terms contained in
    00014 ** a written agreement between you and Nokia.
    00015 **
    00016 ** GNU Lesser General Public License Usage
    00017 ** Alternatively, this file may be used under the terms of the GNU Lesser
    00018 ** General Public License version 2.1 as published by the Free Software
    00019 ** Foundation and appearing in the file LICENSE.LGPL included in the
    00020 ** packaging of this file.  Please review the following information to
    00021 ** ensure the GNU Lesser General Public License version 2.1 requirements
    00022 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    00023 **
    00024 ** In addition, as a special exception, Nokia gives you certain additional
    00025 ** rights.  These rights are described in the Nokia Qt LGPL Exception
    00026 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this module.
    00027 **
    00028 ** GNU General Public License Usage
    00029 ** Alternatively, this file may be used under the terms of the GNU
    00030 ** General Public License version 3.0 as published by the Free Software
    00031 ** Foundation and appearing in the file LICENSE.GPL included in the
    00032 ** packaging of this file.  Please review the following information to
    00033 ** ensure the GNU General Public License version 3.0 requirements will be
    00034 ** met: http://www.gnu.org/copyleft/gpl.html.
    00035 **
    00036 ** If you have questions regarding the use of this file, please contact
    00037 ** Nokia at qt-info@nokia.com.
    00038 ** $QT_END_LICENSE$
    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 // ### Qt 5: merge with QLatin1String
    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             // this resize is necessary since we allocate a bit too much
    00112             // when dealing with variable sized 8-bit encodings
    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