Title: [187815] trunk/Source/WTF
Revision
187815
Author
[email protected]
Date
2015-08-03 23:27:12 -0700 (Mon, 03 Aug 2015)

Log Message

[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<>::createString() directly when concatenating the two objects
into one String.

* wtf/text/StringConcatenate.h:
(WTF::StringTypeAdapter<char>::length):
(WTF::StringTypeAdapter<char>::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):

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (187814 => 187815)


--- 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)
@@ -1,3 +1,45 @@
+2015-08-03  Zan Dobersek  <[email protected]>
+
+        [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<>::createString() directly when concatenating the two objects
+        into one String.
+
+        * wtf/text/StringConcatenate.h:
+        (WTF::StringTypeAdapter<char>::length):
+        (WTF::StringTypeAdapter<char>::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):
+
 2015-08-03  Anders Carlsson  <[email protected]>
 
         Make it possible to use String::utf8() in the debugger

Modified: trunk/Source/WTF/wtf/text/StringConcatenate.h (187814 => 187815)


--- 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)
@@ -55,8 +55,8 @@
     {
     }
 
-    unsigned length() { return 1; }
-    bool is8Bit() { return true; }
+    unsigned length() const { return 1; }
+    bool is8Bit() const { return true; }
 
     void writeTo(LChar* destination) const
     {
@@ -98,6 +98,74 @@
     UChar m_character;
 };
 
