Vector should be able to easily create from a list of movable only items
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 Oct 2017 04:44:51 +0000 (04:44 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 Oct 2017 04:44:51 +0000 (04:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=176432

Patch by Youenn Fablet <youenn@apple.com> on 2017-10-09
Reviewed by Darin Adler.

Source/WTF:

Adding static from method to construct a Vector from movable-only items.
This may also be used instead of initializer list constructor for types that would benefit of being moved.

* wtf/Vector.h:
(WTF::Vector::Vector):
(WTF::Vector::from):
(WTF::Vector::uncheckedInitialize): Introduced as an optimization to set the vector size once.
(WTF::Malloc>::reserveInitialCapacity):

Tools:

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

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

Source/WTF/ChangeLog
Source/WTF/wtf/Vector.h
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WTF/Vector.cpp

index eb91b82..1e5bed0 100644 (file)
@@ -1,3 +1,19 @@
+2017-10-09  Youenn Fablet  <youenn@apple.com>
+
+        Vector should be able to easily create from a list of movable only items
+        https://bugs.webkit.org/show_bug.cgi?id=176432
+
+        Reviewed by Darin Adler.
+
+        Adding static from method to construct a Vector from movable-only items.
+        This may also be used instead of initializer list constructor for types that would benefit of being moved.
+
+        * wtf/Vector.h:
+        (WTF::Vector::Vector):
+        (WTF::Vector::from):
+        (WTF::Vector::uncheckedInitialize): Introduced as an optimization to set the vector size once.
+        (WTF::Malloc>::reserveInitialCapacity):
+
 2017-10-09  Tim Horton  <timothy_horton@apple.com>
 
         Disable INPUT_TYPE_COLOR in FeatureDefines.h
index 7184e90..2c8046b 100644 (file)
@@ -625,6 +625,20 @@ public:
             uncheckedAppend(element);
     }
 
+    template<typename... Items>
+    static Vector from(Items&&... items)
+    {
+        Vector result;
+        auto size = sizeof...(items);
+
+        result.reserveInitialCapacity(size);
+        result.asanSetInitialBufferSizeTo(size);
+        result.m_size = size;
+
+        result.uncheckedInitialize<0>(std::forward<Items>(items)...);
+        return result;
+    }
+
     ~Vector()
     {
         if (m_size)
@@ -793,6 +807,20 @@ private:
     template<typename... Args> void constructAndAppendSlowCase(Args&&...);
     template<typename... Args> bool tryConstructAndAppendSlowCase(Args&&...);
 
+    template<size_t position, typename U, typename... Items>
+    void uncheckedInitialize(U&& item, Items&&... items)
+    {
+        uncheckedInitialize<position>(std::forward<U>(item));
+        uncheckedInitialize<position + 1>(std::forward<Items>(items)...);
+    }
+    template<size_t position, typename U>
+    void uncheckedInitialize(U&& value)
+    {
+        ASSERT(position < size());
+        ASSERT(position < capacity());
+        new (NotNull, begin() + position) T(std::forward<U>(value));
+    }
+
     void asanSetInitialBufferSizeTo(size_t);
     void asanSetBufferSizeToFullCapacity(size_t);
     void asanSetBufferSizeToFullCapacity() { asanSetBufferSizeToFullCapacity(size()); }
@@ -1327,8 +1355,7 @@ ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler, minCapacity, Mallo
 
     asanBufferSizeWillChangeTo(m_size + 1);
 
-    auto ptr = std::addressof(value);
-    new (NotNull, end()) T(std::forward<U>(*ptr));
+    new (NotNull, end()) T(std::forward<U>(value));
     ++m_size;
 }
 
index e7c4288..06259b4 100644 (file)
@@ -1,3 +1,13 @@
+2017-10-09  Youenn Fablet  <youenn@apple.com>
+
+        Vector should be able to easily create from a list of movable only items
+        https://bugs.webkit.org/show_bug.cgi?id=176432
+
+        Reviewed by Darin Adler.
+
+        * TestWebKitAPI/Tests/WTF/Vector.cpp:
+        (TestWebKitAPI::TEST):
+
 2017-09-29  Filip Pizlo  <fpizlo@apple.com>
 
         Enable gigacage on iOS
index 3392622..1852fa9 100644 (file)
@@ -99,6 +99,51 @@ TEST(WTF_Vector, InitializerList)
     EXPECT_EQ(4, vector[3]);
 }
 
