Merge remote-tracking branch 'origin/master' into api_changes
[profile/ivi/qtbase.git] / src / corelib / tools / qstringbuilder.h
index 709d84a..9a1fd69 100644 (file)
@@ -1,8 +1,7 @@
 /****************************************************************************
 **
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
 **
 ** This file is part of the QtCore module of the Qt Toolkit.
 **
@@ -35,6 +34,7 @@
 **
 **
 **
+**
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/
 #ifndef QSTRINGBUILDER_H
 #define QSTRINGBUILDER_H
 
+#if 0
+// syncqt can not handle the templates in this file, and it doesn't need to
+// process them anyway because they are internal.
+#pragma qt_class(QStringBuilder)
+#pragma qt_sync_stop_processing
+#endif
+
 #include <QtCore/qstring.h>
 #include <QtCore/qbytearray.h>
 
-#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL)
-#  if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)
-#    include <QtCore/qmap.h>
-#  endif
-#endif
-
 #include <string.h>
 
 QT_BEGIN_HEADER
 
 QT_BEGIN_NAMESPACE
 
-QT_MODULE(Core)
-
-// ### Qt 5: merge with QLatin1String
-class QLatin1Literal
-{
-public:
-    int size() const { return m_size; }
-    const char *data() const { return m_data; }
-
-    template <int N>
-    QLatin1Literal(const char (&str)[N])
-        : m_size(N - 1), m_data(str) {}
-
-private:
-    const int m_size;
-    const char * const m_data;
-};
 
 struct Q_CORE_EXPORT QAbstractConcatenable
 {
 protected:
     static void convertFromAscii(const char *a, int len, QChar *&out);
-    static void convertToAscii(const QChar *a, int len, char *&out);
     static inline void convertFromAscii(char a, QChar *&out)
     {
-#ifndef QT_NO_TEXTCODEC
-        if (QString::codecForCStrings)
-            *out++ = QChar::fromAscii(a);
-        else
-#endif
-            *out++ = QLatin1Char(a);
+        *out++ = QLatin1Char(a);
     }
+};
 
-    static inline void convertToAscii(QChar a, char *&out)
-    {
-#ifndef QT_NO_TEXTCODEC
-        if (QString::codecForCStrings)
-            *out++ = a.toAscii(); //###
-        else
-#endif
-            convertToLatin1(a, out);
-    }
+template <typename T> struct QConcatenable {};
 
-    static inline void convertToLatin1(QChar a, char *&out)
-    {
-        *out++ = a.unicode() > 0xff ? '?' : char(a.unicode());
-    }
+namespace QtStringBuilder {
+    template <typename A, typename B> struct ConvertToTypeHelper
+    { typedef A ConvertTo; };
+    template <typename T> struct ConvertToTypeHelper<T, QString>
+    { typedef QString ConvertTo; };
+}
+
+template<typename Builder, typename T>
+struct QStringBuilderCommon
+{
+    T toUpper() const { return resolved().toUpper(); }
+    T toLower() const { return resolved().toLower(); }
+
+protected:
+    const T resolved() const { return *static_cast<const Builder*>(this); }
 };
 
-template <typename T> struct QConcatenable {};
+template<typename Builder, typename T>
+struct QStringBuilderBase : public QStringBuilderCommon<Builder, T>
+{
+};
+
+template<typename Builder>
+struct QStringBuilderBase<Builder, QString> : public QStringBuilderCommon<Builder, QString>
+{
+    QByteArray toLatin1() const { return this->resolved().toLatin1(); }
+    QByteArray toLocal8Bit() const { return this->resolved().toLocal8Bit(); }
+};
 
 template <typename A, typename B>
-class QStringBuilder
+class QStringBuilder : public QStringBuilderBase<QStringBuilder<A, B>, typename QtStringBuilder::ConvertToTypeHelper<typename QConcatenable<A>::ConvertTo, typename QConcatenable<B>::ConvertTo>::ConvertTo>
 {
 public:
     QStringBuilder(const A &a_, const B &b_) : a(a_), b(b_) {}
@@ -138,7 +130,6 @@ private:
 public:
     operator ConvertTo() const { return convertTo<ConvertTo>(); }
 
-    QByteArray toLatin1() const { return convertTo<QString>().toLatin1(); }
     int size() const { return Concatenable::size(*this); }
 
     const A &a;
@@ -146,21 +137,20 @@ public:
 };
 
 template <>
-class QStringBuilder <QString, QString>
+class QStringBuilder <QString, QString> : public QStringBuilderBase<QStringBuilder<QString, QString>, QString>
 {
     public:
         QStringBuilder(const QString &a_, const QString &b_) : a(a_), b(b_) {}
 
         operator QString() const
         { QString r(a); r += b; return r; }
-        QByteArray toLatin1() const { return QString(*this).toLatin1(); }
 
         const QString &a;
         const QString &b;
 };
 
 template <>
-class QStringBuilder <QByteArray, QByteArray>
+class QStringBuilder <QByteArray, QByteArray> : public QStringBuilderBase<QStringBuilder<QByteArray, QByteArray>, QByteArray>
 {
     public:
         QStringBuilder(const QByteArray &a_, const QByteArray &b_) : a(a_), b(b_) {}
@@ -209,10 +199,16 @@ template <> struct QConcatenable<QChar> : private QAbstractConcatenable
     static int size(const QChar) { return 1; }
     static inline void appendTo(const QChar c, QChar *&out)
     { *out++ = c; }
-#ifndef QT_NO_CAST_TO_ASCII
-    static inline QT_ASCII_CAST_WARN void appendTo(const QChar c, char *&out)
-    { convertToAscii(c, out); }
-#endif
+};
+
+template <> struct QConcatenable<QChar::SpecialCharacter> : private QAbstractConcatenable
+{
+    typedef QChar::SpecialCharacter type;
+    typedef QString ConvertTo;
+    enum { ExactSize = true };
+    static int size(const QChar::SpecialCharacter) { return 1; }
+    static inline void appendTo(const QChar::SpecialCharacter c, QChar *&out)
+    { *out++ = c; }
 };
 
 template <> struct QConcatenable<QCharRef> : private QAbstractConcatenable
@@ -223,10 +219,6 @@ template <> struct QConcatenable<QCharRef> : private QAbstractConcatenable
     static int size(const QCharRef &) { return 1; }
     static inline void appendTo(const QCharRef &c, QChar *&out)
     { *out++ = QChar(c); }
-#ifndef QT_NO_CAST_TO_ASCII
-    static inline QT_ASCII_CAST_WARN void appendTo(const QCharRef &c, char *&out)
-    { convertToAscii(c, out); }
-#endif
 };
 
 template <> struct QConcatenable<QLatin1String>
@@ -234,31 +226,13 @@ template <> struct QConcatenable<QLatin1String>
     typedef QLatin1String type;
     typedef QString ConvertTo;
     enum { ExactSize = true };
-    static int size(const QLatin1String &a) { return qstrlen(a.latin1()); }
+    static int size(const QLatin1String &a) { return a.size(); }
     static inline void appendTo(const QLatin1String &a, QChar *&out)
     {
-        for (const char *s = a.latin1(); *s; )
-            *out++ = QLatin1Char(*s++);
-    }
-    static inline void appendTo(const QLatin1String &a, char *&out)
-    {
-        for (const char *s = a.latin1(); *s; )
-            *out++ = *s++;
-    }
-};
-
-template <> struct QConcatenable<QLatin1Literal>
-{
-    typedef QLatin1Literal type;
-    typedef QString ConvertTo;
-    enum { ExactSize = true };
-    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++);
     }
-    static inline void appendTo(const QLatin1Literal &a, char *&out)
+    static inline void appendTo(const QLatin1String &a, char *&out)
     {
         for (const char *s = a.data(); *s; )
             *out++ = *s++;
@@ -277,10 +251,19 @@ template <> struct QConcatenable<QString> : private QAbstractConcatenable
         memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
         out += n;
     }
-#ifndef QT_NO_CAST_TO_ASCII
-    static inline QT_ASCII_CAST_WARN void appendTo(const QString &a, char *&out)
-    { convertToAscii(a.constData(), a.length(), out); }
-#endif
+};
+
+template <> struct QConcatenable<QStringDataPtr> : private QAbstractConcatenable
+{
+    typedef QStringDataPtr type;
+    typedef QString ConvertTo;
+    enum { ExactSize = true };
+    static int size(const type &a) { return a.ptr->size; }
+    static inline void appendTo(const type &a, QChar *&out)
+    {
+        memcpy(out, reinterpret_cast<const char*>(a.ptr->data()), sizeof(QChar) * a.ptr->size);
+        out += a.ptr->size;
+    }
 };
 
 template <> struct QConcatenable<QStringRef> : private QAbstractConcatenable
@@ -295,11 +278,6 @@ template <> struct QConcatenable<QStringRef> : private QAbstractConcatenable
         memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
         out += n;
     }
-#ifndef QT_NO_CAST_TO_ASCII
-    static inline QT_ASCII_CAST_WARN void appendTo(const QStringRef &a, char *&out)
-    { convertToAscii(a.constData(), a.length(), out); }
-#endif
-
 };
 
 template <int N> struct QConcatenable<char[N]> : private QAbstractConcatenable
@@ -311,7 +289,7 @@ template <int N> struct QConcatenable<char[N]> : private QAbstractConcatenable
 #ifndef QT_NO_CAST_FROM_ASCII
     static inline void QT_ASCII_CAST_WARN appendTo(const char a[N], QChar *&out)
     {
-        QAbstractConcatenable::convertFromAscii(a, N, out);
+        QAbstractConcatenable::convertFromAscii(a, N - 1, out);
     }
 #endif
     static inline void appendTo(const char a[N], char *&out)
@@ -330,7 +308,7 @@ template <int N> struct QConcatenable<const char[N]> : private QAbstractConcaten
 #ifndef QT_NO_CAST_FROM_ASCII
     static inline void QT_ASCII_CAST_WARN appendTo(const char a[N], QChar *&out)
     {
-        QAbstractConcatenable::convertFromAscii(a, N, out);
+        QAbstractConcatenable::convertFromAscii(a, N - 1, out);
     }
 #endif
     static inline void appendTo(const char a[N], char *&out)
@@ -352,6 +330,8 @@ template <> struct QConcatenable<const char *> : private QAbstractConcatenable
 #endif
     static inline void appendTo(const char *a, char *&out)
     {
+        if (!a)
+            return;
         while (*a)
             *out++ = *a++;
     }
@@ -364,10 +344,9 @@ template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
     enum { ExactSize = false };
     static int size(const QByteArray &ba) { return ba.size(); }
 #ifndef QT_NO_CAST_FROM_ASCII
-    static inline void appendTo(const QByteArray &ba, QChar *&out)
+    static inline QT_ASCII_CAST_WARN void appendTo(const QByteArray &ba, QChar *&out)
     {
-        // adding 1 because convertFromAscii expects the size including the null-termination
-        QAbstractConcatenable::convertFromAscii(ba.constData(), ba.size() + 1, out);
+        QAbstractConcatenable::convertFromAscii(ba.constData(), ba.size(), out);
     }
 #endif
     static inline void appendTo(const QByteArray &ba, char *&out)
@@ -379,12 +358,24 @@ template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
     }
 };
 
-namespace QtStringBuilder {
-    template <typename A, typename B> struct ConvertToTypeHelper
-    { typedef A ConvertTo; };
-    template <typename T> struct ConvertToTypeHelper<T, QString>
-    { typedef QString ConvertTo; };
-}
+template <> struct QConcatenable<QByteArrayDataPtr> : private QAbstractConcatenable
+{
+    typedef QByteArrayDataPtr type;
+    typedef QByteArray ConvertTo;
+    enum { ExactSize = false };
+    static int size(const type &ba) { return ba.ptr->size; }
+#ifndef QT_NO_CAST_FROM_ASCII
+    static inline QT_ASCII_CAST_WARN void appendTo(const type &a, QChar *&out)
+    {
+        QAbstractConcatenable::convertFromAscii(a.ptr->data(), a.ptr->size, out);
+    }
+#endif
+    static inline void appendTo(const type &ba, char *&out)
+    {
+        ::memcpy(out, ba.ptr->data(), ba.ptr->size);
+        out += ba.ptr->size;
+    }
+};
 
 template <typename A, typename B>
 struct QConcatenable< QStringBuilder<A, B> >