summaryrefslogtreecommitdiff
path: root/Tests/AK/TestVariant.cpp
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2021-05-19 11:28:27 -0400
committerAndreas Kling <kling@serenityos.org>2021-05-19 20:41:09 +0200
commit145e246a5e9f229656bc1182bdc6c397ca8efe8a (patch)
tree715147020a48f61c672743ed0840f491b789e71b /Tests/AK/TestVariant.cpp
parent585e7890cdd416b77bd28c2ef853477b42c606ef (diff)
downloadserenity-145e246a5e9f229656bc1182bdc6c397ca8efe8a.zip
AK: Allow AK::Variant::visit to return a value
This changes Variant::visit() to forward the value returned by the selected visitor invocation. By perfectly forwarding the returned value, this allows for the visitor to return by value or reference. Note that all provided visitors must return the same type - the compiler will otherwise fail with the message: "inconsistent deduction for auto return type".
Diffstat (limited to 'Tests/AK/TestVariant.cpp')
-rw-r--r--Tests/AK/TestVariant.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/Tests/AK/TestVariant.cpp b/Tests/AK/TestVariant.cpp
index 587eae2819..28dc92340c 100644
--- a/Tests/AK/TestVariant.cpp
+++ b/Tests/AK/TestVariant.cpp
@@ -6,8 +6,16 @@
#include <LibTest/TestSuite.h>
+#include <AK/RefPtr.h>
#include <AK/Variant.h>
+namespace {
+
+struct Object : public RefCounted<Object> {
+};
+
+}
+
TEST_CASE(basic)
{
Variant<int, String> the_value { 42 };
@@ -117,3 +125,50 @@ TEST_CASE(duplicated_types)
EXPECT(its_just_an_int.has<int>());
EXPECT_EQ(its_just_an_int.get<int>(), 42);
}
+
+TEST_CASE(return_values)
+{
+ using MyVariant = Variant<int, String, float>;
+ {
+ MyVariant the_value { 42.0f };
+
+ float value = the_value.visit(
+ [&](const int&) { return 1.0f; },
+ [&](const String&) { return 2.0f; },
+ [&](const float& f) { return f; });
+ EXPECT_EQ(value, 42.0f);
+ }
+ {
+ MyVariant the_value { 42 };
+
+ int value = the_value.visit(
+ [&](int& i) { return i; },
+ [&](String&) { return 2; },
+ [&](float&) { return 3; });
+ EXPECT_EQ(value, 42);
+ }
+ {
+ const MyVariant the_value { "str" };
+
+ String value = the_value.visit(
+ [&](const int&) { return String { "wrong" }; },
+ [&](const String& s) { return s; },
+ [&](const float&) { return String { "wrong" }; });
+ EXPECT_EQ(value, "str");
+ }
+}
+
+TEST_CASE(return_values_by_reference)
+{
+ auto ref = adopt_ref_if_nonnull(new Object());
+ Variant<int, String, float> the_value { 42.0f };
+
+ auto& value = the_value.visit(
+ [&](const int&) -> RefPtr<Object>& { return ref; },
+ [&](const String&) -> RefPtr<Object>& { return ref; },
+ [&](const float&) -> RefPtr<Object>& { return ref; });
+
+ EXPECT_EQ(ref, value);
+ EXPECT_EQ(ref->ref_count(), 1u);
+ EXPECT_EQ(value->ref_count(), 1u);
+}