+TEST(WTF_Vector, ConstructWithFrom)
+{
+    auto vector = Vector<int>::from(1, 2, 3, 4, 5);
+    EXPECT_EQ(5U, vector.size());
+    EXPECT_EQ(5U, vector.capacity());
+
+    EXPECT_EQ(1, vector[0]);
+    EXPECT_EQ(2, vector[1]);
+    EXPECT_EQ(3, vector[2]);
+    EXPECT_EQ(4, vector[3]);
+    EXPECT_EQ(5, vector[4]);
+}
+
+TEST(WTF_Vector, ConstructWithFromString)
+{
+    String s1 = "s1";
+    String s2 = "s2";
+    String s3 = s1;
+    auto vector = Vector<String>::from(s1, s2, WTFMove(s3));
+    EXPECT_EQ(3U, vector.size());
+    EXPECT_EQ(3U, vector.capacity());
+
+    EXPECT_TRUE(s1 == vector[0]);
+    EXPECT_TRUE(s2 == vector[1]);
+    EXPECT_TRUE(s1 == vector[2]);
+    EXPECT_TRUE(s3.isNull());
+}
+
+TEST(WTF_Vector, ConstructWithFromMoveOnly)
+{
+    auto vector1 = Vector<MoveOnly>::from(MoveOnly(1));
+    auto vector3 = Vector<MoveOnly>::from(MoveOnly(1), MoveOnly(2), MoveOnly(3));
+
+    EXPECT_EQ(1U, vector1.size());
+    EXPECT_EQ(1U, vector1.capacity());
+
+    EXPECT_EQ(3U, vector3.size());
+    EXPECT_EQ(3U, vector3.capacity());
+
+    EXPECT_EQ(1U, vector1[0].value());
+    EXPECT_EQ(1U, vector3[0].value());
+    EXPECT_EQ(2U, vector3[1].value());
+    EXPECT_EQ(3U, vector3[2].value());
+}
+
 TEST(WTF_Vector, InitializeFromOtherInitialCapacity)
 {
     Vector<int, 3> vector = { 1, 3, 2, 4 };
@@ -350,16 +395,16 @@ TEST(WTF_Vector, VectorOfVectorsOfVectorsInlineCapacitySwap)
 
     EXPECT_EQ(1U, x.size());
     EXPECT_EQ(42, x[0]);
-    
+
     Vector<Vector<int, 1>, 1> y;
     y.append(x);
-    
+
     EXPECT_EQ(1U, x.size());
     EXPECT_EQ(42, x[0]);
     EXPECT_EQ(1U, y.size());
     EXPECT_EQ(1U, y[0].size());
     EXPECT_EQ(42, y[0][0]);
-    
+
     a.append(y);
 
     EXPECT_EQ(1U, x.size());
@@ -371,7 +416,7 @@ TEST(WTF_Vector, VectorOfVectorsOfVectorsInlineCapacitySwap)
     EXPECT_EQ(1U, a[0].size());
     EXPECT_EQ(1U, a[0][0].size());
     EXPECT_EQ(42, a[0][0][0]);
-    
+
     a.swap(b);
 
     EXPECT_EQ(0U, a.size());
@@ -384,7 +429,7 @@ TEST(WTF_Vector, VectorOfVectorsOfVectorsInlineCapacitySwap)
     EXPECT_EQ(1U, b[0].size());
     EXPECT_EQ(1U, b[0][0].size());
     EXPECT_EQ(42, b[0][0][0]);
-    
+
     b.swap(c);
 
     EXPECT_EQ(0U, a.size());
@@ -398,7 +443,7 @@ TEST(WTF_Vector, VectorOfVectorsOfVectorsInlineCapacitySwap)
     EXPECT_EQ(1U, c[0].size());
     EXPECT_EQ(1U, c[0][0].size());
     EXPECT_EQ(42, c[0][0][0]);
-    
+
     y[0][0] = 24;
 
     EXPECT_EQ(1U, x.size());
@@ -406,7 +451,7 @@ TEST(WTF_Vector, VectorOfVectorsOfVectorsInlineCapacitySwap)
     EXPECT_EQ(1U, y.size());
     EXPECT_EQ(1U, y[0].size());
     EXPECT_EQ(24, y[0][0]);
-    
+
     a.append(y);
 
     EXPECT_EQ(1U, x.size());