summaryrefslogtreecommitdiffstats
path: root/mfbt/tests/TestVariant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mfbt/tests/TestVariant.cpp')
-rw-r--r--mfbt/tests/TestVariant.cpp188
1 files changed, 188 insertions, 0 deletions
diff --git a/mfbt/tests/TestVariant.cpp b/mfbt/tests/TestVariant.cpp
new file mode 100644
index 000000000..d47df70cb
--- /dev/null
+++ b/mfbt/tests/TestVariant.cpp
@@ -0,0 +1,188 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/UniquePtr.h"
+#include "mozilla/Variant.h"
+
+using mozilla::MakeUnique;
+using mozilla::UniquePtr;
+using mozilla::Variant;
+
+struct Destroyer {
+ static int destroyedCount;
+ ~Destroyer() {
+ destroyedCount++;
+ }
+};
+
+int Destroyer::destroyedCount = 0;
+
+static void
+testSimple()
+{
+ printf("testSimple\n");
+ Variant<uint32_t, uint64_t> v(uint64_t(1));
+ MOZ_RELEASE_ASSERT(v.is<uint64_t>());
+ MOZ_RELEASE_ASSERT(!v.is<uint32_t>());
+ MOZ_RELEASE_ASSERT(v.as<uint64_t>() == 1);
+}
+
+static void
+testCopy()
+{
+ printf("testCopy\n");
+ Variant<uint32_t, uint64_t> v1(uint64_t(1));
+ Variant<uint32_t, uint64_t> v2(v1);
+ MOZ_RELEASE_ASSERT(v2.is<uint64_t>());
+ MOZ_RELEASE_ASSERT(!v2.is<uint32_t>());
+ MOZ_RELEASE_ASSERT(v2.as<uint64_t>() == 1);
+
+ Variant<uint32_t, uint64_t> v3(uint32_t(10));
+ v3 = v2;
+ MOZ_RELEASE_ASSERT(v3.is<uint64_t>());
+ MOZ_RELEASE_ASSERT(v3.as<uint64_t>() == 1);
+}
+
+static void
+testMove()
+{
+ printf("testMove\n");
+ Variant<UniquePtr<int>, char> v1(MakeUnique<int>(5));
+ Variant<UniquePtr<int>, char> v2(Move(v1));
+
+ MOZ_RELEASE_ASSERT(v2.is<UniquePtr<int>>());
+ MOZ_RELEASE_ASSERT(*v2.as<UniquePtr<int>>() == 5);
+
+ MOZ_RELEASE_ASSERT(v1.is<UniquePtr<int>>());
+ MOZ_RELEASE_ASSERT(v1.as<UniquePtr<int>>() == nullptr);
+
+ Destroyer::destroyedCount = 0;
+ {
+ Variant<char, UniquePtr<Destroyer>> v3(MakeUnique<Destroyer>());
+ Variant<char, UniquePtr<Destroyer>> v4(Move(v3));
+
+ Variant<char, UniquePtr<Destroyer>> v5('a');
+ v5 = Move(v4);
+
+ auto ptr = v5.extract<UniquePtr<Destroyer>>();
+ MOZ_RELEASE_ASSERT(Destroyer::destroyedCount == 0);
+ }
+ MOZ_RELEASE_ASSERT(Destroyer::destroyedCount == 1);
+}
+
+static void
+testDestructor()
+{
+ printf("testDestructor\n");
+ Destroyer::destroyedCount = 0;
+
+ {
+ Destroyer d;
+
+ {
+ Variant<char, UniquePtr<char[]>, Destroyer> v(d);
+ MOZ_RELEASE_ASSERT(Destroyer::destroyedCount == 0); // None detroyed yet.
+ }
+
+ MOZ_RELEASE_ASSERT(Destroyer::destroyedCount == 1); // v's copy of d is destroyed.
+ }
+
+ MOZ_RELEASE_ASSERT(Destroyer::destroyedCount == 2); // d is destroyed.
+}
+
+static void
+testEquality()
+{
+ printf("testEquality\n");
+ using V = Variant<char, int>;
+
+ V v0('a');
+ V v1('b');
+ V v2('b');
+ V v3(42);
+ V v4(27);
+ V v5(27);
+ V v6(int('b'));
+
+ MOZ_RELEASE_ASSERT(v0 != v1);
+ MOZ_RELEASE_ASSERT(v1 == v2);
+ MOZ_RELEASE_ASSERT(v2 != v3);
+ MOZ_RELEASE_ASSERT(v3 != v4);
+ MOZ_RELEASE_ASSERT(v4 == v5);
+ MOZ_RELEASE_ASSERT(v1 != v6);
+
+ MOZ_RELEASE_ASSERT(v0 == v0);
+ MOZ_RELEASE_ASSERT(v1 == v1);
+ MOZ_RELEASE_ASSERT(v2 == v2);
+ MOZ_RELEASE_ASSERT(v3 == v3);
+ MOZ_RELEASE_ASSERT(v4 == v4);
+ MOZ_RELEASE_ASSERT(v5 == v5);
+ MOZ_RELEASE_ASSERT(v6 == v6);
+}
+
+struct Describer
+{
+ static const char* little;
+ static const char* medium;
+ static const char* big;
+
+ const char* match(const uint8_t&) { return little; }
+ const char* match(const uint32_t&) { return medium; }
+ const char* match(const uint64_t&) { return big; }
+};
+
+const char* Describer::little = "little";
+const char* Describer::medium = "medium";
+const char* Describer::big = "big";
+
+static void
+testMatching()
+{
+ printf("testMatching\n");
+ using V = Variant<uint8_t, uint32_t, uint64_t>;
+
+ Describer desc;
+
+ V v1(uint8_t(1));
+ V v2(uint32_t(2));
+ V v3(uint64_t(3));
+
+ MOZ_RELEASE_ASSERT(v1.match(desc) == Describer::little);
+ MOZ_RELEASE_ASSERT(v2.match(desc) == Describer::medium);
+ MOZ_RELEASE_ASSERT(v3.match(desc) == Describer::big);
+
+ const V& constRef1 = v1;
+ const V& constRef2 = v2;
+ const V& constRef3 = v3;
+
+ MOZ_RELEASE_ASSERT(constRef1.match(desc) == Describer::little);
+ MOZ_RELEASE_ASSERT(constRef2.match(desc) == Describer::medium);
+ MOZ_RELEASE_ASSERT(constRef3.match(desc) == Describer::big);
+}
+
+static void
+testRvalueMatcher()
+{
+ printf("testRvalueMatcher\n");
+ using V = Variant<uint8_t, uint32_t, uint64_t>;
+ V v(uint8_t(1));
+ MOZ_RELEASE_ASSERT(v.match(Describer()) == Describer::little);
+}
+
+int
+main()
+{
+ testSimple();
+ testCopy();
+ testMove();
+ testDestructor();
+ testEquality();
+ testMatching();
+ testRvalueMatcher();
+
+ printf("TestVariant OK!\n");
+ return 0;
+}