diff options
Diffstat (limited to 'mfbt/tests/TestVariant.cpp')
-rw-r--r-- | mfbt/tests/TestVariant.cpp | 188 |
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; +} |