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++); |
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) |