+template<size_t stringLiteralLength>
+class StringTypeAdapter<char[stringLiteralLength]> {
+public:
+    StringTypeAdapter(const char (&stringLiteral)[stringLiteralLength])
+        : m_string(reinterpret_cast<const LChar*>(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<size_t stringLiteralLength>
+class StringTypeAdapter<const char[stringLiteralLength]> : public StringTypeAdapter<char[stringLiteralLength]> {
+public:
+    StringTypeAdapter(const char (&stringLiteral)[stringLiteralLength])
+        : StringTypeAdapter<char[stringLiteralLength]>(stringLiteral)
+    {
+    }
+};
+
+template<size_t stringLiteralLength>
+class StringTypeAdapter<UChar[stringLiteralLength]> {
+public:
+    StringTypeAdapter(const UChar (&stringLiteral)[stringLiteralLength])
+        : m_string(reinterpret_cast<const UChar*>(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<size_t stringLiteralLength>
+class StringTypeAdapter<const UChar[stringLiteralLength]> : public StringTypeAdapter<UChar[stringLiteralLength]> {
+public:
+    StringTypeAdapter(const UChar (&stringLiteral)[stringLiteralLength])
+        : StringTypeAdapter<UChar[stringLiteralLength]>(stringLiteral)
+    {
+    }
+};
+
 template<>
 class StringTypeAdapter<const LChar*> {
 public:
@@ -247,574 +315,87 @@
     }
 };
 
-inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow)
-{
-    unsigned oldTotal = total;
-    total = oldTotal + addend;
-    if (total < oldTotal)
-        overflow = true;
-}
-
-template<typename StringType1, typename StringType2>
-RefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2)
-{
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-
-    bool overflow = false;
-    unsigned length = adapter1.length();
-    sumWithOverflow(length, adapter2.length(), overflow);
-    if (overflow)
-        return nullptr;
-
-    if (adapter1.is8Bit() && adapter2.is8Bit()) {
-        LChar* buffer;
-        RefPtr<StringImpl> 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);
+template<size_t index, typename... Adapters>
+struct StringAdapterTuple {
+    static inline Checked<unsigned, RecordOverflow> sumWithOverflow(const std::tuple<Adapters...>& tuple)
+    {
+        auto& adapter = std::get<sizeof...(Adapters) - index>(tuple);
+        return Checked<unsigned, RecordOverflow>(adapter.length()) + StringAdapterTuple<index - 1, Adapters...>::sumWithOverflow(tuple);
     }
 
-    UChar* buffer;
-    RefPtr<StringImpl> 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<typename StringType1, typename StringType2, typename StringType3>
-RefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3)
-{
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-    StringTypeAdapter<StringType3> 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() && adapter2.is8Bit() && adapter3.is8Bit()) {
-        LChar* buffer;
-        RefPtr<StringImpl> 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);
+    static inline bool is8Bit(const std::tuple<Adapters...>& tuple)
+    {
+        auto& adapter = std::get<sizeof...(Adapters) - index>(tuple);
+        return adapter.is8Bit() && StringAdapterTuple<index - 1, Adapters...>::is8Bit(tuple);
     }
 
-    UChar* buffer = 0;
-    RefPtr<StringImpl> 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<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
-RefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
-{
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-    StringTypeAdapter<StringType3> adapter3(string3);
-    StringTypeAdapter<StringType4> 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() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit()) {
-        LChar* buffer;
-        RefPtr<StringImpl> 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);
+    template<typename T>
+    static inline void writeTo(T* buffer, const std::tuple<Adapters...>& tuple)
+    {
+        auto& adapter = std::get<sizeof...(Adapters) - index>(tuple);
+        adapter.writeTo(buffer);
+        StringAdapterTuple<index - 1, Adapters...>::writeTo(buffer + adapter.length(), tuple);
     }
 
-    UChar* buffer;
-    RefPtr<StringImpl> 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<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
-RefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
-{
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-    StringTypeAdapter<StringType3> adapter3(string3);
-    StringTypeAdapter<StringType4> adapter4(string4);
-    StringTypeAdapter<StringType5> 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() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit()) {
-        LChar* buffer;
-        RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
+    static inline RefPtr<StringImpl> createString(const std::tuple<Adapters...>& adapters)
+    {
+        unsigned length = 0;
+        if (sumWithOverflow(adapters).safeGet(length) == CheckedState::DidOverflow)
             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);
+        if (is8Bit(adapters)) {
+            LChar* buffer;
+            RefPtr<StringImpl> result = StringImpl::tryCreateUninitialized(length, buffer);
+            if (!result)
+                return nullptr;
 
-        return WTF::move(resultImpl);
-    }
+            writeTo(buffer, adapters);
+            return result;
+        }
 
-    UChar* buffer;
-    RefPtr<StringImpl> 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<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
-RefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
-{
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-    StringTypeAdapter<StringType3> adapter3(string3);
-    StringTypeAdapter<StringType4> adapter4(string4);
-    StringTypeAdapter<StringType5> adapter5(string5);
-    StringTypeAdapter<StringType6> 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() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit()) {
-        LChar* buffer;
-        RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-        if (!resultImpl)
+        UChar* buffer;
+        RefPtr<StringImpl> result = StringImpl::tryCreateUninitialized(length, buffer);
+        if (!result)
             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);
-
-        return WTF::move(resultImpl);
+        writeTo(buffer, adapters);
+        return result;
     }
+};
 
-    UChar* buffer;
-    RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
-    if (!resultImpl)
-        return nullptr;
+template<typename... Adapters>
+struct StringAdapterTuple<0, Adapters...> {
+    static Checked<unsigned, RecordOverflow> sumWithOverflow(const std::tuple<Adapters...>&) { return 0; }
+    static bool is8Bit(const std::tuple<Adapters...>&) { return true; }
+    template<typename T> static void writeTo(T*, const std::tuple<Adapters...>&) { }
+};
 
-    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);
+template<typename T>
+using AdapterType = StringTypeAdapter<typename std::decay<T>::type>;
 
-    return WTF::move(resultImpl);
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
-RefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
+template<typename T1, typename T2, typename... Ts>
+RefPtr<StringImpl> tryMakeString(const T1& string1, const T2& string2, const Ts&... strings)
 {
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-    StringTypeAdapter<StringType3> adapter3(string3);
-    StringTypeAdapter<StringType4> adapter4(string4);
-    StringTypeAdapter<StringType5> adapter5(string5);
-    StringTypeAdapter<StringType6> adapter6(string6);
-    StringTypeAdapter<StringType7> 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() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit()) {
-        LChar* buffer;
-        RefPtr<StringImpl> 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<StringImpl> 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);
+    auto adapters = std::make_tuple(AdapterType<T1>(string1), AdapterType<T2>(string2), AdapterType<Ts>(strings)...);
+    return StringAdapterTuple<2 + sizeof...(Ts), AdapterType<T1>, AdapterType<T2>, AdapterType<Ts>...>::createString(adapters);
 }
 
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
-RefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
-{
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-    StringTypeAdapter<StringType3> adapter3(string3);
-    StringTypeAdapter<StringType4> adapter4(string4);
-    StringTypeAdapter<StringType5> adapter5(string5);
-    StringTypeAdapter<StringType6> adapter6(string6);
-    StringTypeAdapter<StringType7> adapter7(string7);
-    StringTypeAdapter<StringType8> 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() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit() && adapter8.is8Bit()) {
-        LChar* buffer;
-        RefPtr<StringImpl> 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<StringImpl> 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<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8, typename StringType9>
-RefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8, StringType9 string9)
-{
-    StringTypeAdapter<StringType1> adapter1(string1);
-    StringTypeAdapter<StringType2> adapter2(string2);
-    StringTypeAdapter<StringType3> adapter3(string3);
-    StringTypeAdapter<StringType4> adapter4(string4);
-    StringTypeAdapter<StringType5> adapter5(string5);
-    StringTypeAdapter<StringType6> adapter6(string6);
-    StringTypeAdapter<StringType7> adapter7(string7);
-    StringTypeAdapter<StringType8> adapter8(string8);
-    StringTypeAdapter<StringType9> 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() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit() && adapter8.is8Bit() && adapter9.is8Bit()) {
-        LChar* buffer;
-        RefPtr<StringImpl> 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<StringImpl> 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);
-}
-
-
 // Convenience only.
