/external/mac/Qt/lib/QtCore.framework/Versions/5/Headers/qstringbuilder.h

https://gitlab.com/alvinahmadov2/icq-desktop · C Header · 431 lines · 339 code · 51 blank · 41 comment · 13 complexity · eb621ced2c1c0fc9fc2b2ead17752ff0 MD5 · raw file

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2015 The Qt Company Ltd.
  4. ** Contact: http://www.qt.io/licensing/
  5. **
  6. ** This file is part of the QtCore module of the Qt Toolkit.
  7. **
  8. ** $QT_BEGIN_LICENSE:LGPL21$
  9. ** Commercial License Usage
  10. ** Licensees holding valid commercial Qt licenses may use this file in
  11. ** accordance with the commercial license agreement provided with the
  12. ** Software or, alternatively, in accordance with the terms contained in
  13. ** a written agreement between you and The Qt Company. For licensing terms
  14. ** and conditions see http://www.qt.io/terms-conditions. For further
  15. ** information use the contact form at http://www.qt.io/contact-us.
  16. **
  17. ** GNU Lesser General Public License Usage
  18. ** Alternatively, this file may be used under the terms of the GNU Lesser
  19. ** General Public License version 2.1 or version 3 as published by the Free
  20. ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
  21. ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
  22. ** following information to ensure the GNU Lesser General Public License
  23. ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
  24. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  25. **
  26. ** As a special exception, The Qt Company gives you certain additional
  27. ** rights. These rights are described in The Qt Company LGPL Exception
  28. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  29. **
  30. ** $QT_END_LICENSE$
  31. **
  32. ****************************************************************************/
  33. #ifndef QSTRINGBUILDER_H
  34. #define QSTRINGBUILDER_H
  35. #if 0
  36. // syncqt can not handle the templates in this file, and it doesn't need to
  37. // process them anyway because they are internal.
  38. #pragma qt_class(QStringBuilder)
  39. #pragma qt_sync_stop_processing
  40. #endif
  41. #include <QtCore/qstring.h>
  42. #include <QtCore/qbytearray.h>
  43. #include <string.h>
  44. QT_BEGIN_NAMESPACE
  45. struct Q_CORE_EXPORT QAbstractConcatenable
  46. {
  47. protected:
  48. static void convertFromAscii(const char *a, int len, QChar *&out);
  49. static inline void convertFromAscii(char a, QChar *&out)
  50. {
  51. *out++ = QLatin1Char(a);
  52. }
  53. static void appendLatin1To(const char *a, int len, QChar *out);
  54. };
  55. template <typename T> struct QConcatenable {};
  56. namespace QtStringBuilder {
  57. template <typename A, typename B> struct ConvertToTypeHelper
  58. { typedef A ConvertTo; };
  59. template <typename T> struct ConvertToTypeHelper<T, QString>
  60. { typedef QString ConvertTo; };
  61. }
  62. template<typename Builder, typename T>
  63. struct QStringBuilderCommon
  64. {
  65. T toUpper() const { return resolved().toUpper(); }
  66. T toLower() const { return resolved().toLower(); }
  67. protected:
  68. const T resolved() const { return *static_cast<const Builder*>(this); }
  69. };
  70. template<typename Builder, typename T>
  71. struct QStringBuilderBase : public QStringBuilderCommon<Builder, T>
  72. {
  73. };
  74. template<typename Builder>
  75. struct QStringBuilderBase<Builder, QString> : public QStringBuilderCommon<Builder, QString>
  76. {
  77. QByteArray toLatin1() const { return this->resolved().toLatin1(); }
  78. QByteArray toUtf8() const { return this->resolved().toUtf8(); }
  79. QByteArray toLocal8Bit() const { return this->resolved().toLocal8Bit(); }
  80. };
  81. template <typename A, typename B>
  82. class QStringBuilder : public QStringBuilderBase<QStringBuilder<A, B>, typename QtStringBuilder::ConvertToTypeHelper<typename QConcatenable<A>::ConvertTo, typename QConcatenable<B>::ConvertTo>::ConvertTo>
  83. {
  84. public:
  85. QStringBuilder(const A &a_, const B &b_) : a(a_), b(b_) {}
  86. private:
  87. friend class QByteArray;
  88. friend class QString;
  89. template <typename T> T convertTo() const
  90. {
  91. const uint len = QConcatenable< QStringBuilder<A, B> >::size(*this);
  92. T s(len, Qt::Uninitialized);
  93. // we abuse const_cast / constData here because we know we've just
  94. // allocated the data and we're the only reference count
  95. typename T::iterator d = const_cast<typename T::iterator>(s.constData());
  96. typename T::const_iterator const start = d;
  97. QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d);
  98. if (!QConcatenable< QStringBuilder<A, B> >::ExactSize && int(len) != d - start) {
  99. // this resize is necessary since we allocate a bit too much
  100. // when dealing with variable sized 8-bit encodings
  101. s.resize(d - start);
  102. }
  103. return s;
  104. }
  105. typedef QConcatenable<QStringBuilder<A, B> > Concatenable;
  106. typedef typename Concatenable::ConvertTo ConvertTo;
  107. public:
  108. operator ConvertTo() const { return convertTo<ConvertTo>(); }
  109. int size() const { return Concatenable::size(*this); }
  110. const A &a;
  111. const B &b;
  112. };
  113. template <>
  114. class QStringBuilder <QString, QString> : public QStringBuilderBase<QStringBuilder<QString, QString>, QString>
  115. {
  116. public:
  117. QStringBuilder(const QString &a_, const QString &b_) : a(a_), b(b_) {}
  118. QStringBuilder(const QStringBuilder &other) : a(other.a), b(other.b) {}
  119. operator QString() const
  120. { QString r(a); r += b; return r; }
  121. const QString &a;
  122. const QString &b;
  123. private:
  124. QStringBuilder &operator=(const QStringBuilder &) Q_DECL_EQ_DELETE;
  125. };
  126. template <>
  127. class QStringBuilder <QByteArray, QByteArray> : public QStringBuilderBase<QStringBuilder<QByteArray, QByteArray>, QByteArray>
  128. {
  129. public:
  130. QStringBuilder(const QByteArray &a_, const QByteArray &b_) : a(a_), b(b_) {}
  131. QStringBuilder(const QStringBuilder &other) : a(other.a), b(other.b) {}
  132. operator QByteArray() const
  133. { QByteArray r(a); r += b; return r; }
  134. const QByteArray &a;
  135. const QByteArray &b;
  136. private:
  137. QStringBuilder &operator=(const QStringBuilder &) Q_DECL_EQ_DELETE;
  138. };
  139. template <> struct QConcatenable<char> : private QAbstractConcatenable
  140. {
  141. typedef char type;
  142. typedef QByteArray ConvertTo;
  143. enum { ExactSize = true };
  144. static int size(const char) { return 1; }
  145. #ifndef QT_NO_CAST_FROM_ASCII
  146. static inline QT_ASCII_CAST_WARN void appendTo(const char c, QChar *&out)
  147. {
  148. QAbstractConcatenable::convertFromAscii(c, out);
  149. }
  150. #endif
  151. static inline void appendTo(const char c, char *&out)
  152. { *out++ = c; }
  153. };
  154. template <> struct QConcatenable<QLatin1Char>
  155. {
  156. typedef QLatin1Char type;
  157. typedef QString ConvertTo;
  158. enum { ExactSize = true };
  159. static int size(const QLatin1Char) { return 1; }
  160. static inline void appendTo(const QLatin1Char c, QChar *&out)
  161. { *out++ = c; }
  162. static inline void appendTo(const QLatin1Char c, char *&out)
  163. { *out++ = c.toLatin1(); }
  164. };
  165. template <> struct QConcatenable<QChar> : private QAbstractConcatenable
  166. {
  167. typedef QChar type;
  168. typedef QString ConvertTo;
  169. enum { ExactSize = true };
  170. static int size(const QChar) { return 1; }
  171. static inline void appendTo(const QChar c, QChar *&out)
  172. { *out++ = c; }
  173. };
  174. template <> struct QConcatenable<QChar::SpecialCharacter> : private QAbstractConcatenable
  175. {
  176. typedef QChar::SpecialCharacter type;
  177. typedef QString ConvertTo;
  178. enum { ExactSize = true };
  179. static int size(const QChar::SpecialCharacter) { return 1; }
  180. static inline void appendTo(const QChar::SpecialCharacter c, QChar *&out)
  181. { *out++ = c; }
  182. };
  183. template <> struct QConcatenable<QCharRef> : private QAbstractConcatenable
  184. {
  185. typedef QCharRef type;
  186. typedef QString ConvertTo;
  187. enum { ExactSize = true };
  188. static int size(QCharRef) { return 1; }
  189. static inline void appendTo(QCharRef c, QChar *&out)
  190. { *out++ = QChar(c); }
  191. };
  192. template <> struct QConcatenable<QLatin1String> : private QAbstractConcatenable
  193. {
  194. typedef QLatin1String type;
  195. typedef QString ConvertTo;
  196. enum { ExactSize = true };
  197. static int size(const QLatin1String a) { return a.size(); }
  198. static inline void appendTo(const QLatin1String a, QChar *&out)
  199. {
  200. appendLatin1To(a.latin1(), a.size(), out);
  201. out += a.size();
  202. }
  203. static inline void appendTo(const QLatin1String a, char *&out)
  204. {
  205. if (a.data()) {
  206. for (const char *s = a.data(); *s; )
  207. *out++ = *s++;
  208. }
  209. }
  210. };
  211. template <> struct QConcatenable<QString> : private QAbstractConcatenable
  212. {
  213. typedef QString type;
  214. typedef QString ConvertTo;
  215. enum { ExactSize = true };
  216. static int size(const QString &a) { return a.size(); }
  217. static inline void appendTo(const QString &a, QChar *&out)
  218. {
  219. const int n = a.size();
  220. memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
  221. out += n;
  222. }
  223. };
  224. template <> struct QConcatenable<QStringRef> : private QAbstractConcatenable
  225. {
  226. typedef QStringRef type;
  227. typedef QString ConvertTo;
  228. enum { ExactSize = true };
  229. static int size(const QStringRef &a) { return a.size(); }
  230. static inline void appendTo(const QStringRef &a, QChar *&out)
  231. {
  232. const int n = a.size();
  233. memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
  234. out += n;
  235. }
  236. };
  237. template <int N> struct QConcatenable<char[N]> : private QAbstractConcatenable
  238. {
  239. typedef char type[N];
  240. typedef QByteArray ConvertTo;
  241. enum { ExactSize = false };
  242. static int size(const char[N]) { return N - 1; }
  243. #ifndef QT_NO_CAST_FROM_ASCII
  244. static inline void QT_ASCII_CAST_WARN appendTo(const char a[N], QChar *&out)
  245. {
  246. QAbstractConcatenable::convertFromAscii(a, N - 1, out);
  247. }
  248. #endif
  249. static inline void appendTo(const char a[N], char *&out)
  250. {
  251. while (*a)
  252. *out++ = *a++;
  253. }
  254. };
  255. template <int N> struct QConcatenable<const char[N]> : private QAbstractConcatenable
  256. {
  257. typedef const char type[N];
  258. typedef QByteArray ConvertTo;
  259. enum { ExactSize = false };
  260. static int size(const char[N]) { return N - 1; }
  261. #ifndef QT_NO_CAST_FROM_ASCII
  262. static inline void QT_ASCII_CAST_WARN appendTo(const char a[N], QChar *&out)
  263. {
  264. QAbstractConcatenable::convertFromAscii(a, N - 1, out);
  265. }
  266. #endif
  267. static inline void appendTo(const char a[N], char *&out)
  268. {
  269. while (*a)
  270. *out++ = *a++;
  271. }
  272. };
  273. template <> struct QConcatenable<const char *> : private QAbstractConcatenable
  274. {
  275. typedef char const *type;
  276. typedef QByteArray ConvertTo;
  277. enum { ExactSize = false };
  278. static int size(const char *a) { return qstrlen(a); }
  279. #ifndef QT_NO_CAST_FROM_ASCII
  280. static inline void QT_ASCII_CAST_WARN appendTo(const char *a, QChar *&out)
  281. { QAbstractConcatenable::convertFromAscii(a, -1, out); }
  282. #endif
  283. static inline void appendTo(const char *a, char *&out)
  284. {
  285. if (!a)
  286. return;
  287. while (*a)
  288. *out++ = *a++;
  289. }
  290. };
  291. template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
  292. {
  293. typedef QByteArray type;
  294. typedef QByteArray ConvertTo;
  295. enum { ExactSize = false };
  296. static int size(const QByteArray &ba) { return ba.size(); }
  297. #ifndef QT_NO_CAST_FROM_ASCII
  298. static inline QT_ASCII_CAST_WARN void appendTo(const QByteArray &ba, QChar *&out)
  299. {
  300. QAbstractConcatenable::convertFromAscii(ba.constData(), ba.size(), out);
  301. }
  302. #endif
  303. static inline void appendTo(const QByteArray &ba, char *&out)
  304. {
  305. const char *a = ba.constData();
  306. const char * const end = ba.end();
  307. while (a != end)
  308. *out++ = *a++;
  309. }
  310. };
  311. template <typename A, typename B>
  312. struct QConcatenable< QStringBuilder<A, B> >
  313. {
  314. typedef QStringBuilder<A, B> type;
  315. typedef typename QtStringBuilder::ConvertToTypeHelper<typename QConcatenable<A>::ConvertTo, typename QConcatenable<B>::ConvertTo>::ConvertTo ConvertTo;
  316. enum { ExactSize = QConcatenable<A>::ExactSize && QConcatenable<B>::ExactSize };
  317. static int size(const type &p)
  318. {
  319. return QConcatenable<A>::size(p.a) + QConcatenable<B>::size(p.b);
  320. }
  321. template<typename T> static inline void appendTo(const type &p, T *&out)
  322. {
  323. QConcatenable<A>::appendTo(p.a, out);
  324. QConcatenable<B>::appendTo(p.b, out);
  325. }
  326. };
  327. template <typename A, typename B>
  328. QStringBuilder<typename QConcatenable<A>::type, typename QConcatenable<B>::type>
  329. operator%(const A &a, const B &b)
  330. {
  331. return QStringBuilder<typename QConcatenable<A>::type, typename QConcatenable<B>::type>(a, b);
  332. }
  333. // QT_USE_FAST_OPERATOR_PLUS was introduced in 4.7, QT_USE_QSTRINGBUILDER is to be used from 4.8 onwards
  334. // QT_USE_FAST_OPERATOR_PLUS does not remove the normal operator+ for QByteArray
  335. #if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER)
  336. template <typename A, typename B>
  337. QStringBuilder<typename QConcatenable<A>::type, typename QConcatenable<B>::type>
  338. operator+(const A &a, const B &b)
  339. {
  340. return QStringBuilder<typename QConcatenable<A>::type, typename QConcatenable<B>::type>(a, b);
  341. }
  342. #endif
  343. namespace QtStringBuilder {
  344. template <typename A, typename B>
  345. QByteArray &appendToByteArray(QByteArray &a, const QStringBuilder<A, B> &b, char)
  346. {
  347. // append 8-bit data to a byte array
  348. int len = a.size() + QConcatenable< QStringBuilder<A, B> >::size(b);
  349. a.reserve(len);
  350. char *it = a.data() + a.size();
  351. QConcatenable< QStringBuilder<A, B> >::appendTo(b, it);
  352. a.resize(len); //we need to resize after the appendTo for the case str+=foo+str
  353. return a;
  354. }
  355. #ifndef QT_NO_CAST_TO_ASCII
  356. template <typename A, typename B>
  357. QByteArray &appendToByteArray(QByteArray &a, const QStringBuilder<A, B> &b, QChar)
  358. {
  359. return a += QString(b).toUtf8();
  360. }
  361. #endif
  362. }
  363. template <typename A, typename B>
  364. QByteArray &operator+=(QByteArray &a, const QStringBuilder<A, B> &b)
  365. {
  366. return QtStringBuilder::appendToByteArray(a, b,
  367. typename QConcatenable< QStringBuilder<A, B> >::ConvertTo::value_type());
  368. }
  369. template <typename A, typename B>
  370. QString &operator+=(QString &a, const QStringBuilder<A, B> &b)
  371. {
  372. int len = a.size() + QConcatenable< QStringBuilder<A, B> >::size(b);
  373. a.reserve(len);
  374. QChar *it = a.data() + a.size();
  375. QConcatenable< QStringBuilder<A, B> >::appendTo(b, it);
  376. a.resize(int(it - a.constData())); //may be smaller than len if there was conversion from utf8
  377. return a;
  378. }
  379. QT_END_NAMESPACE
  380. #endif // QSTRINGBUILDER_H