mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1184385 - Add a Tie() utility function for tuples (the equivalent of std::tie()) to MFBT. r=froydnj
--HG-- extra : rebase_source : 5d6ce0668782e4f3339dbca0d15e2202b566c6b3 extra : source : 9f736422e7903a20560bb83d1832f85a28b89880
This commit is contained in:
parent
20a6d72138
commit
f1d4fcd69b
60
mfbt/Tuple.h
60
mfbt/Tuple.h
@ -142,7 +142,30 @@ struct TupleImpl<Index, HeadT, TailT...>
|
||||
, mHead(Head(aOther)) {}
|
||||
TupleImpl(TupleImpl&& aOther)
|
||||
: Base(Move(Tail(aOther)))
|
||||
, mHead(Move(Head(aOther))) {}
|
||||
, mHead(Forward<HeadT>(Head(aOther))) {}
|
||||
|
||||
// Assign from a tuple whose elements are convertible to the elements
|
||||
// of this tuple.
|
||||
template <typename... OtherElements,
|
||||
typename = typename EnableIf<
|
||||
sizeof...(OtherElements) == sizeof...(TailT) + 1>::Type>
|
||||
TupleImpl& operator=(const TupleImpl<Index, OtherElements...>& aOther)
|
||||
{
|
||||
typedef TupleImpl<Index, OtherElements...> OtherT;
|
||||
Head(*this) = OtherT::Head(aOther);
|
||||
Tail(*this) = OtherT::Tail(aOther);
|
||||
return *this;
|
||||
}
|
||||
template <typename... OtherElements,
|
||||
typename = typename EnableIf<
|
||||
sizeof...(OtherElements) == sizeof...(TailT) + 1>::Type>
|
||||
TupleImpl& operator=(TupleImpl<Index, OtherElements...>&& aOther)
|
||||
{
|
||||
typedef TupleImpl<Index, OtherElements...> OtherT;
|
||||
Head(*this) = Move(OtherT::Head(aOther));
|
||||
Tail(*this) = Move(OtherT::Tail(aOther));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Copy and move assignment operators.
|
||||
TupleImpl& operator=(const TupleImpl& aOther)
|
||||
@ -195,6 +218,22 @@ public:
|
||||
Tuple(const Tuple& aOther) : Impl(aOther) { }
|
||||
Tuple(Tuple&& aOther) : Impl(Move(aOther)) { }
|
||||
|
||||
template <typename... OtherElements,
|
||||
typename = typename EnableIf<
|
||||
sizeof...(OtherElements) == sizeof...(Elements)>::Type>
|
||||
Tuple& operator=(const Tuple<OtherElements...>& aOther)
|
||||
{
|
||||
static_cast<Impl&>(*this) = aOther;
|
||||
return *this;
|
||||
}
|
||||
template <typename... OtherElements,
|
||||
typename = typename EnableIf<
|
||||
sizeof...(OtherElements) == sizeof...(Elements)>::Type>
|
||||
Tuple& operator=(Tuple<OtherElements...>&& aOther)
|
||||
{
|
||||
static_cast<Impl&>(*this) = Move(aOther);
|
||||
return *this;
|
||||
}
|
||||
Tuple& operator=(const Tuple& aOther)
|
||||
{
|
||||
static_cast<Impl&>(*this) = aOther;
|
||||
@ -296,6 +335,25 @@ Tuple<Elements...> MakeTuple(Elements&&... aElements)
|
||||
return Tuple<Elements...>(Forward<Elements>(aElements)...);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience function for constructing a tuple of references to a
|
||||
* sequence of variables. Since assignments to the elements of the tuple
|
||||
* "go through" to the referenced variables, this can be used to "unpack"
|
||||
* a tuple into individual variables.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* int i;
|
||||
* float f;
|
||||
* char c;
|
||||
* Tie(i, f, c) = FunctionThatReturnsATuple();
|
||||
*/
|
||||
template<typename... Elements>
|
||||
Tuple<Elements&...> Tie(Elements&... aVariables)
|
||||
{
|
||||
return Tuple<Elements&...>(aVariables...);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_Tuple_h */
|
||||
|
@ -18,6 +18,7 @@ using mozilla::IsSame;
|
||||
using mozilla::MakeTuple;
|
||||
using mozilla::MakeUnique;
|
||||
using mozilla::Move;
|
||||
using mozilla::Tie;
|
||||
using mozilla::Tuple;
|
||||
using mozilla::UniquePtr;
|
||||
using mozilla::unused;
|
||||
@ -36,7 +37,7 @@ using mozilla::unused;
|
||||
|
||||
struct ConvertibleToInt
|
||||
{
|
||||
operator int() { return 42; }
|
||||
operator int() const { return 42; }
|
||||
};
|
||||
|
||||
static void
|
||||
@ -136,6 +137,27 @@ TestMakeTuple()
|
||||
return true;
|
||||
}
|
||||
|
||||
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));
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
@ -143,5 +165,6 @@ main()
|
||||
TestAssignment();
|
||||
TestGet();
|
||||
TestMakeTuple();
|
||||
TestTie();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user