From 910924f55963f282d575fe42f54eeed6d93a7acd Mon Sep 17 00:00:00 2001 From: asynts Date: Wed, 9 Sep 2020 13:41:58 +0200 Subject: [PATCH] AK: Moved TypedTransfer into it's own header. --- AK/Tests/TestTypedTransfer.cpp | 63 +++++++++++++++++++++++++ AK/TypedTransfer.h | 84 ++++++++++++++++++++++++++++++++++ AK/Vector.h | 44 +----------------- 3 files changed, 148 insertions(+), 43 deletions(-) create mode 100644 AK/Tests/TestTypedTransfer.cpp create mode 100644 AK/TypedTransfer.h diff --git a/AK/Tests/TestTypedTransfer.cpp b/AK/Tests/TestTypedTransfer.cpp new file mode 100644 index 0000000000..3e0358d195 --- /dev/null +++ b/AK/Tests/TestTypedTransfer.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include +#include + +struct NonPrimitiveIntWrapper { + NonPrimitiveIntWrapper(int value) + : m_value(value) + { + } + + int m_value; +}; + +TEST_CASE(overlapping_source_and_destination_1) +{ + const Array expected { 3, 4, 5, 6, 5, 6 }; + + Array actual { 1, 2, 3, 4, 5, 6 }; + AK::TypedTransfer::copy(actual.data(), actual.data() + 2, 4); + + for (size_t i = 0; i < 6; ++i) + EXPECT_EQ(actual[i].m_value, expected[i].m_value); +} + +TEST_CASE(overlapping_source_and_destination_2) +{ + const Array expected { 1, 2, 1, 2, 3, 4 }; + + Array actual { 1, 2, 3, 4, 5, 6 }; + AK::TypedTransfer::copy(actual.data() + 2, actual.data(), 4); + + for (size_t i = 0; i < 6; ++i) + EXPECT_EQ(actual[i].m_value, expected[i].m_value); +} + +TEST_MAIN(TypedTransfer) diff --git a/AK/TypedTransfer.h b/AK/TypedTransfer.h new file mode 100644 index 0000000000..0e0de78e63 --- /dev/null +++ b/AK/TypedTransfer.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +namespace AK { + +template +class TypedTransfer { +public: + static size_t move(T* destination, T* source, size_t count) + { + if constexpr (Traits::is_trivial()) { + __builtin_memmove(destination, source, count * sizeof(T)); + return count; + } + + for (size_t i = 0; i < count; ++i) { + if (destination <= source) + new (&destination[i]) T(AK::move(source[i])); + else + new (&destination[count - i - 1]) T(AK::move(source[count - i - 1])); + } + + return count; + } + + static size_t copy(T* destination, const T* source, size_t count) + { + if constexpr (Traits::is_trivial()) { + __builtin_memmove(destination, source, count * sizeof(T)); + return count; + } + + for (size_t i = 0; i < count; ++i) { + if (destination <= source) + new (&destination[i]) T(source[i]); + else + new (&destination[count - i - 1]) T(source[count - i - 1]); + } + + return count; + } + + static bool compare(const T* a, const T* b, size_t count) + { + if constexpr (Traits::is_trivial()) + return !__builtin_memcmp(a, b, count * sizeof(T)); + + for (size_t i = 0; i < count; ++i) { + if (a[i] != b[i]) + return false; + } + + return true; + } +}; + +} diff --git a/AK/Vector.h b/AK/Vector.h index c65f1753a1..94804368a9 100644 --- a/AK/Vector.h +++ b/AK/Vector.h @@ -33,6 +33,7 @@ #include #include #include +#include #include // NOTE: We can't include during the toolchain bootstrap, @@ -48,49 +49,6 @@ namespace AK { -template -class TypedTransfer { -public: - static void move(T* destination, T* source, size_t count) - { - if (!count) - return; - if constexpr (Traits::is_trivial()) { - __builtin_memmove(destination, source, count * sizeof(T)); - return; - } - for (size_t i = 0; i < count; ++i) - new (&destination[i]) T(AK::move(source[i])); - } - - static void copy(T* destination, const T* source, size_t count) - { - if (!count) - return; - if constexpr (Traits::is_trivial()) { - __builtin_memmove(destination, source, count * sizeof(T)); - return; - } - for (size_t i = 0; i < count; ++i) - new (&destination[i]) T(source[i]); - } - - static bool compare(const T* a, const T* b, size_t count) - { - if (!count) - return true; - - if constexpr (Traits::is_trivial()) - return !__builtin_memcmp(a, b, count * sizeof(T)); - - for (size_t i = 0; i < count; ++i) { - if (a[i] != b[i]) - return false; - } - return true; - } -}; - template class Vector { public: