<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[187815] trunk/Source/WTF</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/187815">187815</a></dd>
<dt>Author</dt> <dd>zandobersek@gmail.com</dd>
<dt>Date</dt> <dd>2015-08-03 23:27:12 -0700 (Mon, 03 Aug 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[WTF] Turn tryMakeString(), makeString() into variadic templates
https://bugs.webkit.org/show_bug.cgi?id=147142

Reviewed by Sam Weinig.

Built upon the original work by Anders Carlsson, Mark Rowe and Sam Weinig.

Implement tryMakeString() and makeString() as variadic templates, replacing
the argument count-based overloads.

tryMakeString() now constructs a stack-based tuple of necessary StringTypeAdapter
objects and utilizes the StringAdapterTuple struct template to operate on that
tuple, recursively calling the necessary operations on each element in the tuple.
This effectively mimics the process of previous tryMakeString() implementation,
but makes it scalable to a tuple of elements that are to be concatenated.

StringAppend class template now stores two StringTypeAdapter objects for the
two passed-in string objects, packed in a tuple, calling
StringAdapterTuple&lt;&gt;::createString() directly when concatenating the two objects
into one String.

* wtf/text/StringConcatenate.h:
(WTF::StringTypeAdapter&lt;char&gt;::length):
(WTF::StringTypeAdapter&lt;char&gt;::is8Bit):
(WTF::StringAdapterTuple::sumWithOverflow):
(WTF::StringAdapterTuple::is8Bit):
(WTF::StringAdapterTuple::writeTo):
(WTF::StringAdapterTuple::createString):
(WTF::tryMakeString):
(WTF::makeString):
(WTF::sumWithOverflow): Deleted.
* wtf/text/StringOperators.h:
(WTF::StringAppend::StringAppend):
(WTF::StringAppend::operator String):
(WTF::StringAppend::is8Bit):
(WTF::StringAppend::writeTo):
(WTF::StringAppend::length):
(WTF::StringAppend::string1):
(WTF::StringAppend::string2):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtftextStringConcatenateh">trunk/Source/WTF/wtf/text/StringConcatenate.h</a></li>
<li><a href="#trunkSourceWTFwtftextStringOperatorsh">trunk/Source/WTF/wtf/text/StringOperators.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (187814 => 187815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2015-08-04 06:05:35 UTC (rev 187814)
+++ trunk/Source/WTF/ChangeLog        2015-08-04 06:27:12 UTC (rev 187815)
</span><span class="lines">@@ -1,3 +1,45 @@
</span><ins>+2015-08-03  Zan Dobersek  &lt;zdobersek@igalia.com&gt;
+
+        [WTF] Turn tryMakeString(), makeString() into variadic templates
+        https://bugs.webkit.org/show_bug.cgi?id=147142
+
+        Reviewed by Sam Weinig.
+
+        Built upon the original work by Anders Carlsson, Mark Rowe and Sam Weinig.
+
+        Implement tryMakeString() and makeString() as variadic templates, replacing
+        the argument count-based overloads.
+
+        tryMakeString() now constructs a stack-based tuple of necessary StringTypeAdapter
+        objects and utilizes the StringAdapterTuple struct template to operate on that
+        tuple, recursively calling the necessary operations on each element in the tuple.
+        This effectively mimics the process of previous tryMakeString() implementation,
+        but makes it scalable to a tuple of elements that are to be concatenated.
+
+        StringAppend class template now stores two StringTypeAdapter objects for the
+        two passed-in string objects, packed in a tuple, calling
+        StringAdapterTuple&lt;&gt;::createString() directly when concatenating the two objects
+        into one String.
+
+        * wtf/text/StringConcatenate.h:
+        (WTF::StringTypeAdapter&lt;char&gt;::length):
+        (WTF::StringTypeAdapter&lt;char&gt;::is8Bit):
+        (WTF::StringAdapterTuple::sumWithOverflow):
+        (WTF::StringAdapterTuple::is8Bit):
+        (WTF::StringAdapterTuple::writeTo):
+        (WTF::StringAdapterTuple::createString):
+        (WTF::tryMakeString):
+        (WTF::makeString):
+        (WTF::sumWithOverflow): Deleted.
+        * wtf/text/StringOperators.h:
+        (WTF::StringAppend::StringAppend):
+        (WTF::StringAppend::operator String):
+        (WTF::StringAppend::is8Bit):
+        (WTF::StringAppend::writeTo):
+        (WTF::StringAppend::length):
+        (WTF::StringAppend::string1):
+        (WTF::StringAppend::string2):
+
</ins><span class="cx"> 2015-08-03  Anders Carlsson  &lt;andersca@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Make it possible to use String::utf8() in the debugger
</span></span></pre></div>
<a id="trunkSourceWTFwtftextStringConcatenateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/StringConcatenate.h (187814 => 187815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringConcatenate.h        2015-08-04 06:05:35 UTC (rev 187814)
+++ trunk/Source/WTF/wtf/text/StringConcatenate.h        2015-08-04 06:27:12 UTC (rev 187815)
</span><span class="lines">@@ -55,8 +55,8 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    unsigned length() { return 1; }
-    bool is8Bit() { return true; }
</del><ins>+    unsigned length() const { return 1; }
+    bool is8Bit() const { return true; }
</ins><span class="cx"> 
</span><span class="cx">     void writeTo(LChar* destination) const
</span><span class="cx">     {
</span><span class="lines">@@ -98,6 +98,74 @@
</span><span class="cx">     UChar m_character;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+template&lt;size_t stringLiteralLength&gt;
+class StringTypeAdapter&lt;char[stringLiteralLength]&gt; {
+public:
+    StringTypeAdapter(const char (&amp;stringLiteral)[stringLiteralLength])
+        : m_string(reinterpret_cast&lt;const LChar*&gt;(stringLiteral))
+    {
+    }
+
+    unsigned length() const { return stringLiteralLength - 1; }
+    bool is8Bit() const { return true; }
+
+    void writeTo(LChar* destination) const
+    {
+        StringView(m_string, length()).getCharactersWithUpconvert(destination);
+    }
+
+    void writeTo(UChar* destination) const
+    {
+        StringView(m_string, length()).getCharactersWithUpconvert(destination);
+    }
+
+private:
+    const LChar* m_string;
+};
+
+template&lt;size_t stringLiteralLength&gt;
+class StringTypeAdapter&lt;const char[stringLiteralLength]&gt; : public StringTypeAdapter&lt;char[stringLiteralLength]&gt; {
+public:
+    StringTypeAdapter(const char (&amp;stringLiteral)[stringLiteralLength])
+        : StringTypeAdapter&lt;char[stringLiteralLength]&gt;(stringLiteral)
+    {
+    }
+};
+
+template&lt;size_t stringLiteralLength&gt;
+class StringTypeAdapter&lt;UChar[stringLiteralLength]&gt; {
+public:
+    StringTypeAdapter(const UChar (&amp;stringLiteral)[stringLiteralLength])
+        : m_string(reinterpret_cast&lt;const UChar*&gt;(stringLiteral))
+    {
+    }
+
+    unsigned length() const { return stringLiteralLength - 1; }
+    bool is8Bit() const { return false; }
+
+    NO_RETURN_DUE_TO_CRASH void writeTo(LChar*) const
+    {
+        CRASH();
+    }
+
+    void writeTo(UChar* destination) const
+    {
+        StringView(m_string, length()).getCharactersWithUpconvert(destination);
+    }
+
+private:
+    const UChar* m_string;
+};
+
+template&lt;size_t stringLiteralLength&gt;
+class StringTypeAdapter&lt;const UChar[stringLiteralLength]&gt; : public StringTypeAdapter&lt;UChar[stringLiteralLength]&gt; {
+public:
+    StringTypeAdapter(const UChar (&amp;stringLiteral)[stringLiteralLength])
+        : StringTypeAdapter&lt;UChar[stringLiteralLength]&gt;(stringLiteral)
+    {
+    }
+};
+
</ins><span class="cx"> template&lt;&gt;
</span><span class="cx"> class StringTypeAdapter&lt;const LChar*&gt; {
</span><span class="cx"> public:
</span><span class="lines">@@ -247,574 +315,87 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-inline void sumWithOverflow(unsigned&amp; total, unsigned addend, bool&amp; overflow)
-{
-    unsigned oldTotal = total;
-    total = oldTotal + addend;
-    if (total &lt; oldTotal)
-        overflow = true;
-}
-
-template&lt;typename StringType1, typename StringType2&gt;
-RefPtr&lt;StringImpl&gt; tryMakeString(StringType1 string1, StringType2 string2)
-{
-    StringTypeAdapter&lt;StringType1&gt; adapter1(string1);
-    StringTypeAdapter&lt;StringType2&gt; adapter2(string2);
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    if (overflow)
-        return nullptr;
-
-    if (adapter1.is8Bit() &amp;&amp; adapter2.is8Bit()) {
-        LChar* buffer;
-        RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
-            return nullptr;
-
-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-
-        return WTF::move(resultImpl);
</del><ins>+template&lt;size_t index, typename... Adapters&gt;
+struct StringAdapterTuple {
+    static inline Checked&lt;unsigned, RecordOverflow&gt; sumWithOverflow(const std::tuple&lt;Adapters...&gt;&amp; tuple)
+    {
+        auto&amp; adapter = std::get&lt;sizeof...(Adapters) - index&gt;(tuple);
+        return Checked&lt;unsigned, RecordOverflow&gt;(adapter.length()) + StringAdapterTuple&lt;index - 1, Adapters...&gt;::sumWithOverflow(tuple);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    UChar* buffer;
-    RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return nullptr;
-
-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-
-    return WTF::move(resultImpl);
-}
-
-template&lt;typename StringType1, typename StringType2, typename StringType3&gt;
-RefPtr&lt;StringImpl&gt; tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3)
-{
-    StringTypeAdapter&lt;StringType1&gt; adapter1(string1);
-    StringTypeAdapter&lt;StringType2&gt; adapter2(string2);
-    StringTypeAdapter&lt;StringType3&gt; adapter3(string3);
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    sumWithOverflow(length, adapter3.length(), overflow);
-    if (overflow)
-        return nullptr;
-
-    if (adapter1.is8Bit() &amp;&amp; adapter2.is8Bit() &amp;&amp; adapter3.is8Bit()) {
-        LChar* buffer;
-        RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
-            return nullptr;
-
-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-        result += adapter2.length();
-        adapter3.writeTo(result);
-
-        return WTF::move(resultImpl);
</del><ins>+    static inline bool is8Bit(const std::tuple&lt;Adapters...&gt;&amp; tuple)
+    {
+        auto&amp; adapter = std::get&lt;sizeof...(Adapters) - index&gt;(tuple);
+        return adapter.is8Bit() &amp;&amp; StringAdapterTuple&lt;index - 1, Adapters...&gt;::is8Bit(tuple);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    UChar* buffer = 0;
-    RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return nullptr;
-
-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-    result += adapter2.length();
-    adapter3.writeTo(result);
-
-    return WTF::move(resultImpl);
-}
-
-template&lt;typename StringType1, typename StringType2, typename StringType3, typename StringType4&gt;
-RefPtr&lt;StringImpl&gt; tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
-{
-    StringTypeAdapter&lt;StringType1&gt; adapter1(string1);
-    StringTypeAdapter&lt;StringType2&gt; adapter2(string2);
-    StringTypeAdapter&lt;StringType3&gt; adapter3(string3);
-    StringTypeAdapter&lt;StringType4&gt; adapter4(string4);
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    sumWithOverflow(length, adapter3.length(), overflow);
-    sumWithOverflow(length, adapter4.length(), overflow);
-    if (overflow)
-        return nullptr;
-
-    if (adapter1.is8Bit() &amp;&amp; adapter2.is8Bit() &amp;&amp; adapter3.is8Bit() &amp;&amp; adapter4.is8Bit()) {
-        LChar* buffer;
-        RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
-            return nullptr;
-
-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-        result += adapter2.length();
-        adapter3.writeTo(result);
-        result += adapter3.length();
-        adapter4.writeTo(result);
-
-        return WTF::move(resultImpl);
</del><ins>+    template&lt;typename T&gt;
+    static inline void writeTo(T* buffer, const std::tuple&lt;Adapters...&gt;&amp; tuple)
+    {
+        auto&amp; adapter = std::get&lt;sizeof...(Adapters) - index&gt;(tuple);
+        adapter.writeTo(buffer);
+        StringAdapterTuple&lt;index - 1, Adapters...&gt;::writeTo(buffer + adapter.length(), tuple);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    UChar* buffer;
-    RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return nullptr;
-
-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-    result += adapter2.length();
-    adapter3.writeTo(result);
-    result += adapter3.length();
-    adapter4.writeTo(result);
-
-    return WTF::move(resultImpl);
-}
-
-template&lt;typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5&gt;
-RefPtr&lt;StringImpl&gt; tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
-{
-    StringTypeAdapter&lt;StringType1&gt; adapter1(string1);
-    StringTypeAdapter&lt;StringType2&gt; adapter2(string2);
-    StringTypeAdapter&lt;StringType3&gt; adapter3(string3);
-    StringTypeAdapter&lt;StringType4&gt; adapter4(string4);
-    StringTypeAdapter&lt;StringType5&gt; adapter5(string5);
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    sumWithOverflow(length, adapter3.length(), overflow);
-    sumWithOverflow(length, adapter4.length(), overflow);
-    sumWithOverflow(length, adapter5.length(), overflow);
-    if (overflow)
-        return nullptr;
-
-    if (adapter1.is8Bit() &amp;&amp; adapter2.is8Bit() &amp;&amp; adapter3.is8Bit() &amp;&amp; adapter4.is8Bit() &amp;&amp; adapter5.is8Bit()) {
-        LChar* buffer;
-        RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
</del><ins>+    static inline RefPtr&lt;StringImpl&gt; createString(const std::tuple&lt;Adapters...&gt;&amp; adapters)
+    {
+        unsigned length = 0;
+        if (sumWithOverflow(adapters).safeGet(length) == CheckedState::DidOverflow)
</ins><span class="cx">             return nullptr;
</span><span class="cx"> 
</span><del>-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-        result += adapter2.length();
-        adapter3.writeTo(result);
-        result += adapter3.length();
-        adapter4.writeTo(result);
-        result += adapter4.length();
-        adapter5.writeTo(result);
</del><ins>+        if (is8Bit(adapters)) {
+            LChar* buffer;
+            RefPtr&lt;StringImpl&gt; result = StringImpl::tryCreateUninitialized(length, buffer);
+            if (!result)
+                return nullptr;
</ins><span class="cx"> 
</span><del>-        return WTF::move(resultImpl);
-    }
</del><ins>+            writeTo(buffer, adapters);
+            return result;
+        }
</ins><span class="cx"> 
</span><del>-    UChar* buffer;
-    RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return nullptr;
-
-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-    result += adapter2.length();
-    adapter3.writeTo(result);
-    result += adapter3.length();
-    adapter4.writeTo(result);
-    result += adapter4.length();
-    adapter5.writeTo(result);
-
-    return WTF::move(resultImpl);
-}
-
-template&lt;typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6&gt;
-RefPtr&lt;StringImpl&gt; tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
-{
-    StringTypeAdapter&lt;StringType1&gt; adapter1(string1);
-    StringTypeAdapter&lt;StringType2&gt; adapter2(string2);
-    StringTypeAdapter&lt;StringType3&gt; adapter3(string3);
-    StringTypeAdapter&lt;StringType4&gt; adapter4(string4);
-    StringTypeAdapter&lt;StringType5&gt; adapter5(string5);
-    StringTypeAdapter&lt;StringType6&gt; adapter6(string6);
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    sumWithOverflow(length, adapter3.length(), overflow);
-    sumWithOverflow(length, adapter4.length(), overflow);
-    sumWithOverflow(length, adapter5.length(), overflow);
-    sumWithOverflow(length, adapter6.length(), overflow);
-    if (overflow)
-        return nullptr;
-
-    if (adapter1.is8Bit() &amp;&amp; adapter2.is8Bit() &amp;&amp; adapter3.is8Bit() &amp;&amp; adapter4.is8Bit() &amp;&amp; adapter5.is8Bit() &amp;&amp; adapter6.is8Bit()) {
-        LChar* buffer;
-        RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
</del><ins>+        UChar* buffer;
+        RefPtr&lt;StringImpl&gt; result = StringImpl::tryCreateUninitialized(length, buffer);
+        if (!result)
</ins><span class="cx">             return nullptr;
</span><span class="cx"> 
</span><del>-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-        result += adapter2.length();
-        adapter3.writeTo(result);
-        result += adapter3.length();
-        adapter4.writeTo(result);
-        result += adapter4.length();
-        adapter5.writeTo(result);
-        result += adapter5.length();
-        adapter6.writeTo(result);
-
-        return WTF::move(resultImpl);
</del><ins>+        writeTo(buffer, adapters);
+        return result;
</ins><span class="cx">     }
</span><ins>+};
</ins><span class="cx"> 
</span><del>-    UChar* buffer;
-    RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return nullptr;
</del><ins>+template&lt;typename... Adapters&gt;
+struct StringAdapterTuple&lt;0, Adapters...&gt; {
+    static Checked&lt;unsigned, RecordOverflow&gt; sumWithOverflow(const std::tuple&lt;Adapters...&gt;&amp;) { return 0; }
+    static bool is8Bit(const std::tuple&lt;Adapters...&gt;&amp;) { return true; }
+    template&lt;typename T&gt; static void writeTo(T*, const std::tuple&lt;Adapters...&gt;&amp;) { }
+};
</ins><span class="cx"> 
</span><del>-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-    result += adapter2.length();
-    adapter3.writeTo(result);
-    result += adapter3.length();
-    adapter4.writeTo(result);
-    result += adapter4.length();
-    adapter5.writeTo(result);
-    result += adapter5.length();
-    adapter6.writeTo(result);
</del><ins>+template&lt;typename T&gt;
+using AdapterType = StringTypeAdapter&lt;typename std::decay&lt;T&gt;::type&gt;;
</ins><span class="cx"> 
</span><del>-    return WTF::move(resultImpl);
-}
-
-template&lt;typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7&gt;
-RefPtr&lt;StringImpl&gt; tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
</del><ins>+template&lt;typename T1, typename T2, typename... Ts&gt;
+RefPtr&lt;StringImpl&gt; tryMakeString(const T1&amp; string1, const T2&amp; string2, const Ts&amp;... strings)
</ins><span class="cx"> {
</span><del>-    StringTypeAdapter&lt;StringType1&gt; adapter1(string1);
-    StringTypeAdapter&lt;StringType2&gt; adapter2(string2);
-    StringTypeAdapter&lt;StringType3&gt; adapter3(string3);
-    StringTypeAdapter&lt;StringType4&gt; adapter4(string4);
-    StringTypeAdapter&lt;StringType5&gt; adapter5(string5);
-    StringTypeAdapter&lt;StringType6&gt; adapter6(string6);
-    StringTypeAdapter&lt;StringType7&gt; adapter7(string7);
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    sumWithOverflow(length, adapter3.length(), overflow);
-    sumWithOverflow(length, adapter4.length(), overflow);
-    sumWithOverflow(length, adapter5.length(), overflow);
-    sumWithOverflow(length, adapter6.length(), overflow);
-    sumWithOverflow(length, adapter7.length(), overflow);
-    if (overflow)
-        return nullptr;
-
-    if (adapter1.is8Bit() &amp;&amp; adapter2.is8Bit() &amp;&amp; adapter3.is8Bit() &amp;&amp; adapter4.is8Bit() &amp;&amp; adapter5.is8Bit() &amp;&amp; adapter6.is8Bit() &amp;&amp; adapter7.is8Bit()) {
-        LChar* buffer;
-        RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
-            return nullptr;
-
-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-        result += adapter2.length();
-        adapter3.writeTo(result);
-        result += adapter3.length();
-        adapter4.writeTo(result);
-        result += adapter4.length();
-        adapter5.writeTo(result);
-        result += adapter5.length();
-        adapter6.writeTo(result);
-        result += adapter6.length();
-        adapter7.writeTo(result);
-
-        return WTF::move(resultImpl);
-    }
-
-    UChar* buffer;
-    RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return nullptr;
-
-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-    result += adapter2.length();
-    adapter3.writeTo(result);
-    result += adapter3.length();
-    adapter4.writeTo(result);
-    result += adapter4.length();
-    adapter5.writeTo(result);
-    result += adapter5.length();
-    adapter6.writeTo(result);
-    result += adapter6.length();
-    adapter7.writeTo(result);
-
-    return WTF::move(resultImpl);
</del><ins>+    auto adapters = std::make_tuple(AdapterType&lt;T1&gt;(string1), AdapterType&lt;T2&gt;(string2), AdapterType&lt;Ts&gt;(strings)...);
+    return StringAdapterTuple&lt;2 + sizeof...(Ts), AdapterType&lt;T1&gt;, AdapterType&lt;T2&gt;, AdapterType&lt;Ts&gt;...&gt;::createString(adapters);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8&gt;
-RefPtr&lt;StringImpl&gt; tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
-{
-    StringTypeAdapter&lt;StringType1&gt; adapter1(string1);
-    StringTypeAdapter&lt;StringType2&gt; adapter2(string2);
-    StringTypeAdapter&lt;StringType3&gt; adapter3(string3);
-    StringTypeAdapter&lt;StringType4&gt; adapter4(string4);
-    StringTypeAdapter&lt;StringType5&gt; adapter5(string5);
-    StringTypeAdapter&lt;StringType6&gt; adapter6(string6);
-    StringTypeAdapter&lt;StringType7&gt; adapter7(string7);
-    StringTypeAdapter&lt;StringType8&gt; adapter8(string8);
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    sumWithOverflow(length, adapter3.length(), overflow);
-    sumWithOverflow(length, adapter4.length(), overflow);
-    sumWithOverflow(length, adapter5.length(), overflow);
-    sumWithOverflow(length, adapter6.length(), overflow);
-    sumWithOverflow(length, adapter7.length(), overflow);
-    sumWithOverflow(length, adapter8.length(), overflow);
-    if (overflow)
-        return nullptr;
-
-    if (adapter1.is8Bit() &amp;&amp; adapter2.is8Bit() &amp;&amp; adapter3.is8Bit() &amp;&amp; adapter4.is8Bit() &amp;&amp; adapter5.is8Bit() &amp;&amp; adapter6.is8Bit() &amp;&amp; adapter7.is8Bit() &amp;&amp; adapter8.is8Bit()) {
-        LChar* buffer;
-        RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
-            return nullptr;
-
-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-        result += adapter2.length();
-        adapter3.writeTo(result);
-        result += adapter3.length();
-        adapter4.writeTo(result);
-        result += adapter4.length();
-        adapter5.writeTo(result);
-        result += adapter5.length();
-        adapter6.writeTo(result);
-        result += adapter6.length();
-        adapter7.writeTo(result);
-        result += adapter7.length();
-        adapter8.writeTo(result);
-
-        return WTF::move(resultImpl);
-    }
-
-    UChar* buffer;
-    RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return nullptr;
-
-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-    result += adapter2.length();
-    adapter3.writeTo(result);
-    result += adapter3.length();
-    adapter4.writeTo(result);
-    result += adapter4.length();
-    adapter5.writeTo(result);
-    result += adapter5.length();
-    adapter6.writeTo(result);
-    result += adapter6.length();
-    adapter7.writeTo(result);
-    result += adapter7.length();
-    adapter8.writeTo(result);
-
-    return WTF::move(resultImpl);
-}
-
-template&lt;typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8, typename StringType9&gt;
-RefPtr&lt;StringImpl&gt; tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8, StringType9 string9)
-{
-    StringTypeAdapter&lt;StringType1&gt; adapter1(string1);
-    StringTypeAdapter&lt;StringType2&gt; adapter2(string2);
-    StringTypeAdapter&lt;StringType3&gt; adapter3(string3);
-    StringTypeAdapter&lt;StringType4&gt; adapter4(string4);
-    StringTypeAdapter&lt;StringType5&gt; adapter5(string5);
-    StringTypeAdapter&lt;StringType6&gt; adapter6(string6);
-    StringTypeAdapter&lt;StringType7&gt; adapter7(string7);
-    StringTypeAdapter&lt;StringType8&gt; adapter8(string8);
-    StringTypeAdapter&lt;StringType9&gt; adapter9(string9);
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    sumWithOverflow(length, adapter3.length(), overflow);
-    sumWithOverflow(length, adapter4.length(), overflow);
-    sumWithOverflow(length, adapter5.length(), overflow);
-    sumWithOverflow(length, adapter6.length(), overflow);
-    sumWithOverflow(length, adapter7.length(), overflow);
-    sumWithOverflow(length, adapter8.length(), overflow);
-    sumWithOverflow(length, adapter9.length(), overflow);
-    if (overflow)
-        return nullptr;
-
-    if (adapter1.is8Bit() &amp;&amp; adapter2.is8Bit() &amp;&amp; adapter3.is8Bit() &amp;&amp; adapter4.is8Bit() &amp;&amp; adapter5.is8Bit() &amp;&amp; adapter6.is8Bit() &amp;&amp; adapter7.is8Bit() &amp;&amp; adapter8.is8Bit() &amp;&amp; adapter9.is8Bit()) {
-        LChar* buffer;
-        RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
-            return nullptr;
-
-        LChar* result = buffer;
-        adapter1.writeTo(result);
-        result += adapter1.length();
-        adapter2.writeTo(result);
-        result += adapter2.length();
-        adapter3.writeTo(result);
-        result += adapter3.length();
-        adapter4.writeTo(result);
-        result += adapter4.length();
-        adapter5.writeTo(result);
-        result += adapter5.length();
-        adapter6.writeTo(result);
-        result += adapter6.length();
-        adapter7.writeTo(result);
-        result += adapter7.length();
-        adapter8.writeTo(result);
-        result += adapter8.length();
-        adapter9.writeTo(result);
-
-        return WTF::move(resultImpl);
-    }
-
-    UChar* buffer;
-    RefPtr&lt;StringImpl&gt; resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return nullptr;
-
-    UChar* result = buffer;
-    adapter1.writeTo(result);
-    result += adapter1.length();
-    adapter2.writeTo(result);
-    result += adapter2.length();
-    adapter3.writeTo(result);
-    result += adapter3.length();
-    adapter4.writeTo(result);
-    result += adapter4.length();
-    adapter5.writeTo(result);
-    result += adapter5.length();
-    adapter6.writeTo(result);
-    result += adapter6.length();
-    adapter7.writeTo(result);
-    result += adapter7.length();
-    adapter8.writeTo(result);
-    result += adapter8.length();
-    adapter9.writeTo(result);
-
-    return WTF::move(resultImpl);
-}
-
-
</del><span class="cx"> // Convenience only.
</span><del>-template&lt;typename StringType1&gt;
-String makeString(StringType1 string1)
</del><ins>+template&lt;typename T&gt;
+String makeString(T&amp;&amp; string)
</ins><span class="cx"> {
</span><del>-    return String(string1);
</del><ins>+    return std::forward&lt;T&gt;(string);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename StringType1, typename StringType2&gt;
-String makeString(StringType1 string1, StringType2 string2)
</del><ins>+template&lt;typename T1, typename T2, typename... Ts&gt;
+String makeString(const T1&amp; string1, const T2&amp; string2, const Ts&amp;... strings)
</ins><span class="cx"> {
</span><del>-    RefPtr&lt;StringImpl&gt; resultImpl = tryMakeString(string1, string2);
-    if (!resultImpl)
</del><ins>+    RefPtr&lt;StringImpl&gt; result = tryMakeString(string1, string2, strings...);
+    if (!result)
</ins><span class="cx">         CRASH();
</span><del>-    return WTF::move(resultImpl);
</del><ins>+    return WTF::move(result);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename StringType1, typename StringType2, typename StringType3&gt;
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3)
-{
-    RefPtr&lt;StringImpl&gt; resultImpl = tryMakeString(string1, string2, string3);
-    if (!resultImpl)
-        CRASH();
-    return WTF::move(resultImpl);
-}
-
-template&lt;typename StringType1, typename StringType2, typename StringType3, typename StringType4&gt;
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
-{
-    RefPtr&lt;StringImpl&gt; resultImpl = tryMakeString(string1, string2, string3, string4);
-    if (!resultImpl)
-        CRASH();
-    return WTF::move(resultImpl);
-}
-
-template&lt;typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5&gt;
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
-{
-    RefPtr&lt;StringImpl&gt; resultImpl = tryMakeString(string1, string2, string3, string4, string5);
-    if (!resultImpl)
-        CRASH();
-    return WTF::move(resultImpl);
-}
-
-template&lt;typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6&gt;
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
-{
-    RefPtr&lt;StringImpl&gt; resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6);
-    if (!resultImpl)
-        CRASH();
-    return WTF::move(resultImpl);
-}
-
-template&lt;typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7&gt;
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
-{
-    RefPtr&lt;StringImpl&gt; resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7);
-    if (!resultImpl)
-        CRASH();
-    return WTF::move(resultImpl);
-}
-
-template&lt;typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8&gt;
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
-{
-    RefPtr&lt;StringImpl&gt; resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8);
-    if (!resultImpl)
-        CRASH();
-    return WTF::move(resultImpl);
-}
-
-template&lt;typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8, typename StringType9&gt;
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8, StringType9 string9)
-{
-    RefPtr&lt;StringImpl&gt; resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8, string9);
-    if (!resultImpl)
-        CRASH();
-    return WTF::move(resultImpl);
-}
-
</del><span class="cx"> } // namespace WTF
</span><span class="cx"> 
</span><span class="cx"> using WTF::makeString;
</span></span></pre></div>
<a id="trunkSourceWTFwtftextStringOperatorsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/StringOperators.h (187814 => 187815)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringOperators.h        2015-08-04 06:05:35 UTC (rev 187814)
+++ trunk/Source/WTF/wtf/text/StringOperators.h        2015-08-04 06:27:12 UTC (rev 187815)
</span><span class="lines">@@ -24,21 +24,20 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><del>-template&lt;typename StringType1, typename StringType2&gt;
</del><ins>+template&lt;typename T1, typename T2&gt;
</ins><span class="cx"> class StringAppend {
</span><span class="cx"> public:
</span><del>-    StringAppend(StringType1 string1, StringType2 string2)
-        : m_string1(string1)
-        , m_string2(string2)
</del><ins>+    StringAppend(const T1&amp; string1, const T2&amp; string2)
+        : m_tuple(std::make_tuple(AdapterType&lt;T1&gt;(string1), AdapterType&lt;T2&gt;(string2)))
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     operator String() const
</span><span class="cx">     {
</span><del>-        RefPtr&lt;StringImpl&gt; resultImpl = tryMakeString(m_string1, m_string2);
</del><ins>+        RefPtr&lt;StringImpl&gt; resultImpl = StringAdapterTuple&lt;2, AdapterType&lt;T1&gt;, AdapterType&lt;T2&gt;&gt;::createString(m_tuple);
</ins><span class="cx">         if (!resultImpl)
</span><span class="cx">             CRASH();
</span><del>-        return resultImpl.release();
</del><ins>+        return WTF::move(resultImpl);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     operator AtomicString() const
</span><span class="lines">@@ -46,59 +45,52 @@
</span><span class="cx">         return operator String();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    bool is8Bit()
</del><ins>+    bool is8Bit() const
</ins><span class="cx">     {
</span><del>-        StringTypeAdapter&lt;StringType1&gt; adapter1(m_string1);
-        StringTypeAdapter&lt;StringType2&gt; adapter2(m_string2);
-        return adapter1.is8Bit() &amp;&amp; adapter2.is8Bit();
</del><ins>+        return string1().is8Bit() &amp;&amp; string2().is8Bit();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void writeTo(LChar* destination)
</del><ins>+    void writeTo(LChar* destination) const
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(is8Bit());
</span><del>-        StringTypeAdapter&lt;StringType1&gt; adapter1(m_string1);
-        StringTypeAdapter&lt;StringType2&gt; adapter2(m_string2);
-        adapter1.writeTo(destination);
-        adapter2.writeTo(destination + adapter1.length());
</del><ins>+        string1().writeTo(destination);
+        string2().writeTo(destination + string1().length());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void writeTo(UChar* destination)
</del><ins>+    void writeTo(UChar* destination) const
</ins><span class="cx">     {
</span><del>-        StringTypeAdapter&lt;StringType1&gt; adapter1(m_string1);
-        StringTypeAdapter&lt;StringType2&gt; adapter2(m_string2);
-        adapter1.writeTo(destination);
-        adapter2.writeTo(destination + adapter1.length());
</del><ins>+        string1().writeTo(destination);
+        string2().writeTo(destination + string1().length());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    unsigned length()
</del><ins>+    unsigned length() const
</ins><span class="cx">     {
</span><del>-        StringTypeAdapter&lt;StringType1&gt; adapter1(m_string1);
-        StringTypeAdapter&lt;StringType2&gt; adapter2(m_string2);
-        return adapter1.length() + adapter2.length();
</del><ins>+        return string1().length() + string2().length();
</ins><span class="cx">     }    
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    StringType1 m_string1;
-    StringType2 m_string2;
</del><ins>+    std::tuple&lt;AdapterType&lt;T1&gt;, AdapterType&lt;T2&gt;&gt; m_tuple;
+    const AdapterType&lt;T1&gt;&amp; string1() const { return std::get&lt;0&gt;(m_tuple); }
+    const AdapterType&lt;T2&gt;&amp; string2() const { return std::get&lt;1&gt;(m_tuple); }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename StringType1, typename StringType2&gt;
</span><span class="cx"> class StringTypeAdapter&lt;StringAppend&lt;StringType1, StringType2&gt;&gt; {
</span><span class="cx"> public:
</span><del>-    StringTypeAdapter&lt;StringAppend&lt;StringType1, StringType2&gt;&gt;(StringAppend&lt;StringType1, StringType2&gt;&amp; buffer)
</del><ins>+    StringTypeAdapter&lt;StringAppend&lt;StringType1, StringType2&gt;&gt;(const StringAppend&lt;StringType1, StringType2&gt;&amp; buffer)
</ins><span class="cx">         : m_buffer(buffer)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    unsigned length() { return m_buffer.length(); }
</del><ins>+    unsigned length() const { return m_buffer.length(); }
</ins><span class="cx"> 
</span><del>-    bool is8Bit() { return m_buffer.is8Bit(); }
</del><ins>+    bool is8Bit() const { return m_buffer.is8Bit(); }
</ins><span class="cx"> 
</span><del>-    void writeTo(LChar* destination) { m_buffer.writeTo(destination); }
-    void writeTo(UChar* destination) { m_buffer.writeTo(destination); }
</del><ins>+    void writeTo(LChar* destination) const { m_buffer.writeTo(destination); }
+    void writeTo(UChar* destination) const { m_buffer.writeTo(destination); }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    StringAppend&lt;StringType1, StringType2&gt;&amp; m_buffer;
</del><ins>+    const StringAppend&lt;StringType1, StringType2&gt;&amp; m_buffer;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> inline StringAppend&lt;const char*, String&gt; operator+(const char* string1, const String&amp; string2)
</span></span></pre>
</div>
</div>

</body>
</html>