Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WTF / wtf / text / StringConcatenate.h
1 /*
2  * Copyright (C) 2010-2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef StringConcatenate_h
27 #define StringConcatenate_h
28
29 #include <string.h>
30
31 #ifndef AtomicString_h
32 #include <wtf/text/AtomicString.h>
33 #endif
34
35 #ifndef StringView_h
36 #include <wtf/text/StringView.h>
37 #endif
38
39 // This macro is helpful for testing how many intermediate Strings are created while evaluating an
40 // expression containing operator+.
41 #ifndef WTF_STRINGTYPEADAPTER_COPIED_WTF_STRING
42 #define WTF_STRINGTYPEADAPTER_COPIED_WTF_STRING() ((void)0)
43 #endif
44
45 namespace WTF {
46
47 template<typename StringType>
48 class StringTypeAdapter;
49
50 template<>
51 class StringTypeAdapter<char> {
52 public:
53     StringTypeAdapter<char>(char character)
54         : m_character(character)
55     {
56     }
57
58     unsigned length() { return 1; }
59     bool is8Bit() { return true; }
60
61     void writeTo(LChar* destination) const
62     {
63         *destination = m_character;
64     }
65
66     void writeTo(UChar* destination) const
67     {
68         *destination = m_character;
69     }
70
71     String toString() const { return String(&m_character, 1); }
72
73 private:
74     char m_character;
75 };
76
77 template<>
78 class StringTypeAdapter<UChar> {
79 public:
80     StringTypeAdapter<UChar>(UChar character)
81         : m_character(character)
82     {
83     }
84
85     unsigned length() const { return 1; }
86     bool is8Bit() const { return m_character <= 0xff; }
87
88     void writeTo(LChar* destination) const
89     {
90         ASSERT(is8Bit());
91         *destination = static_cast<LChar>(m_character);
92     }
93
94     void writeTo(UChar* destination) const
95     {
96         *destination = m_character;
97     }
98
99     String toString() const { return String(&m_character, 1); }
100
101 private:
102     UChar m_character;
103 };
104
105 template<>
106 class StringTypeAdapter<const LChar*> {
107 public:
108     StringTypeAdapter(const LChar* characters)
109         : m_characters(characters)
110         , m_length(strlen(reinterpret_cast<const char*>(characters)))
111     {
112     }
113
114     unsigned length() const { return m_length; }
115     bool is8Bit() const { return true; }
116
117     void writeTo(LChar* destination) const
118     {
119         StringView(m_characters, m_length).getCharactersWithUpconvert(destination);
120     }
121
122     void writeTo(UChar* destination) const
123     {
124         StringView(m_characters, m_length).getCharactersWithUpconvert(destination);
125     }
126
127     String toString() const { return String(m_characters, m_length); }
128
129 private:
130     const LChar* m_characters;
131     unsigned m_length;
132 };
133
134 template<>
135 class StringTypeAdapter<const UChar*> {
136 public:
137     StringTypeAdapter(const UChar* characters)
138         : m_characters(characters)
139     {
140         unsigned length = 0;
141         while (m_characters[length])
142             ++length;
143
144         if (length > std::numeric_limits<unsigned>::max())
145             CRASH();
146
147         m_length = length;
148     }
149
150     unsigned length() const { return m_length; }
151     bool is8Bit() const { return false; }
152
153     NO_RETURN_DUE_TO_CRASH void writeTo(LChar*) const
154     {
155         CRASH();
156     }
157
158     void writeTo(UChar* destination) const
159     {
160         memcpy(destination, m_characters, m_length * sizeof(UChar));
161     }
162
163     String toString() const { return String(m_characters, m_length); }
164
165 private:
166     const UChar* m_characters;
167     unsigned m_length;
168 };
169
170 template<>
171 class StringTypeAdapter<const char*> : public StringTypeAdapter<const LChar*> {
172 public:
173     StringTypeAdapter(const char* characters)
174         : StringTypeAdapter<const LChar*>(reinterpret_cast<const LChar*>(characters))
175     {
176     }
177 };
178
179 template<>
180 class StringTypeAdapter<char*> : public StringTypeAdapter<const char*> {
181 public:
182     StringTypeAdapter(const char* characters)
183         : StringTypeAdapter<const char*>(characters)
184     {
185     }
186 };
187
188 template<>
189 class StringTypeAdapter<ASCIILiteral> : public StringTypeAdapter<const char*> {
190 public:
191     StringTypeAdapter(ASCIILiteral characters)
192         : StringTypeAdapter<const char*>(characters)
193     {
194     }
195 };
196
197 template<>
198 class StringTypeAdapter<Vector<char>> {
199 public:
200     StringTypeAdapter(const Vector<char>& vector)
201         : m_vector(vector)
202     {
203     }
204
205     size_t length() const { return m_vector.size(); }
206     bool is8Bit() const { return true; }
207
208     void writeTo(LChar* destination) const
209     {
210         StringView(reinterpret_cast<const LChar*>(m_vector.data()), m_vector.size()).getCharactersWithUpconvert(destination);
211     }
212
213     void writeTo(UChar* destination) const
214     {
215         StringView(reinterpret_cast<const LChar*>(m_vector.data()), m_vector.size()).getCharactersWithUpconvert(destination);
216     }
217
218     String toString() const { return String(m_vector.data(), m_vector.size()); }
219
220 private:
221     const Vector<char>& m_vector;
222 };
223
224 template<>
225 class StringTypeAdapter<String> {
226 public:
227     StringTypeAdapter<String>(const String& string)
228         : m_string(string)
229     {
230     }
231
232     unsigned length() const { return m_string.length(); }
233     bool is8Bit() const { return m_string.isNull() || m_string.is8Bit(); }
234
235     void writeTo(LChar* destination) const
236     {
237         StringView(m_string).getCharactersWithUpconvert(destination);
238         WTF_STRINGTYPEADAPTER_COPIED_WTF_STRING();
239     }
240
241     void writeTo(UChar* destination) const
242     {
243         StringView(m_string).getCharactersWithUpconvert(destination);
244         WTF_STRINGTYPEADAPTER_COPIED_WTF_STRING();
245     }
246
247     String toString() const { return m_string; }
248
249 private:
250     const String& m_string;
251 };
252
253 template<>
254 class StringTypeAdapter<AtomicString> : public StringTypeAdapter<String> {
255 public:
256     StringTypeAdapter(const AtomicString& string)
257         : StringTypeAdapter<String>(string.string())
258     {
259     }
260 };
261
262 inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow)
263 {
264     unsigned oldTotal = total;
265     total = oldTotal + addend;
266     if (total < oldTotal)
267         overflow = true;
268 }
269
270 template<typename StringType1, typename StringType2>
271 String tryMakeString(StringType1 string1, StringType2 string2)
272 {
273     StringTypeAdapter<StringType1> adapter1(string1);
274     StringTypeAdapter<StringType2> adapter2(string2);
275
276     if (adapter1.length() && !adapter2.length())
277         return adapter1.toString();
278     if (!adapter1.length() && adapter2.length())
279         return adapter2.toString();
280
281     bool overflow = false;
282     unsigned length = adapter1.length();
283     sumWithOverflow(length, adapter2.length(), overflow);
284     if (overflow)
285         return String();
286
287     if (adapter1.is8Bit() && adapter2.is8Bit()) {
288         LChar* buffer;
289         RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
290         if (!resultImpl)
291             return String();
292
293         LChar* result = buffer;
294         adapter1.writeTo(result);
295         result += adapter1.length();
296         adapter2.writeTo(result);
297
298         return WTFMove(resultImpl);
299     }
300
301     UChar* buffer;
302     RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
303     if (!resultImpl)
304         return String();
305
306     UChar* result = buffer;
307     adapter1.writeTo(result);
308     result += adapter1.length();
309     adapter2.writeTo(result);
310
311     return WTFMove(resultImpl);
312 }
313
314 template<typename StringType1, typename StringType2, typename StringType3>
315 String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3)
316 {
317     StringTypeAdapter<StringType1> adapter1(string1);
318     StringTypeAdapter<StringType2> adapter2(string2);
319     StringTypeAdapter<StringType3> adapter3(string3);
320
321     bool overflow = false;
322     unsigned length = adapter1.length();
323     sumWithOverflow(length, adapter2.length(), overflow);
324     sumWithOverflow(length, adapter3.length(), overflow);
325     if (overflow)
326         return String();
327
328     if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit()) {
329         LChar* buffer;
330         RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
331         if (!resultImpl)
332             return String();
333
334         LChar* result = buffer;
335         adapter1.writeTo(result);
336         result += adapter1.length();
337         adapter2.writeTo(result);
338         result += adapter2.length();
339         adapter3.writeTo(result);
340
341         return WTFMove(resultImpl);
342     }
343
344     UChar* buffer = 0;
345     RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
346     if (!resultImpl)
347         return String();
348
349     UChar* result = buffer;
350     adapter1.writeTo(result);
351     result += adapter1.length();
352     adapter2.writeTo(result);
353     result += adapter2.length();
354     adapter3.writeTo(result);
355
356     return WTFMove(resultImpl);
357 }
358
359 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
360 String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
361 {
362     StringTypeAdapter<StringType1> adapter1(string1);
363     StringTypeAdapter<StringType2> adapter2(string2);
364     StringTypeAdapter<StringType3> adapter3(string3);
365     StringTypeAdapter<StringType4> adapter4(string4);
366
367     bool overflow = false;
368     unsigned length = adapter1.length();
369     sumWithOverflow(length, adapter2.length(), overflow);
370     sumWithOverflow(length, adapter3.length(), overflow);
371     sumWithOverflow(length, adapter4.length(), overflow);
372     if (overflow)
373         return String();
374
375     if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit()) {
376         LChar* buffer;
377         RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
378         if (!resultImpl)
379             return String();
380
381         LChar* result = buffer;
382         adapter1.writeTo(result);
383         result += adapter1.length();
384         adapter2.writeTo(result);
385         result += adapter2.length();
386         adapter3.writeTo(result);
387         result += adapter3.length();
388         adapter4.writeTo(result);
389
390         return WTFMove(resultImpl);
391     }
392
393     UChar* buffer;
394     RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
395     if (!resultImpl)
396         return String();
397
398     UChar* result = buffer;
399     adapter1.writeTo(result);
400     result += adapter1.length();
401     adapter2.writeTo(result);
402     result += adapter2.length();
403     adapter3.writeTo(result);
404     result += adapter3.length();
405     adapter4.writeTo(result);
406
407     return WTFMove(resultImpl);
408 }
409
410 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
411 String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
412 {
413     StringTypeAdapter<StringType1> adapter1(string1);
414     StringTypeAdapter<StringType2> adapter2(string2);
415     StringTypeAdapter<StringType3> adapter3(string3);
416     StringTypeAdapter<StringType4> adapter4(string4);
417     StringTypeAdapter<StringType5> adapter5(string5);
418
419     bool overflow = false;
420     unsigned length = adapter1.length();
421     sumWithOverflow(length, adapter2.length(), overflow);
422     sumWithOverflow(length, adapter3.length(), overflow);
423     sumWithOverflow(length, adapter4.length(), overflow);
424     sumWithOverflow(length, adapter5.length(), overflow);
425     if (overflow)
426         return String();
427
428     if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit()) {
429         LChar* buffer;
430         RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
431         if (!resultImpl)
432             return String();
433
434         LChar* result = buffer;
435         adapter1.writeTo(result);
436         result += adapter1.length();
437         adapter2.writeTo(result);
438         result += adapter2.length();
439         adapter3.writeTo(result);
440         result += adapter3.length();
441         adapter4.writeTo(result);
442         result += adapter4.length();
443         adapter5.writeTo(result);
444
445         return WTFMove(resultImpl);
446     }
447
448     UChar* buffer;
449     RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
450     if (!resultImpl)
451         return String();
452
453     UChar* result = buffer;
454     adapter1.writeTo(result);
455     result += adapter1.length();
456     adapter2.writeTo(result);
457     result += adapter2.length();
458     adapter3.writeTo(result);
459     result += adapter3.length();
460     adapter4.writeTo(result);
461     result += adapter4.length();
462     adapter5.writeTo(result);
463
464     return WTFMove(resultImpl);
465 }
466
467 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
468 String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
469 {
470     StringTypeAdapter<StringType1> adapter1(string1);
471     StringTypeAdapter<StringType2> adapter2(string2);
472     StringTypeAdapter<StringType3> adapter3(string3);
473     StringTypeAdapter<StringType4> adapter4(string4);
474     StringTypeAdapter<StringType5> adapter5(string5);
475     StringTypeAdapter<StringType6> adapter6(string6);
476
477     bool overflow = false;
478     unsigned length = adapter1.length();
479     sumWithOverflow(length, adapter2.length(), overflow);
480     sumWithOverflow(length, adapter3.length(), overflow);
481     sumWithOverflow(length, adapter4.length(), overflow);
482     sumWithOverflow(length, adapter5.length(), overflow);
483     sumWithOverflow(length, adapter6.length(), overflow);
484     if (overflow)
485         return String();
486
487     if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit()) {
488         LChar* buffer;
489         RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
490         if (!resultImpl)
491             return String();
492
493         LChar* result = buffer;
494         adapter1.writeTo(result);
495         result += adapter1.length();
496         adapter2.writeTo(result);
497         result += adapter2.length();
498         adapter3.writeTo(result);
499         result += adapter3.length();
500         adapter4.writeTo(result);
501         result += adapter4.length();
502         adapter5.writeTo(result);
503         result += adapter5.length();
504         adapter6.writeTo(result);
505
506         return WTFMove(resultImpl);
507     }
508
509     UChar* buffer;
510     RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
511     if (!resultImpl)
512         return String();
513
514     UChar* result = buffer;
515     adapter1.writeTo(result);
516     result += adapter1.length();
517     adapter2.writeTo(result);
518     result += adapter2.length();
519     adapter3.writeTo(result);
520     result += adapter3.length();
521     adapter4.writeTo(result);
522     result += adapter4.length();
523     adapter5.writeTo(result);
524     result += adapter5.length();
525     adapter6.writeTo(result);
526
527     return WTFMove(resultImpl);
528 }
529
530 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
531 String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
532 {
533     StringTypeAdapter<StringType1> adapter1(string1);
534     StringTypeAdapter<StringType2> adapter2(string2);
535     StringTypeAdapter<StringType3> adapter3(string3);
536     StringTypeAdapter<StringType4> adapter4(string4);
537     StringTypeAdapter<StringType5> adapter5(string5);
538     StringTypeAdapter<StringType6> adapter6(string6);
539     StringTypeAdapter<StringType7> adapter7(string7);
540
541     bool overflow = false;
542     unsigned length = adapter1.length();
543     sumWithOverflow(length, adapter2.length(), overflow);
544     sumWithOverflow(length, adapter3.length(), overflow);
545     sumWithOverflow(length, adapter4.length(), overflow);
546     sumWithOverflow(length, adapter5.length(), overflow);
547     sumWithOverflow(length, adapter6.length(), overflow);
548     sumWithOverflow(length, adapter7.length(), overflow);
549     if (overflow)
550         return String();
551
552     if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit()) {
553         LChar* buffer;
554         RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
555         if (!resultImpl)
556             return String();
557
558         LChar* result = buffer;
559         adapter1.writeTo(result);
560         result += adapter1.length();
561         adapter2.writeTo(result);
562         result += adapter2.length();
563         adapter3.writeTo(result);
564         result += adapter3.length();
565         adapter4.writeTo(result);
566         result += adapter4.length();
567         adapter5.writeTo(result);
568         result += adapter5.length();
569         adapter6.writeTo(result);
570         result += adapter6.length();
571         adapter7.writeTo(result);
572
573         return WTFMove(resultImpl);
574     }
575
576     UChar* buffer;
577     RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
578     if (!resultImpl)
579         return String();
580
581     UChar* result = buffer;
582     adapter1.writeTo(result);
583     result += adapter1.length();
584     adapter2.writeTo(result);
585     result += adapter2.length();
586     adapter3.writeTo(result);
587     result += adapter3.length();
588     adapter4.writeTo(result);
589     result += adapter4.length();
590     adapter5.writeTo(result);
591     result += adapter5.length();
592     adapter6.writeTo(result);
593     result += adapter6.length();
594     adapter7.writeTo(result);
595
596     return WTFMove(resultImpl);
597 }
598
599 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
600 String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
601 {
602     StringTypeAdapter<StringType1> adapter1(string1);
603     StringTypeAdapter<StringType2> adapter2(string2);
604     StringTypeAdapter<StringType3> adapter3(string3);
605     StringTypeAdapter<StringType4> adapter4(string4);
606     StringTypeAdapter<StringType5> adapter5(string5);
607     StringTypeAdapter<StringType6> adapter6(string6);
608     StringTypeAdapter<StringType7> adapter7(string7);
609     StringTypeAdapter<StringType8> adapter8(string8);
610
611     bool overflow = false;
612     unsigned length = adapter1.length();
613     sumWithOverflow(length, adapter2.length(), overflow);
614     sumWithOverflow(length, adapter3.length(), overflow);
615     sumWithOverflow(length, adapter4.length(), overflow);
616     sumWithOverflow(length, adapter5.length(), overflow);
617     sumWithOverflow(length, adapter6.length(), overflow);
618     sumWithOverflow(length, adapter7.length(), overflow);
619     sumWithOverflow(length, adapter8.length(), overflow);
620     if (overflow)
621         return String();
622
623     if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit() && adapter8.is8Bit()) {
624         LChar* buffer;
625         RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
626         if (!resultImpl)
627             return String();
628
629         LChar* result = buffer;
630         adapter1.writeTo(result);
631         result += adapter1.length();
632         adapter2.writeTo(result);
633         result += adapter2.length();
634         adapter3.writeTo(result);
635         result += adapter3.length();
636         adapter4.writeTo(result);
637         result += adapter4.length();
638         adapter5.writeTo(result);
639         result += adapter5.length();
640         adapter6.writeTo(result);
641         result += adapter6.length();
642         adapter7.writeTo(result);
643         result += adapter7.length();
644         adapter8.writeTo(result);
645
646         return WTFMove(resultImpl);
647     }
648
649     UChar* buffer;
650     RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
651     if (!resultImpl)
652         return String();
653
654     UChar* result = buffer;
655     adapter1.writeTo(result);
656     result += adapter1.length();
657     adapter2.writeTo(result);
658     result += adapter2.length();
659     adapter3.writeTo(result);
660     result += adapter3.length();
661     adapter4.writeTo(result);
662     result += adapter4.length();
663     adapter5.writeTo(result);
664     result += adapter5.length();
665     adapter6.writeTo(result);
666     result += adapter6.length();
667     adapter7.writeTo(result);
668     result += adapter7.length();
669     adapter8.writeTo(result);
670
671     return WTFMove(resultImpl);
672 }
673
674 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8, typename StringType9>
675 String tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8, StringType9 string9)
676 {
677     StringTypeAdapter<StringType1> adapter1(string1);
678     StringTypeAdapter<StringType2> adapter2(string2);
679     StringTypeAdapter<StringType3> adapter3(string3);
680     StringTypeAdapter<StringType4> adapter4(string4);
681     StringTypeAdapter<StringType5> adapter5(string5);
682     StringTypeAdapter<StringType6> adapter6(string6);
683     StringTypeAdapter<StringType7> adapter7(string7);
684     StringTypeAdapter<StringType8> adapter8(string8);
685     StringTypeAdapter<StringType9> adapter9(string9);
686
687     bool overflow = false;
688     unsigned length = adapter1.length();
689     sumWithOverflow(length, adapter2.length(), overflow);
690     sumWithOverflow(length, adapter3.length(), overflow);
691     sumWithOverflow(length, adapter4.length(), overflow);
692     sumWithOverflow(length, adapter5.length(), overflow);
693     sumWithOverflow(length, adapter6.length(), overflow);
694     sumWithOverflow(length, adapter7.length(), overflow);
695     sumWithOverflow(length, adapter8.length(), overflow);
696     sumWithOverflow(length, adapter9.length(), overflow);
697     if (overflow)
698         return String();
699
700     if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit() && adapter8.is8Bit() && adapter9.is8Bit()) {
701         LChar* buffer;
702         RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
703         if (!resultImpl)
704             return String();
705
706         LChar* result = buffer;
707         adapter1.writeTo(result);
708         result += adapter1.length();
709         adapter2.writeTo(result);
710         result += adapter2.length();
711         adapter3.writeTo(result);
712         result += adapter3.length();
713         adapter4.writeTo(result);
714         result += adapter4.length();
715         adapter5.writeTo(result);
716         result += adapter5.length();
717         adapter6.writeTo(result);
718         result += adapter6.length();
719         adapter7.writeTo(result);
720         result += adapter7.length();
721         adapter8.writeTo(result);
722         result += adapter8.length();
723         adapter9.writeTo(result);
724
725         return WTFMove(resultImpl);
726     }
727
728     UChar* buffer;
729     RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
730     if (!resultImpl)
731         return String();
732
733     UChar* result = buffer;
734     adapter1.writeTo(result);
735     result += adapter1.length();
736     adapter2.writeTo(result);
737     result += adapter2.length();
738     adapter3.writeTo(result);
739     result += adapter3.length();
740     adapter4.writeTo(result);
741     result += adapter4.length();
742     adapter5.writeTo(result);
743     result += adapter5.length();
744     adapter6.writeTo(result);
745     result += adapter6.length();
746     adapter7.writeTo(result);
747     result += adapter7.length();
748     adapter8.writeTo(result);
749     result += adapter8.length();
750     adapter9.writeTo(result);
751
752     return WTFMove(resultImpl);
753 }
754
755
756 // Convenience only.
757 template<typename StringType1>
758 String makeString(StringType1 string1)
759 {
760     return String(string1);
761 }
762
763 template<typename StringType1, typename StringType2>
764 String makeString(StringType1 string1, StringType2 string2)
765 {
766     String result = tryMakeString(string1, string2);
767     if (!result)
768         CRASH();
769     return result;
770 }
771
772 template<typename StringType1, typename StringType2, typename StringType3>
773 String makeString(StringType1 string1, StringType2 string2, StringType3 string3)
774 {
775     String result = tryMakeString(string1, string2, string3);
776     if (!result)
777         CRASH();
778     return result;
779 }
780
781 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
782 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
783 {
784     String result = tryMakeString(string1, string2, string3, string4);
785     if (!result)
786         CRASH();
787     return result;
788 }
789
790 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
791 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
792 {
793     String result = tryMakeString(string1, string2, string3, string4, string5);
794     if (!result)
795         CRASH();
796     return result;
797 }
798
799 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
800 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
801 {
802     String result = tryMakeString(string1, string2, string3, string4, string5, string6);
803     if (!result)
804         CRASH();
805     return result;
806 }
807
808 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
809 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
810 {
811     String result = tryMakeString(string1, string2, string3, string4, string5, string6, string7);
812     if (!result)
813         CRASH();
814     return result;
815 }
816
817 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
818 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
819 {
820     String result = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8);
821     if (!result)
822         CRASH();
823     return result;
824 }
825
826 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8, typename StringType9>
827 String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8, StringType9 string9)
828 {
829     String result = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8, string9);
830     if (!result)
831         CRASH();
832     return result;
833 }
834
835 } // namespace WTF
836
837 using WTF::makeString;
838
839 #include <wtf/text/StringOperators.h>
840 #endif