-template<typename StringType1>
-String makeString(StringType1 string1)
+template<typename T>
+String makeString(T&& string)
 {
-    return String(string1);
+    return std::forward<T>(string);
 }
 
-template<typename StringType1, typename StringType2>
-String makeString(StringType1 string1, StringType2 string2)
+template<typename T1, typename T2, typename... Ts>
+String makeString(const T1& string1, const T2& string2, const Ts&... strings)
 {
-    RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2);
-    if (!resultImpl)
+    RefPtr<StringImpl> result = tryMakeString(string1, string2, strings...);
+    if (!result)
         CRASH();
-    return WTF::move(resultImpl);
+    return WTF::move(result);
 }
 
-template<typename StringType1, typename StringType2, typename StringType3>
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3)
-{
-    RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3);
-    if (!resultImpl)
-        CRASH();
-    return WTF::move(resultImpl);
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
-{
-    RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4);
-    if (!resultImpl)
-        CRASH();
-    return WTF::move(resultImpl);
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
-{
-    RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5);
-    if (!resultImpl)
-        CRASH();
-    return WTF::move(resultImpl);
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
-{
-    RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6);
-    if (!resultImpl)
-        CRASH();
-    return WTF::move(resultImpl);
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
-{
-    RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7);
-    if (!resultImpl)
-        CRASH();
-    return WTF::move(resultImpl);
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
-{
-    RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8);
-    if (!resultImpl)
-        CRASH();
-    return WTF::move(resultImpl);
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8, typename StringType9>
-String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8, StringType9 string9)
-{
-    RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8, string9);
-    if (!resultImpl)
-        CRASH();
-    return WTF::move(resultImpl);
-}
-
 } // namespace WTF
 
 using WTF::makeString;

Modified: trunk/Source/WTF/wtf/text/StringOperators.h (187814 => 187815)


