mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Add IPC support for mozilla::Variant (bug 1371846); r=botond
Changes made: * Add IPC::ParamTraits as a friend to mozilla::Variant in Variant.h. This is required so that `tag` can be accessed in the IPC::ParamTraits specialization. * Add a IPC::ParamTraits specialization to IPCMessageUtils.h. MozReview-Commit-ID: B3pGrZE1z0O --HG-- extra : rebase_source : cb73873b87401846f79e124249c7ce00dff2de77
This commit is contained in:
parent
9dbb1b4b10
commit
447dee122f
@ -903,6 +903,82 @@ struct ParamTraits<mozilla::Maybe<T>>
|
||||
}
|
||||
};
|
||||
|
||||
template<class... Ts>
|
||||
struct ParamTraits<mozilla::Variant<Ts...>>
|
||||
{
|
||||
typedef mozilla::Variant<Ts...> paramType;
|
||||
using Tag = typename mozilla::detail::VariantTag<Ts...>::Type;
|
||||
|
||||
struct VariantWriter
|
||||
{
|
||||
Message* msg;
|
||||
|
||||
template<class T>
|
||||
void match(const T& t) {
|
||||
WriteParam(msg, t);
|
||||
}
|
||||
};
|
||||
|
||||
static void Write(Message* msg, const paramType& param)
|
||||
{
|
||||
WriteParam(msg, param.tag);
|
||||
param.match(VariantWriter(msg));
|
||||
}
|
||||
|
||||
// Because VariantReader is a nested struct, we need the dummy template
|
||||
// parameter to avoid making VariantReader<0> an explicit specialization,
|
||||
// which is not allowed for a nested class template
|
||||
template<size_t N, typename dummy = void>
|
||||
struct VariantReader
|
||||
{
|
||||
using Next = VariantReader<N-1>;
|
||||
|
||||
static bool Read(const Message* msg, PickleIterator* iter,
|
||||
Tag tag, paramType* result)
|
||||
{
|
||||
// Since the VariantReader specializations start at N , we need to
|
||||
// subtract one to look at N - 1, the first valid tag. This means our
|
||||
// comparisons are off by 1. If we get to N = 0 then we have failed to
|
||||
// find a match to the tag.
|
||||
if (tag == N - 1) {
|
||||
// Recall, even though the template parameter is N, we are
|
||||
// actually interested in the N - 1 tag.
|
||||
typename mozilla::detail::Nth<N - 1, Ts...>::Type val;
|
||||
if (ReadParam(msg, iter, &val)) {
|
||||
*result = paramType::AsVariant(val);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return Next::Read(msg, iter, tag);
|
||||
}
|
||||
}
|
||||
|
||||
}; // VariantReader<N>
|
||||
|
||||
// Since we are conditioning on tag = N - 1 in the preceding specialization,
|
||||
// if we get to `VariantReader<0, dummy>` we have failed to find
|
||||
// a matching tag.
|
||||
template<typename dummy>
|
||||
struct VariantReader<0, dummy>
|
||||
{
|
||||
static bool Read(const Message* msg, PickleIterator* iter,
|
||||
Tag tag, paramType* result)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
|
||||
{
|
||||
Tag tag;
|
||||
if (ReadParam(msg, iter, &tag)) {
|
||||
return VariantReader<sizeof...(Ts)>::Read(msg, iter, tag, result);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace IPC */
|
||||
|
||||
#endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */
|
||||
|
@ -18,6 +18,10 @@
|
||||
#ifndef mozilla_Variant_h
|
||||
#define mozilla_Variant_h
|
||||
|
||||
namespace IPC {
|
||||
template <typename T> struct ParamTraits;
|
||||
} // namespace IPC
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
template<typename... Ts>
|
||||
@ -484,6 +488,8 @@ template<size_t N> struct VariantIndex { static constexpr size_t index = N; };
|
||||
template<typename... Ts>
|
||||
class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS MOZ_NON_PARAM Variant
|
||||
{
|
||||
friend struct IPC::ParamTraits<mozilla::Variant<Ts...>>;
|
||||
|
||||
using Tag = typename detail::VariantTag<Ts...>::Type;
|
||||
using Impl = detail::VariantImplementation<Tag, 0, Ts...>;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user