summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AK/StdLibExtras.h2
-rw-r--r--Tests/AK/CMakeLists.txt1
-rw-r--r--Tests/AK/TestStdLibExtras.cpp56
3 files changed, 59 insertions, 0 deletions
diff --git a/AK/StdLibExtras.h b/AK/StdLibExtras.h
index d93ff3834c..39263ece02 100644
--- a/AK/StdLibExtras.h
+++ b/AK/StdLibExtras.h
@@ -99,6 +99,8 @@ constexpr T ceil_div(T a, U b)
template<typename T, typename U>
inline void swap(T& a, U& b)
{
+ if (&a == &b)
+ return;
U tmp = move((U&)a);
a = (T &&) move(b);
b = move(tmp);
diff --git a/Tests/AK/CMakeLists.txt b/Tests/AK/CMakeLists.txt
index 61cb63a14e..ba5f1fb7c0 100644
--- a/Tests/AK/CMakeLists.txt
+++ b/Tests/AK/CMakeLists.txt
@@ -51,6 +51,7 @@ set(AK_TEST_SOURCES
TestSourceLocation.cpp
TestSpan.cpp
TestStack.cpp
+ TestStdLibExtras.cpp
TestString.cpp
TestStringUtils.cpp
TestStringView.cpp
diff --git a/Tests/AK/TestStdLibExtras.cpp b/Tests/AK/TestStdLibExtras.cpp
new file mode 100644
index 0000000000..6a371cfcac
--- /dev/null
+++ b/Tests/AK/TestStdLibExtras.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2021, Tim Flynn <trflynn89@pm.me>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibTest/TestSuite.h>
+
+#include <AK/Optional.h>
+#include <AK/StdLibExtras.h>
+#include <AK/StringView.h>
+#include <AK/Variant.h>
+#include <AK/Vector.h>
+
+TEST_CASE(swap)
+{
+ int i = 4;
+ int j = 6;
+
+ swap(i, j);
+
+ EXPECT_EQ(i, 6);
+ EXPECT_EQ(j, 4);
+}
+
+TEST_CASE(swap_same_value)
+{
+
+ int i = 4;
+ swap(i, i);
+ EXPECT_EQ(i, 4);
+}
+
+TEST_CASE(swap_same_complex_object)
+{
+ struct Type1 {
+ StringView foo;
+ };
+ struct Type2 {
+ Optional<Type1> foo;
+ Vector<Type1> bar;
+ };
+
+ Variant<Type1, Type2> value1 { Type1 { "hello"sv } };
+ Variant<Type1, Type2> value2 { Type2 { {}, { { "goodbye"sv } } } };
+
+ swap(value1, value2);
+
+ EXPECT(value1.has<Type2>());
+ EXPECT(value2.has<Type1>());
+
+ swap(value1, value1);
+
+ EXPECT(value1.has<Type2>());
+ EXPECT(value2.has<Type1>());
+}