Bug 1965599 - Allow serialization of Variant with non default constructible types. r=ipc-reviewers,nika

This will be generally useful for IPC serialization, and specifically
for MediaDataEncoder remoting.

Differential Revision: https://phabricator.services.mozilla.com/D248676
This commit is contained in:
Andrew Osmond
2025-05-13 22:37:01 +00:00
committed by aosmond@mozilla.com
parent 02be5aa7d9
commit b73a14ef05

View File

@@ -536,20 +536,23 @@ struct ParamTraits<mozilla::Variant<Ts...>> {
struct VariantReader { struct VariantReader {
using Next = VariantReader<N - 1>; using Next = VariantReader<N - 1>;
static bool Read(MessageReader* reader, Tag tag, paramType* result) {
// Since the VariantReader specializations start at N , we need to // Since the VariantReader specializations start at N , we need to
// subtract one to look at N - 1, the first valid tag. This means our // 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 // comparisons are off by 1. If we get to N = 0 then we have failed to
// find a match to the tag. // find a match to the tag.
if (tag == N - 1) { static constexpr size_t Idx = N - 1;
// Recall, even though the template parameter is N, we are using T = typename mozilla::detail::Nth<Idx, Ts...>::Type;
// actually interested in the N - 1 tag.
// Default construct our field within the result outparameter and static ReadResult<paramType> Read(MessageReader* reader, Tag tag) {
// directly deserialize into the variant. Note that this means that if (tag == Idx) {
// every type in Ts needs to be default constructible auto p = ReadParam<T>(reader);
return ReadParam(reader, &result->template emplace<N - 1>()); if (p) {
return ReadResult<paramType>(
std::in_place, mozilla::VariantIndex<Idx>{}, std::move(*p));
}
return {};
} else { } else {
return Next::Read(reader, tag, result); return Next::Read(reader, tag);
} }
} }
@@ -560,17 +563,17 @@ struct ParamTraits<mozilla::Variant<Ts...>> {
// a matching tag. // a matching tag.
template <typename dummy> template <typename dummy>
struct VariantReader<0, dummy> { struct VariantReader<0, dummy> {
static bool Read(MessageReader* reader, Tag tag, paramType* result) { static ReadResult<paramType> Read(MessageReader* reader, Tag tag) {
return false; return {};
} }
}; };
static bool Read(MessageReader* reader, paramType* result) { static ReadResult<paramType> Read(MessageReader* reader) {
Tag tag; Tag tag;
if (ReadParam(reader, &tag)) { if (ReadParam(reader, &tag)) {
return VariantReader<sizeof...(Ts)>::Read(reader, tag, result); return VariantReader<sizeof...(Ts)>::Read(reader, tag);
} }
return false; return {};
} }
}; };