src/corelib/tools/qstringbuilder.h
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
    64 public:
    64 public:
    65     int size() const { return m_size; }
    65     int size() const { return m_size; }
    66     const char *data() const { return m_data; }
    66     const char *data() const { return m_data; }
    67 
    67 
    68     template <int N>
    68     template <int N>
    69     QLatin1Literal(const char (&str)[N]) 
    69     QLatin1Literal(const char (&str)[N])
    70         : m_size(N - 1), m_data(str) {}
    70         : m_size(N - 1), m_data(str) {}
    71 
    71 
    72 private:
    72 private:
    73     const int m_size;
    73     const int m_size;
    74     const char *m_data;
    74     const char *m_data;
    75 };
    75 };
    76 
    76 
       
    77 struct Q_CORE_EXPORT QAbstractConcatenable
       
    78 {
       
    79 protected:
       
    80     static void convertFromAscii(const char *a, int len, QChar *&out);
       
    81 
       
    82     static inline void convertFromAscii(char a, QChar *&out)
       
    83     {
       
    84 #ifndef QT_NO_TEXTCODEC
       
    85         if (QString::codecForCStrings)
       
    86             *out++ = QChar::fromAscii(a);
       
    87         else
       
    88 #endif
       
    89             *out++ = QLatin1Char(a);
       
    90     }
       
    91 };
    77 
    92 
    78 template <typename T> struct QConcatenable {};
    93 template <typename T> struct QConcatenable {};
    79 
    94 
    80 template <typename A, typename B>
    95 template <typename A, typename B>
    81 class QStringBuilder
    96 class QStringBuilder
    85 
   100 
    86     operator QString() const
   101     operator QString() const
    87     {
   102     {
    88         QString s(QConcatenable< QStringBuilder<A, B> >::size(*this),
   103         QString s(QConcatenable< QStringBuilder<A, B> >::size(*this),
    89             Qt::Uninitialized);
   104             Qt::Uninitialized);
    90         
   105 
    91         QChar *d = s.data();
   106         QChar *d = s.data();
    92         QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d);
   107         QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d);
       
   108         // this resize is necessary since we allocate a bit too much
       
   109         // when dealing with variable sized 8-bit encodings
       
   110         s.resize(d - s.data());
    93         return s;
   111         return s;
    94     }
   112     }
    95     QByteArray toLatin1() const { return QString(*this).toLatin1(); }
   113     QByteArray toLatin1() const { return QString(*this).toLatin1(); }
    96 
   114 
    97     const A &a;
   115     const A &a;
    98     const B &b;
   116     const B &b;
    99 };
   117 };
   100 
   118 
   101 
   119 
   102 template <> struct QConcatenable<char>
   120 template <> struct QConcatenable<char> : private QAbstractConcatenable
   103 {
   121 {
   104     typedef char type;
   122     typedef char type;
   105     static int size(const char) { return 1; }
   123     static int size(const char) { return 1; }
   106     static inline void appendTo(const char c, QChar *&out)
   124     static inline void appendTo(const char c, QChar *&out)
   107     {
   125     {
   108         *out++ = QLatin1Char(c);
   126         QAbstractConcatenable::convertFromAscii(c, out);
   109     }
   127     }
   110 };
   128 };
   111 
   129 
   112 template <> struct QConcatenable<QLatin1Char>
   130 template <> struct QConcatenable<QLatin1Char>
   113 {
   131 {
   168     static int size(const QString &a) { return a.size(); }
   186     static int size(const QString &a) { return a.size(); }
   169     static inline void appendTo(const QString &a, QChar *&out)
   187     static inline void appendTo(const QString &a, QChar *&out)
   170     {
   188     {
   171         const int n = a.size();
   189         const int n = a.size();
   172         memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
   190         memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
   173         out += n; 
   191         out += n;
   174     }
   192     }
   175 };
   193 };
   176 
   194 
   177 template <> struct QConcatenable<QStringRef>
   195 template <> struct QConcatenable<QStringRef>
   178 {
   196 {
   180     static int size(const QStringRef &a) { return a.size(); }
   198     static int size(const QStringRef &a) { return a.size(); }
   181     static inline void appendTo(QStringRef a, QChar *&out)
   199     static inline void appendTo(QStringRef a, QChar *&out)
   182     {
   200     {
   183         const int n = a.size();
   201         const int n = a.size();
   184         memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
   202         memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
   185         out += n; 
   203         out += n;
   186     }
   204     }
   187 };
   205 };
   188 
   206 
   189 #ifndef QT_NO_CAST_FROM_ASCII
   207 #ifndef QT_NO_CAST_FROM_ASCII
   190 template <int N> struct QConcatenable<char[N]>
   208 template <int N> struct QConcatenable<char[N]> : private QAbstractConcatenable
   191 {
   209 {
   192     typedef char type[N];
   210     typedef char type[N];
   193     static int size(const char[N]) { return N - 1; }
   211     static int size(const char[N])
       
   212     {
       
   213         return N - 1;
       
   214     }
   194     static inline void appendTo(const char a[N], QChar *&out)
   215     static inline void appendTo(const char a[N], QChar *&out)
   195     {
   216     {
   196         for (int i = 0; i < N - 1; ++i)
   217         QAbstractConcatenable::convertFromAscii(a, N, out);
   197             *out++ = QLatin1Char(a[i]);
   218     }
   198     }
   219 };
   199 };
   220 
   200 
   221 template <int N> struct QConcatenable<const char[N]> : private QAbstractConcatenable
   201 template <int N> struct QConcatenable<const char[N]>
       
   202 {
   222 {
   203     typedef const char type[N];
   223     typedef const char type[N];
   204     static int size(const char[N]) { return N - 1; }
   224     static int size(const char[N]) { return N - 1; }
   205     static inline void appendTo(const char a[N], QChar *&out)
   225     static inline void appendTo(const char a[N], QChar *&out)
   206     {
   226     {
   207         for (int i = 0; i < N - 1; ++i)
   227         QAbstractConcatenable::convertFromAscii(a, N, out);
   208             *out++ = QLatin1Char(a[i]);
   228     }
   209     }
   229 };
   210 };
   230 
   211 
   231 template <> struct QConcatenable<const char *> : private QAbstractConcatenable
   212 template <> struct QConcatenable<const char *>
       
   213 {
   232 {
   214     typedef char const *type;
   233     typedef char const *type;
   215     static int size(const char *a) { return qstrlen(a); }
   234     static int size(const char *a) { return qstrlen(a); }
   216     static inline void appendTo(const char *a, QChar *&out)
   235     static inline void appendTo(const char *a, QChar *&out)
   217     {
   236     {
   218         while (*a)
   237         QAbstractConcatenable::convertFromAscii(a, -1, out);
   219             *out++ = QLatin1Char(*a++);
   238     }
   220     }
   239 };
   221 };
   240 
   222 
   241 template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
   223 template <> struct QConcatenable<QByteArray>
       
   224 {
   242 {
   225     typedef QByteArray type;
   243     typedef QByteArray type;
   226     static int size(const QByteArray &ba) { return qstrnlen(ba.constData(), ba.size()); }
   244     static int size(const QByteArray &ba) { return qstrnlen(ba.constData(), ba.size()); }
   227     static inline void appendTo(const QByteArray &ba, QChar *&out)
   245     static inline void appendTo(const QByteArray &ba, QChar *&out)
   228     {
   246     {
   229         const char *data = ba.constData();
   247         QAbstractConcatenable::convertFromAscii(ba.constData(), -1, out);
   230         while (*data)
       
   231             *out++ = QLatin1Char(*data++);
       
   232     }
   248     }
   233 };
   249 };
   234 #endif
   250 #endif
   235 
   251 
   236 template <typename A, typename B>
   252 template <typename A, typename B>
   237 struct QConcatenable< QStringBuilder<A, B> >
   253 struct QConcatenable< QStringBuilder<A, B> >
   238 {
   254 {
   239     typedef QStringBuilder<A, B> type;
   255     typedef QStringBuilder<A, B> type;
   240     static int size(const type &p) 
   256     static int size(const type &p)
   241     {
   257     {
   242         return QConcatenable<A>::size(p.a) + QConcatenable<B>::size(p.b);
   258         return QConcatenable<A>::size(p.a) + QConcatenable<B>::size(p.b);
   243     }
   259     }
   244     static inline void appendTo(const QStringBuilder<A, B> &p, QChar *&out)
   260     static inline void appendTo(const QStringBuilder<A, B> &p, QChar *&out)
   245     {
   261     {