From 502626eecb5bbd658f3dc516d2d46ad1aed55a90 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 19 Jan 2020 12:15:43 +0100 Subject: [PATCH] AK: Teach Vector::insert() to use memmove() for trivial types --- AK/Tests/TestVector.cpp | 18 ++++++++++++++++++ AK/Vector.h | 17 ++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/AK/Tests/TestVector.cpp b/AK/Tests/TestVector.cpp index 68c7582ef8e..74f31667420 100644 --- a/AK/Tests/TestVector.cpp +++ b/AK/Tests/TestVector.cpp @@ -295,4 +295,22 @@ TEST_CASE(nonnullownptrvector) EXPECT_EQ(objects.size(), 2); } +TEST_CASE(insert_trivial) +{ + Vector ints; + ints.append(0); + ints.append(10); + ints.append(20); + ints.append(30); + ints.append(40); + ints.insert(2, 15); + EXPECT_EQ(ints.size(), 6); + EXPECT_EQ(ints[0], 0); + EXPECT_EQ(ints[1], 10); + EXPECT_EQ(ints[2], 15); + EXPECT_EQ(ints[3], 20); + EXPECT_EQ(ints[4], 30); + EXPECT_EQ(ints[5], 40); +} + TEST_MAIN(Vector) diff --git a/AK/Vector.h b/AK/Vector.h index 37f970c0a7c..6cb2cac4e5c 100644 --- a/AK/Vector.h +++ b/AK/Vector.h @@ -94,6 +94,8 @@ class TypedTransfer { public: static void move(T* destination, T* source, size_t count) { + if (!count) + return; if constexpr (Traits::is_trivial()) { memmove(destination, source, count * sizeof(T)); return; @@ -104,6 +106,8 @@ public: static void copy(T* destination, const T* source, size_t count) { + if (!count) + return; if constexpr (Traits::is_trivial()) { memmove(destination, source, count * sizeof(T)); return; @@ -114,6 +118,9 @@ public: static bool compare(const T* a, const T* b, size_t count) { + if (!count) + return true; + if constexpr (Traits::is_trivial()) return !memcmp(a, b, count * sizeof(T)); @@ -335,9 +342,13 @@ public: return append(move(value)); grow_capacity(size() + 1); ++m_size; - for (int i = size() - 1; i > index; --i) { - new (slot(i)) T(move(at(i - 1))); - at(i - 1).~T(); + if constexpr (Traits::is_trivial()) { + TypedTransfer::move(slot(index + 1), slot(index), m_size - index - 1); + } else { + for (int i = size() - 1; i > index; --i) { + new (slot(i)) T(move(at(i - 1))); + at(i - 1).~T(); + } } new (slot(index)) T(move(value)); }