Commit 96e736c6 authored by andersca@apple.com's avatar andersca@apple.com

Implement Vector::append for move-only types

https://bugs.webkit.org/show_bug.cgi?id=120805

Source/WTF:

Reviewed by Andreas Kling.

* wtf/Vector.h:
(WTF::::expandCapacity):
Remove const from the pointer passed to expandCapacity, it can be non-const if we're moving.

(WTF::::append):
Change append to take U&& and use std::forward when constructing the element and when passing
the element along to appendSlowCase if that's necessary.

(WTF::::appendSlowCase):
Use std::forward.

(WTF::::uncheckedAppend):
Rename val to value.

Tools:

Reviewed by Sam Weinig.

Add a test for Vector<MoveOnly>::append.

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

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@155541 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent b117102e
2013-09-11 Anders Carlsson <andersca@apple.com>
Implement Vector::append for move-only types
https://bugs.webkit.org/show_bug.cgi?id=120805
Reviewed by Andreas Kling.
* wtf/Vector.h:
(WTF::::expandCapacity):
Remove const from the pointer passed to expandCapacity, it can be non-const if we're moving.
(WTF::::append):
Change append to take U&& and use std::forward when constructing the element and when passing
the element along to appendSlowCase if that's necessary.
(WTF::::appendSlowCase):
Use std::forward.
(WTF::::uncheckedAppend):
Rename val to value.
2013-09-11 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
WTF::OwnPtr should behave similarly with the rest of WTF smart pointers
......
......@@ -640,7 +640,7 @@ public:
void clear() { shrinkCapacity(0); }
template<typename U> void append(const U*, size_t);
template<typename U> void append(const U&);
template<typename U> void append(U&&);
template<typename U> void uncheckedAppend(U&& val);
template<typename U, size_t otherCapacity> void appendVector(const Vector<U, otherCapacity>&);
template<typename U> bool tryAppend(const U*, size_t);
......@@ -678,11 +678,11 @@ public:
private:
void expandCapacity(size_t newMinCapacity);
const T* expandCapacity(size_t newMinCapacity, const T*);
T* expandCapacity(size_t newMinCapacity, T*);
bool tryExpandCapacity(size_t newMinCapacity);
const T* tryExpandCapacity(size_t newMinCapacity, const T*);
template<typename U> U* expandCapacity(size_t newMinCapacity, U*);
template<typename U> void appendSlowCase(const U&);
template<typename U> void appendSlowCase(U&&);
using Base::m_size;
using Base::buffer;
......@@ -854,7 +854,7 @@ void Vector<T, inlineCapacity, OverflowHandler>::expandCapacity(size_t newMinCap
}
template<typename T, size_t inlineCapacity, typename OverflowHandler>
const T* Vector<T, inlineCapacity, OverflowHandler>::expandCapacity(size_t newMinCapacity, const T* ptr)
T* Vector<T, inlineCapacity, OverflowHandler>::expandCapacity(size_t newMinCapacity, T* ptr)
{
if (ptr < begin() || ptr >= end()) {
expandCapacity(newMinCapacity);
......@@ -1037,28 +1037,28 @@ bool Vector<T, inlineCapacity, OverflowHandler>::tryAppend(const U* data, size_t
}
template<typename T, size_t inlineCapacity, typename OverflowHandler> template<typename U>
ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler>::append(const U& val)
ALWAYS_INLINE void Vector<T, inlineCapacity, OverflowHandler>::append(U&& value)
{
if (size() != capacity()) {
new (NotNull, end()) T(val);
new (NotNull, end()) T(std::forward<U>(value));
++m_size;
return;
}
appendSlowCase(val);
appendSlowCase(std::forward<U>(value));
}
template<typename T, size_t inlineCapacity, typename OverflowHandler> template<typename U>
void Vector<T, inlineCapacity, OverflowHandler>::appendSlowCase(const U& val)
void Vector<T, inlineCapacity, OverflowHandler>::appendSlowCase(U&& value)
{
ASSERT(size() == capacity());
const U* ptr = &val;
auto ptr = &value;
ptr = expandCapacity(size() + 1, ptr);
if (!begin())
return;
new (NotNull, end()) T(*ptr);
new (NotNull, end()) T(std::forward<U>(*ptr));
++m_size;
}
......@@ -1066,10 +1066,10 @@ void Vector<T, inlineCapacity, OverflowHandler>::appendSlowCase(const U& val)
// vector's capacity is large enough for the append to succeed.
template<typename T, size_t inlineCapacity, typename OverflowHandler> template<typename U>
inline void Vector<T, inlineCapacity, OverflowHandler>::uncheckedAppend(U&& val)
inline void Vector<T, inlineCapacity, OverflowHandler>::uncheckedAppend(U&& value)
{
ASSERT(size() < capacity());
typename std::remove_reference<U>::type* ptr = &val;
auto ptr = &value;
new (NotNull, end()) T(std::forward<U>(*ptr));
++m_size;
}
......
2013-09-11 Anders Carlsson <andersca@apple.com>
Implement Vector::append for move-only types
https://bugs.webkit.org/show_bug.cgi?id=120805
Reviewed by Sam Weinig.
Add a test for Vector<MoveOnly>::append.
* TestWebKitAPI/Tests/WTF/Vector.cpp:
(TestWebKitAPI::TEST):
2013-09-11 Csaba Osztrogonác <ossy@webkit.org>
Unreviewed. Fix the indentation after r105848. Typo fix after r155523.
......
......@@ -155,4 +155,34 @@ TEST(WTF_Vector, MoveOnly_UncheckedAppend)
EXPECT_EQ(vector[i].value(), i);
}
TEST(WTF_Vector, MoveOnly_Append)
{
Vector<MoveOnly> vector;
for (size_t i = 0; i < 100; ++i) {
MoveOnly moveOnly(i);
vector.append(std::move(moveOnly));
EXPECT_EQ(moveOnly.value(), 0U);
}
for (size_t i = 0; i < 100; ++i)
EXPECT_EQ(vector[i].value(), i);
for (size_t i = 0; i < 16; ++i) {
Vector<MoveOnly> vector;
vector.append(i);
for (size_t j = 0; j < i; ++j)
vector.append(j);
vector.append(std::move(vector[0]));
EXPECT_EQ(vector[0].value(), 0U);
for (size_t j = 0; j < i; ++j)
EXPECT_EQ(vector[j + 1].value(), j);
EXPECT_EQ(vector.last().value(), i);
}
}
} // namespace TestWebKitAPI
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment