Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions include/mp/proxy-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,21 @@ void BuildList(TypeList<LocalType>, InvokeContext& invoke_context, Output&& outp
}
}

template <typename LocalType, typename Input, typename ReadDest, typename InitFn, typename EmplaceFn>
void ReadList(TypeList<LocalType>, InvokeContext& invoke_context, Input&& input, ReadDest&& read_dest, InitFn&& init, EmplaceFn&& emplace)
{
read_dest.update([&](auto& value) {
auto data = input.get();
init(value, data.size());
for (auto item : data) {
ReadField(TypeList<LocalType>(), invoke_context, Make<ValueField>(item),
ReadDestEmplace(TypeList<LocalType>(), [&emplace, &value](auto&&... args) -> decltype(auto) {
return emplace(value, std::forward<decltype(args)>(args)...);
}));
}
});
}

template <typename LocalType, typename Value, typename Output>
void CustomBuildField(TypeList<LocalType>, Priority<0>, InvokeContext& invoke_context, Value&& value, Output&& output)
{
Expand Down
18 changes: 6 additions & 12 deletions include/mp/type-map.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,12 @@ decltype(auto) CustomReadField(TypeList<std::map<KeyLocalType, ValueLocalType>>,
Input&& input,
ReadDest&& read_dest)
{
return read_dest.update([&](auto& value) {
auto data = input.get();
value.clear();
for (auto item : data) {
ReadField(TypeList<std::pair<const KeyLocalType, ValueLocalType>>(), invoke_context,
Make<ValueField>(item),
ReadDestEmplace(
TypeList<std::pair<const KeyLocalType, ValueLocalType>>(), [&](auto&&... args) -> auto& {
return *EmplacePiecewiseSafe(value, std::forward<decltype(args)>(args)...).first;
}));
}
});
return ReadList(
TypeList<std::pair<const KeyLocalType, ValueLocalType>>(), invoke_context, input, read_dest,
[&](auto& value, size_t) { value.clear(); },
[&](auto& value, auto&&... args) -> auto& {
return *EmplacePiecewiseSafe(value, std::forward<decltype(args)>(args)...).first;
});
}
} // namespace mp

Expand Down
16 changes: 6 additions & 10 deletions include/mp/type-set.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,12 @@ decltype(auto) CustomReadField(TypeList<std::set<LocalType>>,
Input&& input,
ReadDest&& read_dest)
{
return read_dest.update([&](auto& value) {
auto data = input.get();
value.clear();
for (auto item : data) {
ReadField(TypeList<LocalType>(), invoke_context, Make<ValueField>(item),
ReadDestEmplace(TypeList<const LocalType>(), [&](auto&&... args) -> auto& {
return *value.emplace(std::forward<decltype(args)>(args)...).first;
}));
}
});
return ReadList(
TypeList<LocalType>(), invoke_context, input, read_dest,
[&](auto& value, size_t) { value.clear(); },
[&](auto& value, auto&&... args) -> auto& {
return *value.emplace(std::forward<decltype(args)>(args)...).first;
});
}
} // namespace mp

Expand Down
19 changes: 9 additions & 10 deletions include/mp/type-unordered-set.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,15 @@ decltype(auto) CustomReadField(TypeList<std::unordered_set<LocalType>>,
Input&& input,
ReadDest&& read_dest)
{
return read_dest.update([&](auto& value) {
auto data = input.get();
value.clear();
for (auto item : data) {
ReadField(TypeList<LocalType>(), invoke_context, Make<ValueField>(item),
ReadDestEmplace(TypeList<const LocalType>(), [&](auto&&... args) -> auto& {
return *value.emplace(std::forward<decltype(args)>(args)...).first;
}));
}
});
return ReadList(
TypeList<LocalType>(), invoke_context, input, read_dest,
[&](auto& value, size_t size) {
value.clear();
value.reserve(size);
},
[&](auto& value, auto&&... args) -> auto& {
return *value.emplace(std::forward<decltype(args)>(args)...).first;
});
}
} // namespace mp

Expand Down
44 changes: 24 additions & 20 deletions include/mp/type-vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,35 +31,39 @@ decltype(auto) CustomReadField(TypeList<std::vector<LocalType>>,
Input&& input,
ReadDest&& read_dest)
{
return read_dest.update([&](auto& value) {
auto data = input.get();
value.clear();
value.reserve(data.size());
for (auto item : data) {
ReadField(TypeList<LocalType>(), invoke_context, Make<ValueField>(item),
ReadDestEmplace(TypeList<LocalType>(), [&](auto&&... args) -> auto& {
value.emplace_back(std::forward<decltype(args)>(args)...);
return value.back();
}));
}
});
return ReadList(
TypeList<LocalType>(), invoke_context, input, read_dest,
[&](auto& value, size_t size) {
value.clear();
value.reserve(size);
},
[&](auto& value, auto&&... args) -> auto& {
value.emplace_back(std::forward<decltype(args)>(args)...);
return value.back();
});
}

//! Overload CustomReadField for std::vector<bool>, which needs its own handler
//! because its back() returns a proxy by value (std::vector<bool>::reference)
//! rather than a reference, so it can't use the generic vector in-place emplace path
//! that returns auto&. Not returning a reference is fine here: bool is read via
//! construct(), not update(), so the return value is never used.
template <typename Input, typename ReadDest>
decltype(auto) CustomReadField(TypeList<std::vector<bool>>,
Priority<1>,
InvokeContext& invoke_context,
Input&& input,
ReadDest&& read_dest)
{
return read_dest.update([&](auto& value) {
auto data = input.get();
value.clear();
value.reserve(data.size());
for (auto item : data) {
value.push_back(ReadField(TypeList<bool>(), invoke_context, Make<ValueField>(item), ReadDestTemp<bool>()));
}
});
return ReadList(
TypeList<bool>(), invoke_context, input, read_dest,
[&](auto& value, size_t size) {
value.clear();
value.reserve(size);
},
[&](auto& value, auto&& item) {
value.push_back(item);
});
}
} // namespace mp

Expand Down
Loading