зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1185706 - support Tie() for mozilla::Pair. r=froydnj
This commit is contained in:
Родитель
e592f28662
Коммит
2d9863ad53
87
mfbt/Tuple.h
87
mfbt/Tuple.h
|
@ -10,10 +10,12 @@
|
|||
#define mozilla_Tuple_h
|
||||
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/Pair.h"
|
||||
#include "mozilla/TemplateLib.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <utility>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -246,6 +248,91 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Specialization of Tuple for two elements.
|
||||
* This is created to support construction and assignment from a Pair or std::pair.
|
||||
*/
|
||||
template <typename A, typename B>
|
||||
class Tuple<A, B> : public detail::TupleImpl<0, A, B>
|
||||
{
|
||||
typedef detail::TupleImpl<0, A, B> Impl;
|
||||
|
||||
public:
|
||||
// The constructors and assignment operators here are simple wrappers
|
||||
// around those in TupleImpl.
|
||||
|
||||
Tuple() : Impl() { }
|
||||
explicit Tuple(const A& aA, const B& aB) : Impl(aA, aB) { }
|
||||
template <typename AArg, typename BArg,
|
||||
typename = typename EnableIf<
|
||||
detail::CheckConvertibility<
|
||||
detail::Group<AArg, BArg>,
|
||||
detail::Group<A, B>>::value>::Type>
|
||||
explicit Tuple(AArg&& aA, BArg&& aB)
|
||||
: Impl(Forward<AArg>(aA), Forward<BArg>(aB)) { }
|
||||
Tuple(const Tuple& aOther) : Impl(aOther) { }
|
||||
Tuple(Tuple&& aOther) : Impl(Move(aOther)) { }
|
||||
explicit Tuple(const Pair<A, B>& aOther)
|
||||
: Impl(aOther.first(), aOther.second()) { }
|
||||
explicit Tuple(Pair<A, B>&& aOther) : Impl(Forward<A>(aOther.first()),
|
||||
Forward<B>(aOther.second())) { }
|
||||
explicit Tuple(const std::pair<A, B>& aOther)
|
||||
: Impl(aOther.first, aOther.second) { }
|
||||
explicit Tuple(std::pair<A, B>&& aOther) : Impl(Forward<A>(aOther.first),
|
||||
Forward<B>(aOther.second)) { }
|
||||
|
||||
template <typename AArg, typename BArg>
|
||||
Tuple& operator=(const Tuple<AArg, BArg>& aOther)
|
||||
{
|
||||
static_cast<Impl&>(*this) = aOther;
|
||||
return *this;
|
||||
}
|
||||
template <typename AArg, typename BArg>
|
||||
Tuple& operator=(Tuple<AArg, BArg>&& aOther)
|
||||
{
|
||||
static_cast<Impl&>(*this) = Move(aOther);
|
||||
return *this;
|
||||
}
|
||||
Tuple& operator=(const Tuple& aOther)
|
||||
{
|
||||
static_cast<Impl&>(*this) = aOther;
|
||||
return *this;
|
||||
}
|
||||
Tuple& operator=(Tuple&& aOther)
|
||||
{
|
||||
static_cast<Impl&>(*this) = Move(aOther);
|
||||
return *this;
|
||||
}
|
||||
template <typename AArg, typename BArg>
|
||||
Tuple& operator=(const Pair<AArg, BArg>& aOther)
|
||||
{
|
||||
Impl::Head(*this) = aOther.first();
|
||||
Impl::Tail(*this).Head(*this) = aOther.second();
|
||||
return *this;
|
||||
}
|
||||
template <typename AArg, typename BArg>
|
||||
Tuple& operator=(Pair<AArg, BArg>&& aOther)
|
||||
{
|
||||
Impl::Head(*this) = Forward<AArg>(aOther.first());
|
||||
Impl::Tail(*this).Head(*this) = Forward<BArg>(aOther.second());
|
||||
return *this;
|
||||
}
|
||||
template <typename AArg, typename BArg>
|
||||
Tuple& operator=(const std::pair<AArg, BArg>& aOther)
|
||||
{
|
||||
Impl::Head(*this) = aOther.first;
|
||||
Impl::Tail(*this).Head(*this) = aOther.second;
|
||||
return *this;
|
||||
}
|
||||
template <typename AArg, typename BArg>
|
||||
Tuple& operator=(std::pair<AArg, BArg>&& aOther)
|
||||
{
|
||||
Impl::Head(*this) = Forward<AArg>(aOther.first);
|
||||
Impl::Tail(*this).Head(*this) = Forward<BArg>(aOther.second);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Specialization of Tuple for zero arguments.
|
||||
* This is necessary because if the primary template were instantiated with
|
||||
|
|
|
@ -6,22 +6,26 @@
|
|||
|
||||
#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 { \
|
||||
|
@ -78,6 +82,40 @@ TestConstruction()
|
|||
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()
|
||||
{
|
||||
|
@ -103,6 +141,72 @@ TestAssignment()
|
|||
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()
|
||||
{
|
||||
|
@ -155,6 +259,18 @@ TestTie()
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -162,7 +278,11 @@ int
|
|||
main()
|
||||
{
|
||||
TestConstruction();
|
||||
TestConstructionFromMozPair();
|
||||
TestConstructionFromStdPair();
|
||||
TestAssignment();
|
||||
TestAssignmentFromMozPair();
|
||||
TestAssignmentFromStdPair();
|
||||
TestGet();
|
||||
TestMakeTuple();
|
||||
TestTie();
|
||||
|
|
Загрузка…
Ссылка в новой задаче