--- 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)
@@ -24,21 +24,20 @@
 
 namespace WTF {
 
-template<typename StringType1, typename StringType2>
+template<typename T1, typename T2>
 class StringAppend {
 public:
-    StringAppend(StringType1 string1, StringType2 string2)
-        : m_string1(string1)
-        , m_string2(string2)
+    StringAppend(const T1& string1, const T2& string2)
+        : m_tuple(std::make_tuple(AdapterType<T1>(string1), AdapterType<T2>(string2)))
     {
     }
 
     operator String() const
     {
-        RefPtr<StringImpl> resultImpl = tryMakeString(m_string1, m_string2);
+        RefPtr<StringImpl> resultImpl = StringAdapterTuple<2, AdapterType<T1>, AdapterType<T2>>::createString(m_tuple);
         if (!resultImpl)
             CRASH();
-        return resultImpl.release();
+        return WTF::move(resultImpl);
     }
 
     operator AtomicString() const
@@ -46,59 +45,52 @@
         return operator String();
     }
 
-    bool is8Bit()
+    bool is8Bit() const
     {
-        StringTypeAdapter<StringType1> adapter1(m_string1);
-        StringTypeAdapter<StringType2> adapter2(m_string2);
-        return adapter1.is8Bit() && adapter2.is8Bit();
+        return string1().is8Bit() && string2().is8Bit();
     }
 
-    void writeTo(LChar* destination)
+    void writeTo(LChar* destination) const
     {
         ASSERT(is8Bit());
-        StringTypeAdapter<StringType1> adapter1(m_string1);
-        StringTypeAdapter<StringType2> adapter2(m_string2);
-        adapter1.writeTo(destination);
-        adapter2.writeTo(destination + adapter1.length());
+        string1().writeTo(destination);
+        string2().writeTo(destination + string1().length());
     }
 
-    void writeTo(UChar* destination)
+    void writeTo(UChar* destination) const
     {
-        StringTypeAdapter<StringType1> adapter1(m_string1);
-        StringTypeAdapter<StringType2> adapter2(m_string2);
-        adapter1.writeTo(destination);
-        adapter2.writeTo(destination + adapter1.length());
+        string1().writeTo(destination);
+        string2().writeTo(destination + string1().length());
     }
 
-    unsigned length()
+    unsigned length() const
     {
-        StringTypeAdapter<StringType1> adapter1(m_string1);
-        StringTypeAdapter<StringType2> adapter2(m_string2);
-        return adapter1.length() + adapter2.length();
+        return string1().length() + string2().length();
     }    
 
 private:
-    StringType1 m_string1;
-    StringType2 m_string2;
+    std::tuple<AdapterType<T1>, AdapterType<T2>> m_tuple;
+    const AdapterType<T1>& string1() const { return std::get<0>(m_tuple); }
+    const AdapterType<T2>& string2() const { return std::get<1>(m_tuple); }
 };
 
 template<typename StringType1, typename StringType2>
 class StringTypeAdapter<StringAppend<StringType1, StringType2>> {
 public:
-    StringTypeAdapter<StringAppend<StringType1, StringType2>>(StringAppend<StringType1, StringType2>& buffer)
+    StringTypeAdapter<StringAppend<StringType1, StringType2>>(const StringAppend<StringType1, StringType2>& buffer)
         : m_buffer(buffer)
     {
     }
 
-    unsigned length() { return m_buffer.length(); }
+    unsigned length() const { return m_buffer.length(); }
 
-    bool is8Bit() { return m_buffer.is8Bit(); }
+    bool is8Bit() const { return m_buffer.is8Bit(); }
 
-    void writeTo(LChar* destination) { m_buffer.writeTo(destination); }
-    void writeTo(UChar* destination) { m_buffer.writeTo(destination); }
+    void writeTo(LChar* destination) const { m_buffer.writeTo(destination); }
+    void writeTo(UChar* destination) const { m_buffer.writeTo(destination); }
 
 private:
-    StringAppend<StringType1, StringType2>& m_buffer;
+    const StringAppend<StringType1, StringType2>& m_buffer;
 };
 
 inline StringAppend<const char*, String> operator+(const char* string1, const String& string2)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to