Bug 1484373: Part 2a - Add Tuple ForEach helper function. r=froydnj

It's currently fairly difficult to perform some operation on each member of a
tuple. This is a particular issue in the context of adding a cycle collection
helper, where we need to perform traverse and unlink operations on each member
of a tuple, and don't have a way to do so without several layers of templates.

This patch adds a ForEach function which will call a function on each element
of the tuple. This would typically be used with a lambda function with a
single `auto&` argument.

--HG--
extra : rebase_source : 577f7c823ab7ee8d1fdedfbd26393c1f1664b965
This commit is contained in:
Kris Maglione 2018-08-19 17:42:59 -07:00
parent 5fc43565d7
commit 61d9aacb68

View file

@ -100,6 +100,9 @@ struct TupleImpl<Index> {
{
return true;
}
template <typename F>
void ForEach(const F& aFunc) {}
};
/*
@ -191,6 +194,27 @@ struct TupleImpl<Index, HeadT, TailT...>
{
return Head(*this) == Head(aOther) && Tail(*this) == Tail(aOther);
}
template <typename F>
void ForEach(const F& aFunc) const &
{
aFunc(Head(*this));
Tail(*this).ForEach(aFunc);
}
template <typename F>
void ForEach(const F& aFunc) &
{
aFunc(Head(*this));
Tail(*this).ForEach(aFunc);
}
template <typename F>
void ForEach(const F& aFunc) &&
{
aFunc(std::move(Head(*this)));
std::move(Tail(*this)).ForEach(aFunc);
}
private:
HeadT mHead; // The element stored at this index in the tuple.
};
@ -420,6 +444,50 @@ auto Get(Tuple<Elements...>&& aTuple)
return std::move(mozilla::Get<Index>(aTuple));
}
/**
* Helpers which call a function for each member of the tuple in turn. This will
* typically be used with a lambda function with an `auto&` argument:
*
* Tuple<Foo*, Bar*, SmartPtr<Baz>> tuple{a, b, c};
*
* ForEach(tuple, [](auto& aElem) {
* aElem = nullptr;
* });
*/
template <typename F>
inline void
ForEach(const Tuple<>& aTuple, const F& aFunc)
{
}
template <typename F>
inline void
ForEach(Tuple<>& aTuple, const F& aFunc)
{
}
template <typename F, typename... Elements>
void
ForEach(const Tuple<Elements...>& aTuple, const F& aFunc)
{
aTuple.ForEach(aTuple, aFunc);
}
template <typename F, typename... Elements>
void
ForEach(Tuple<Elements...>& aTuple, const F& aFunc)
{
aTuple.ForEach(aFunc);
}
template <typename F, typename... Elements>
void
ForEach(Tuple<Elements...>&& aTuple, const F& aFunc)
{
std::forward<Tuple<Elements...>>(aTuple).ForEach(aFunc);
}
/**
* A convenience function for constructing a tuple out of a sequence of
* values without specifying the type of the tuple.