summaryrefslogtreecommitdiff
path: root/mfbt/tests/TestTuple.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mfbt/tests/TestTuple.cpp')
-rw-r--r--mfbt/tests/TestTuple.cpp296
1 files changed, 296 insertions, 0 deletions
diff --git a/mfbt/tests/TestTuple.cpp b/mfbt/tests/TestTuple.cpp
new file mode 100644
index 0000000000..a85552fef2
--- /dev/null
+++ b/mfbt/tests/TestTuple.cpp
@@ -0,0 +1,296 @@
+/* -*- 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/Assertions.h"
+#include "mozilla/Move.h"
+#include "mozilla/Pair.h"
+#include "mozilla/Tuple.h"
+#include "mozilla/TypeTraits.h"
+#include "mozilla/UniquePtr.h"
+#include "mozilla/Unused.h"
+
+#include <stddef.h>
+#include <utility>
+
+using mozilla::Get;
+using mozilla::IsSame;
+using mozilla::MakeTuple;
+using mozilla::MakeUnique;
+using mozilla::Move;
+using mozilla::Pair;
+using mozilla::Tie;
+using mozilla::Tuple;
+using mozilla::UniquePtr;
+using mozilla::Unused;
+using std::pair;
+
+#define CHECK(c) \
+ do { \
+ bool cond = !!(c); \
+ MOZ_RELEASE_ASSERT(cond, "Failed assertion: " #c); \
+ } while (false)
+
+// The second argument is the expected type. It's variadic to allow the
+// type to contain commas.
+#define CHECK_TYPE(expression, ...) \
+ static_assert(IsSame<decltype(expression), __VA_ARGS__>::value, \
+ "Type mismatch!")
+
+struct ConvertibleToInt
+{
+ operator int() const { return 42; }
+};
+
+static void
+TestConstruction()
+{
+ // Default construction
+ Tuple<> a;
+ Unused << a;
+ Tuple<int> b;
+ Unused << b;
+
+ // Construction from elements
+ int x = 1, y = 1;
+ Tuple<int, int> c{x, y};
+ Tuple<int&, const int&> d{x, y};
+ x = 42;
+ y = 42;
+ CHECK(Get<0>(c) == 1);
+ CHECK(Get<1>(c) == 1);
+ CHECK(Get<0>(d) == 42);
+ CHECK(Get<1>(d) == 42);
+
+ // Construction from objects convertible to the element types
+ Tuple<int, int> e{1.0, ConvertibleToInt{}};
+
+ // Copy construction
+ Tuple<int> x1;
+ Tuple<int> x2{x1};
+
+ Tuple<int, int> f(c);
+ CHECK(Get<0>(f) == 1);
+ CHECK(Get<0>(f) == 1);
+
+ // Move construction
+ Tuple<UniquePtr<int>> g{MakeUnique<int>(42)};
+ Tuple<UniquePtr<int>> h{Move(g)};
+ CHECK(Get<0>(g) == nullptr);
+ CHECK(*Get<0>(h) == 42);
+}
+
+static void
+TestConstructionFromMozPair()
+{
+ // Construction from elements
+ int x = 1, y = 1;
+ Pair<int, int> a{x, y};
+ Pair<int&, const int&> b{x, y};
+ Tuple<int, int> c(a);
+ Tuple<int&, const int&> d(b);
+ x = 42;
+ y = 42;
+ CHECK(Get<0>(c) == 1);
+ CHECK(Get<1>(c) == 1);
+ CHECK(Get<0>(d) == 42);
+ CHECK(Get<1>(d) == 42);
+}
+
+static void
+TestConstructionFromStdPair()
+{
+ // Construction from elements
+ int x = 1, y = 1;
+ pair<int, int> a{x, y};
+ pair<int&, const int&> b{x, y};
+ Tuple<int, int> c(a);
+ Tuple<int&, const int&> d(b);
+ x = 42;
+ y = 42;
+ CHECK(Get<0>(c) == 1);
+ CHECK(Get<1>(c) == 1);
+ CHECK(Get<0>(d) == 42);
+ CHECK(Get<1>(d) == 42);
+}
+
+static void
+TestAssignment()
+{
+ // Copy assignment
+ Tuple<int> a{0};
+ Tuple<int> b{42};
+ a = b;
+ CHECK(Get<0>(a) == 42);
+
+ // Assignment to reference member
+ int i = 0;
+ int j = 42;
+ Tuple<int&> c{i};
+ Tuple<int&> d{j};
+ c = d;
+ CHECK(i == 42);
+
+ // Move assignment
+ Tuple<UniquePtr<int>> e{MakeUnique<int>(0)};
+ Tuple<UniquePtr<int>> f{MakeUnique<int>(42)};
+ e = Move(f);
+ CHECK(*Get<0>(e) == 42);
+ CHECK(Get<0>(f) == nullptr);
+}
+
+static void
+TestAssignmentFromMozPair()
+{
+ // Copy assignment
+ Tuple<int, int> a{0, 0};
+ Pair<int, int> b{42, 42};
+ a = b;
+ CHECK(Get<0>(a) == 42);
+ CHECK(Get<1>(a) == 42);
+
+ // Assignment to reference member
+ int i = 0;
+ int j = 0;
+ int k = 42;
+ Tuple<int&, int&> c{i, j};
+ Pair<int&, int&> d{k, k};
+ c = d;
+ CHECK(i == 42);
+ CHECK(j == 42);
+
+ // Move assignment
+ Tuple<UniquePtr<int>, UniquePtr<int>> e{MakeUnique<int>(0),
+ MakeUnique<int>(0)};
+ Pair<UniquePtr<int>, UniquePtr<int>> f{MakeUnique<int>(42),
+ MakeUnique<int>(42)};
+ e = Move(f);
+ CHECK(*Get<0>(e) == 42);
+ CHECK(*Get<1>(e) == 42);
+ CHECK(f.first() == nullptr);
+ CHECK(f.second() == nullptr);
+}
+
+static void
+TestAssignmentFromStdPair()
+{
+ // Copy assignment
+ Tuple<int, int> a{0, 0};
+ pair<int, int> b{42, 42};
+ a = b;
+ CHECK(Get<0>(a) == 42);
+ CHECK(Get<1>(a) == 42);
+
+ // Assignment to reference member
+ int i = 0;
+ int j = 0;
+ int k = 42;
+ Tuple<int&, int&> c{i, j};
+ pair<int&, int&> d{k, k};
+ c = d;
+ CHECK(i == 42);
+ CHECK(j == 42);
+
+ // Move assignment.
+ Tuple<UniquePtr<int>, UniquePtr<int>> e{MakeUnique<int>(0), MakeUnique<int>(0)};
+ // XXX: On some platforms std::pair doesn't support move constructor.
+ pair<UniquePtr<int>, UniquePtr<int>> f;
+ f.first = MakeUnique<int>(42);
+ f.second = MakeUnique<int>(42);
+
+ e = Move(f);
+ CHECK(*Get<0>(e) == 42);
+ CHECK(*Get<1>(e) == 42);
+ CHECK(f.first == nullptr);
+ CHECK(f.second == nullptr);
+}
+
+static void
+TestGet()
+{
+ int x = 1;
+ int y = 2;
+ int z = 3;
+ Tuple<int, int&, const int&> tuple(x, y, z);
+
+ // Using Get<>() to read elements
+ CHECK(Get<0>(tuple) == 1);
+ CHECK(Get<1>(tuple) == 2);
+ CHECK(Get<2>(tuple) == 3);
+
+ // Using Get<>() to write to elements
+ Get<0>(tuple) = 41;
+ CHECK(Get<0>(tuple) == 41);
+
+ // Writing through reference elements
+ Get<1>(tuple) = 42;
+ CHECK(Get<1>(tuple) == 42);
+ CHECK(y == 42);
+}
+
+static void
+TestMakeTuple()
+{
+ auto tuple = MakeTuple(42, 0.5f, 'c');
+ CHECK_TYPE(tuple, Tuple<int, float, char>);
+ CHECK(Get<0>(tuple) == 42);
+ CHECK(Get<1>(tuple) == 0.5f);
+ CHECK(Get<2>(tuple) == 'c');
+
+ // Make sure we don't infer the type to be Tuple<int&>.
+ int x = 1;
+ auto tuple2 = MakeTuple(x);
+ CHECK_TYPE(tuple2, Tuple<int>);
+ x = 2;
+ CHECK(Get<0>(tuple2) == 1);
+}
+
+static bool
+TestTie()
+{
+ int i;
+ float f;
+ char c;
+ Tuple<int, float, char> rhs1(42, 0.5f, 'c');
+ Tie(i, f, c) = rhs1;
+ CHECK(i == Get<0>(rhs1));
+ CHECK(f == Get<1>(rhs1));
+ CHECK(c == Get<2>(rhs1));
+ // Test conversions
+ Tuple<ConvertibleToInt, double, unsigned char> rhs2(ConvertibleToInt(),
+ 0.7f, 'd');
+ Tie(i, f, c) = rhs2;
+ CHECK(i == Get<0>(rhs2));
+ CHECK(f == Get<1>(rhs2));
+ CHECK(c == Get<2>(rhs2));
+
+ // Test Pair
+ Pair<int, float> rhs3(-1, 1.2f);
+ Tie(i, f) = rhs3;
+ CHECK(i == rhs3.first());
+ CHECK(f == rhs3.second());
+
+ pair<int, float> rhs4(42, 1.5f);
+ Tie(i, f) = rhs4;
+ CHECK(i == rhs4.first);
+ CHECK(f == rhs4.second);
+
+ return true;
+}
+
+int
+main()
+{
+ TestConstruction();
+ TestConstructionFromMozPair();
+ TestConstructionFromStdPair();
+ TestAssignment();
+ TestAssignmentFromMozPair();
+ TestAssignmentFromStdPair();
+ TestGet();
+ TestMakeTuple();
+ TestTie();
+ return 0;
+}