/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* 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 v(uint64_t(1)); MOZ_RELEASE_ASSERT(v.is()); MOZ_RELEASE_ASSERT(!v.is()); MOZ_RELEASE_ASSERT(v.as() == 1); } static void testCopy() { printf("testCopy\n"); Variant v1(uint64_t(1)); Variant v2(v1); MOZ_RELEASE_ASSERT(v2.is()); MOZ_RELEASE_ASSERT(!v2.is()); MOZ_RELEASE_ASSERT(v2.as() == 1); Variant v3(uint32_t(10)); v3 = v2; MOZ_RELEASE_ASSERT(v3.is()); MOZ_RELEASE_ASSERT(v3.as() == 1); } static void testMove() { printf("testMove\n"); Variant, char> v1(MakeUnique(5)); Variant, char> v2(Move(v1)); MOZ_RELEASE_ASSERT(v2.is>()); MOZ_RELEASE_ASSERT(*v2.as>() == 5); MOZ_RELEASE_ASSERT(v1.is>()); MOZ_RELEASE_ASSERT(v1.as>() == nullptr); Destroyer::destroyedCount = 0; { Variant> v3(MakeUnique()); Variant> v4(Move(v3)); Variant> v5('a'); v5 = Move(v4); auto ptr = v5.extract>(); MOZ_RELEASE_ASSERT(Destroyer::destroyedCount == 0); } MOZ_RELEASE_ASSERT(Destroyer::destroyedCount == 1); } static void testDestructor() { printf("testDestructor\n"); Destroyer::destroyedCount = 0; { Destroyer d; { Variant, 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; 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; 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; 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; }