makeString: support more integral types
authorjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Dec 2017 00:50:34 +0000 (00:50 +0000)
committerjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Dec 2017 00:50:34 +0000 (00:50 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180720

Reviewed by Sam Weinig.

Source/WTF:

Only some integral types worked. Add more types by using template
magic. While we're here, also use the same magic for
floating-point types in the theoretical future where short float
or long double matter.

The core of the magic is a second, defaulted, template
parameter. It's declared in Forward.h (as void), and then in
classes where we want to enable_if we use it (in C++ speak we
create a partial class template specialization), otherwise we
leave it as void.

Also clean up some constructors which were being way too verbose
in stating that they were declarations for this template
specialization right here, when really we already knew that.

* wtf/Forward.h:
* wtf/text/StringConcatenate.h:
(WTF::StringTypeAdapter<char>::StringTypeAdapter<char>): Deleted.
(WTF::StringTypeAdapter<char>::length): Deleted.
(WTF::StringTypeAdapter<char>::is8Bit): Deleted.
(WTF::StringTypeAdapter<char>::writeTo const): Deleted.
(WTF::StringTypeAdapter<char>::toString const): Deleted.
(WTF::StringTypeAdapter<UChar>::StringTypeAdapter<UChar>): Deleted.
(WTF::StringTypeAdapter<UChar>::length const): Deleted.
(WTF::StringTypeAdapter<UChar>::is8Bit const): Deleted.
(WTF::StringTypeAdapter<UChar>::writeTo const): Deleted.
(WTF::StringTypeAdapter<UChar>::toString const): Deleted.
(WTF::StringTypeAdapter<char::StringTypeAdapter): Deleted.
(WTF::StringTypeAdapter<ASCIILiteral>::StringTypeAdapter): Deleted.
(WTF::StringTypeAdapter<Vector<char>>::StringTypeAdapter): Deleted.
(WTF::StringTypeAdapter<Vector<char>>::length const): Deleted.
(WTF::StringTypeAdapter<Vector<char>>::is8Bit const): Deleted.
(WTF::StringTypeAdapter<Vector<char>>::writeTo const): Deleted.
(WTF::StringTypeAdapter<Vector<char>>::toString const): Deleted.
(WTF::StringTypeAdapter<String>::StringTypeAdapter<String>): Deleted.
(WTF::StringTypeAdapter<String>::length const): Deleted.
(WTF::StringTypeAdapter<String>::is8Bit const): Deleted.
(WTF::StringTypeAdapter<String>::writeTo const): Deleted.
(WTF::StringTypeAdapter<String>::toString const): Deleted.
(WTF::StringTypeAdapter<AtomicString>::StringTypeAdapter): Deleted.
* wtf/text/StringConcatenateNumbers.h:
(WTF::StringTypeAdapter<FormattedNumber>::StringTypeAdapter):
(WTF::StringTypeAdapter<int>::StringTypeAdapter<int>): Deleted.
(WTF::StringTypeAdapter<int>::length const): Deleted.
(WTF::StringTypeAdapter<int>::is8Bit const): Deleted.
(WTF::StringTypeAdapter<int>::writeTo const): Deleted.
(WTF::StringTypeAdapter<int>::toString const): Deleted.
(WTF::StringTypeAdapter<unsigned>::StringTypeAdapter<unsigned>): Deleted.
(WTF::StringTypeAdapter<unsigned>::length const): Deleted.
(WTF::StringTypeAdapter<unsigned>::is8Bit const): Deleted.
(WTF::StringTypeAdapter<unsigned>::writeTo const): Deleted.
(WTF::StringTypeAdapter<unsigned>::toString const): Deleted.
(WTF::StringTypeAdapter<double>::StringTypeAdapter<double>): Deleted.
(WTF::StringTypeAdapter<double>::length const): Deleted.
(WTF::StringTypeAdapter<double>::is8Bit const): Deleted.
(WTF::StringTypeAdapter<double>::writeTo const): Deleted.
(WTF::StringTypeAdapter<double>::toString const): Deleted.
(WTF::StringTypeAdapter<float>::StringTypeAdapter<float>): Deleted.
(WTF::StringTypeAdapter<FormattedNumber>::StringTypeAdapter<FormattedNumber>): Deleted.
* wtf/text/StringView.h:
(WTF::StringTypeAdapter<StringView>::StringTypeAdapter<StringView>): Deleted.
(WTF::StringTypeAdapter<StringView>::length): Deleted.
(WTF::StringTypeAdapter<StringView>::is8Bit): Deleted.
(WTF::StringTypeAdapter<StringView>::writeTo): Deleted.
(WTF::StringTypeAdapter<StringView>::toString const): Deleted.

Tools:

Test a few more types can be made string'd.

* TestWebKitAPI/Tests/WTF/StringConcatenate.cpp:
(TestWebKitAPI::TEST):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225824 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WTF/ChangeLog
Source/WTF/wtf/Forward.h
Source/WTF/wtf/text/StringConcatenate.h
Source/WTF/wtf/text/StringConcatenateNumbers.h
Source/WTF/wtf/text/StringView.h
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WTF/StringConcatenate.cpp

index 6db4db6..47283cf 100644 (file)
@@ -1,3 +1,76 @@
+2017-12-12  JF Bastien  <jfbastien@apple.com>
+
+        makeString: support more integral types
+        https://bugs.webkit.org/show_bug.cgi?id=180720
+
+        Reviewed by Sam Weinig.
+
+        Only some integral types worked. Add more types by using template
+        magic. While we're here, also use the same magic for
+        floating-point types in the theoretical future where short float
+        or long double matter.
+
+        The core of the magic is a second, defaulted, template
+        parameter. It's declared in Forward.h (as void), and then in
+        classes where we want to enable_if we use it (in C++ speak we
+        create a partial class template specialization), otherwise we
+        leave it as void.
+
+        Also clean up some constructors which were being way too verbose
+        in stating that they were declarations for this template
+        specialization right here, when really we already knew that.
+
+        * wtf/Forward.h:
+        * wtf/text/StringConcatenate.h:
+        (WTF::StringTypeAdapter<char>::StringTypeAdapter<char>): Deleted.
+        (WTF::StringTypeAdapter<char>::length): Deleted.
+        (WTF::StringTypeAdapter<char>::is8Bit): Deleted.
+        (WTF::StringTypeAdapter<char>::writeTo const): Deleted.
+        (WTF::StringTypeAdapter<char>::toString const): Deleted.
+        (WTF::StringTypeAdapter<UChar>::StringTypeAdapter<UChar>): Deleted.
+        (WTF::StringTypeAdapter<UChar>::length const): Deleted.
+        (WTF::StringTypeAdapter<UChar>::is8Bit const): Deleted.
+        (WTF::StringTypeAdapter<UChar>::writeTo const): Deleted.
+        (WTF::StringTypeAdapter<UChar>::toString const): Deleted.
+        (WTF::StringTypeAdapter<char::StringTypeAdapter): Deleted.
+        (WTF::StringTypeAdapter<ASCIILiteral>::StringTypeAdapter): Deleted.
+        (WTF::StringTypeAdapter<Vector<char>>::StringTypeAdapter): Deleted.
+        (WTF::StringTypeAdapter<Vector<char>>::length const): Deleted.
+        (WTF::StringTypeAdapter<Vector<char>>::is8Bit const): Deleted.
+        (WTF::StringTypeAdapter<Vector<char>>::writeTo const): Deleted.
+        (WTF::StringTypeAdapter<Vector<char>>::toString const): Deleted.
+        (WTF::StringTypeAdapter<String>::StringTypeAdapter<String>): Deleted.
+        (WTF::StringTypeAdapter<String>::length const): Deleted.
+        (WTF::StringTypeAdapter<String>::is8Bit const): Deleted.
+        (WTF::StringTypeAdapter<String>::writeTo const): Deleted.
+        (WTF::StringTypeAdapter<String>::toString const): Deleted.
+        (WTF::StringTypeAdapter<AtomicString>::StringTypeAdapter): Deleted.
+        * wtf/text/StringConcatenateNumbers.h:
+        (WTF::StringTypeAdapter<FormattedNumber>::StringTypeAdapter):
+        (WTF::StringTypeAdapter<int>::StringTypeAdapter<int>): Deleted.
+        (WTF::StringTypeAdapter<int>::length const): Deleted.
+        (WTF::StringTypeAdapter<int>::is8Bit const): Deleted.
+        (WTF::StringTypeAdapter<int>::writeTo const): Deleted.
+        (WTF::StringTypeAdapter<int>::toString const): Deleted.
+        (WTF::StringTypeAdapter<unsigned>::StringTypeAdapter<unsigned>): Deleted.
+        (WTF::StringTypeAdapter<unsigned>::length const): Deleted.
+        (WTF::StringTypeAdapter<unsigned>::is8Bit const): Deleted.
+        (WTF::StringTypeAdapter<unsigned>::writeTo const): Deleted.
+        (WTF::StringTypeAdapter<unsigned>::toString const): Deleted.
+        (WTF::StringTypeAdapter<double>::StringTypeAdapter<double>): Deleted.
+        (WTF::StringTypeAdapter<double>::length const): Deleted.
+        (WTF::StringTypeAdapter<double>::is8Bit const): Deleted.
+        (WTF::StringTypeAdapter<double>::writeTo const): Deleted.
+        (WTF::StringTypeAdapter<double>::toString const): Deleted.
+        (WTF::StringTypeAdapter<float>::StringTypeAdapter<float>): Deleted.
+        (WTF::StringTypeAdapter<FormattedNumber>::StringTypeAdapter<FormattedNumber>): Deleted.
+        * wtf/text/StringView.h:
+        (WTF::StringTypeAdapter<StringView>::StringTypeAdapter<StringView>): Deleted.
+        (WTF::StringTypeAdapter<StringView>::length): Deleted.
+        (WTF::StringTypeAdapter<StringView>::is8Bit): Deleted.
+        (WTF::StringTypeAdapter<StringView>::writeTo): Deleted.
+        (WTF::StringTypeAdapter<StringView>::toString const): Deleted.
+
 2017-12-12  Caio Lima  <ticaiolima@gmail.com>
 
         [ESNext][BigInt] Implement BigInt literals and JSBigInt
index ef00c71..9115d7f 100644 (file)
@@ -55,6 +55,7 @@ template<typename> class OptionSet;
 template<typename> class Ref;
 template<typename> class RefPtr;
 template<typename> class StringBuffer;
+template<typename, typename = void> class StringTypeAdapter;
 
 template<typename> struct DefaultHash { using Hash = void; };
 template<typename> struct HashTraits;
index affb7e1..18ff3f8 100644 (file)
 
 namespace WTF {
 
-template<typename StringType>
+template<typename StringType, typename>
 class StringTypeAdapter;
 
 template<>
-class StringTypeAdapter<char> {
+class StringTypeAdapter<char, void> {
 public:
-    StringTypeAdapter<char>(char character)
+    StringTypeAdapter(char character)
         : m_character(character)
     {
     }
@@ -75,9 +75,9 @@ private:
 };
 
 template<>
-class StringTypeAdapter<UChar> {
+class StringTypeAdapter<UChar, void> {
 public:
-    StringTypeAdapter<UChar>(UChar character)
+    StringTypeAdapter(UChar character)
         : m_character(character)
     {
     }
@@ -103,7 +103,7 @@ private:
 };
 
 template<>
-class StringTypeAdapter<const LChar*> {
+class StringTypeAdapter<const LChar*, void> {
 public:
     StringTypeAdapter(const LChar* characters)
         : m_characters(characters)
@@ -132,7 +132,7 @@ private:
 };
 
 template<>
-class StringTypeAdapter<const UChar*> {
+class StringTypeAdapter<const UChar*, void> {
 public:
     StringTypeAdapter(const UChar* characters)
         : m_characters(characters)
@@ -168,34 +168,34 @@ private:
 };
 
 template<>
-class StringTypeAdapter<const char*> : public StringTypeAdapter<const LChar*> {
+class StringTypeAdapter<const char*, void> : public StringTypeAdapter<const LChar*, void> {
 public:
     StringTypeAdapter(const char* characters)
-        : StringTypeAdapter<const LChar*>(reinterpret_cast<const LChar*>(characters))
+        : StringTypeAdapter<const LChar*, void>(reinterpret_cast<const LChar*>(characters))
     {
     }
 };
 
 template<>
-class StringTypeAdapter<char*> : public StringTypeAdapter<const char*> {
+class StringTypeAdapter<char*, void> : public StringTypeAdapter<const char*, void> {
 public:
     StringTypeAdapter(const char* characters)
-        : StringTypeAdapter<const char*>(characters)
+        : StringTypeAdapter<const char*, void>(characters)
     {
     }
 };
 
 template<>
-class StringTypeAdapter<ASCIILiteral> : public StringTypeAdapter<const char*> {
+class StringTypeAdapter<ASCIILiteral, void> : public StringTypeAdapter<const char*, void> {
 public:
     StringTypeAdapter(ASCIILiteral characters)
-        : StringTypeAdapter<const char*>(characters)
+        : StringTypeAdapter<const char*, void>(characters)
     {
     }
 };
 
 template<>
-class StringTypeAdapter<Vector<char>> {
+class StringTypeAdapter<Vector<char>, void> {
 public:
     StringTypeAdapter(const Vector<char>& vector)
         : m_vector(vector)
@@ -222,9 +222,9 @@ private:
 };
 
 template<>
-class StringTypeAdapter<String> {
+class StringTypeAdapter<String, void> {
 public:
-    StringTypeAdapter<String>(const String& string)
+    StringTypeAdapter(const String& string)
         : m_string(string)
     {
     }
@@ -251,10 +251,10 @@ private:
 };
 
 template<>
-class StringTypeAdapter<AtomicString> : public StringTypeAdapter<String> {
+class StringTypeAdapter<AtomicString, void> : public StringTypeAdapter<String, void> {
 public:
     StringTypeAdapter(const AtomicString& string)
-        : StringTypeAdapter<String>(string.string())
+        : StringTypeAdapter<String, void>(string.string())
     {
     }
 };
index 293e745..8c8465a 100644 (file)
 
 namespace WTF {
 
-template<>
-class StringTypeAdapter<int> {
+template<typename SignedInt>
+class StringTypeAdapter<SignedInt, typename std::enable_if_t<std::is_integral<SignedInt>::value && std::is_signed<SignedInt>::value>> {
 public:
-    StringTypeAdapter<int>(int number)
+    StringTypeAdapter(SignedInt number)
         : m_number(number)
     {
     }
@@ -48,13 +48,13 @@ public:
     String toString() const { return String::number(m_number); }
 
 private:
-    int m_number;
+    SignedInt m_number;
 };
 
-template<>
-class StringTypeAdapter<unsigned> {
+template<typename UnsignedInt>
+class StringTypeAdapter<UnsignedInt, typename std::enable_if_t<std::is_integral<UnsignedInt>::value && !std::is_signed<UnsignedInt>::value>> {
 public:
-    StringTypeAdapter<unsigned>(unsigned number)
+    StringTypeAdapter(UnsignedInt number)
         : m_number(number)
     {
     }
@@ -68,13 +68,13 @@ public:
     String toString() const { return String::number(m_number); }
 
 private:
-    unsigned m_number;
+    UnsignedInt m_number;
 };
 
-template<>
-class StringTypeAdapter<double> {
+template<typename FloatingPoint>
+class StringTypeAdapter<FloatingPoint, typename std::enable_if_t<std::is_floating_point<FloatingPoint>::value>> {
 public:
-    StringTypeAdapter<double>(double number)
+    StringTypeAdapter(FloatingPoint number)
     {
         numberToString(number, m_buffer);
         m_length = strlen(m_buffer);
@@ -102,15 +102,6 @@ private:
     unsigned m_length;
 };
 
-template<>
-class StringTypeAdapter<float> : public StringTypeAdapter<double> {
-public:
-    StringTypeAdapter<float>(float number)
-        : StringTypeAdapter<double>(number)
-    {
-    }
-};
-
 class FormattedNumber {
 public:
     static FormattedNumber fixedPrecision(double number, unsigned significantFigures = 6, bool truncateTrailingZeros = false)
@@ -140,7 +131,7 @@ private:
 template<>
 class StringTypeAdapter<FormattedNumber> {
 public:
-    StringTypeAdapter<FormattedNumber>(const FormattedNumber& numberFormatter)
+    StringTypeAdapter(const FormattedNumber& numberFormatter)
         : m_numberFormatter(numberFormatter)
     {
     }
index c88118b..d189ddf 100644 (file)
@@ -566,11 +566,11 @@ inline void StringView::invalidate(const StringImpl&)
 }
 #endif
 
-template<typename StringType> class StringTypeAdapter;
+template<typename StringType, typename> class StringTypeAdapter;
 
-template<> class StringTypeAdapter<StringView> {
+template<> class StringTypeAdapter<StringView, void> {
 public:
-    StringTypeAdapter<StringView>(StringView string)
+    StringTypeAdapter(StringView string)
         : m_string(string)
     {
     }
index 1e7f80b..4bc9657 100644 (file)
@@ -1,3 +1,15 @@
+2017-12-12  JF Bastien  <jfbastien@apple.com>
+
+        makeString: support more integral types
+        https://bugs.webkit.org/show_bug.cgi?id=180720
+
+        Reviewed by Sam Weinig.
+
+        Test a few more types can be made string'd.
+
+        * TestWebKitAPI/Tests/WTF/StringConcatenate.cpp:
+        (TestWebKitAPI::TEST):
+
 2017-12-12  Alicia Boya GarcĂ­a  <aboya@igalia.com>
 
         Flakiness dashboard: Make GTK and WPE builds inherit expectations from WK2
index fc25b08..d4a343e 100644 (file)
 #include "WTFStringUtilities.h"
 #include <wtf/text/StringConcatenate.h>
 #include <wtf/text/StringConcatenateNumbers.h>
+#include <cstddef>
+#include <cstdint>
 
 namespace TestWebKitAPI {
 
+static int arr[2];
+struct S {
+    char c;
+    int i;
+};
+
 TEST(WTF, StringConcatenate)
 {
     EXPECT_EQ("hello world", makeString("hello", " ", "world"));
@@ -40,21 +48,43 @@ TEST(WTF, StringConcatenate_Int)
 {
     EXPECT_EQ(5u, WTF::lengthOfNumberAsStringSigned(17890));
     EXPECT_EQ("hello 17890 world", makeString("hello ", 17890 , " world"));
+    EXPECT_EQ("hello 17890 world", makeString("hello ", 17890l , " world"));
+    EXPECT_EQ("hello 17890 world", makeString("hello ", 17890ll , " world"));
+    EXPECT_EQ("hello 17890 world", makeString("hello ", static_cast<int64_t>(17890) , " world"));
+    EXPECT_EQ("hello 17890 world", makeString("hello ", static_cast<int64_t>(17890) , " world"));
 
     EXPECT_EQ(6u, WTF::lengthOfNumberAsStringSigned(-17890));
     EXPECT_EQ("hello -17890 world", makeString("hello ", -17890 , " world"));
+    EXPECT_EQ("hello -17890 world", makeString("hello ", -17890l , " world"));
+    EXPECT_EQ("hello -17890 world", makeString("hello ", -17890ll , " world"));
+    EXPECT_EQ("hello -17890 world", makeString("hello ", static_cast<int64_t>(-17890) , " world"));
+    EXPECT_EQ("hello -17890 world", makeString("hello ", static_cast<int64_t>(-17890) , " world"));
 
     EXPECT_EQ(1u, WTF::lengthOfNumberAsStringSigned(0));
     EXPECT_EQ("hello 0 world", makeString("hello ", 0 , " world"));
+
+    EXPECT_EQ("hello 42 world", makeString("hello ", static_cast<signed char>(42) , " world"));
+    EXPECT_EQ("hello 42 world", makeString("hello ", static_cast<short>(42) , " world"));
+    EXPECT_EQ("hello 1 world", makeString("hello ", &arr[1] - &arr[0] , " world"));
 }
 
 TEST(WTF, StringConcatenate_Unsigned)
 {
     EXPECT_EQ(5u, WTF::lengthOfNumberAsStringUnsigned(17890u));
     EXPECT_EQ("hello 17890 world", makeString("hello ", 17890u , " world"));
+    EXPECT_EQ("hello 17890 world", makeString("hello ", 17890ul , " world"));
+    EXPECT_EQ("hello 17890 world", makeString("hello ", 17890ull , " world"));
+    EXPECT_EQ("hello 17890 world", makeString("hello ", static_cast<uint64_t>(17890) , " world"));
+    EXPECT_EQ("hello 17890 world", makeString("hello ", static_cast<uint64_t>(17890) , " world"));
 
     EXPECT_EQ(1u, WTF::lengthOfNumberAsStringSigned(0u));
     EXPECT_EQ("hello 0 world", makeString("hello ", 0u , " world"));
+
+    EXPECT_EQ("hello 42 world", makeString("hello ", static_cast<unsigned char>(42) , " world"));
+    EXPECT_EQ("hello * world", makeString("hello ", static_cast<unsigned short>(42) , " world")); // Treated as a character.
+    EXPECT_EQ("hello 4 world", makeString("hello ", sizeof(int) , " world")); // size_t
+    EXPECT_EQ("hello 4 world", makeString("hello ", offsetof(S, i) , " world")); // size_t
+    EXPECT_EQ("hello 3235839742 world", makeString("hello ", static_cast<size_t>(0xc0defefe), " world"));
 }
 
 TEST(WTF, StringConcatenate_Float)