oh I missed this case, thanks for pointing!
I tested your approach and it does compile and passes the tests but I think it is better to not add return value.back(); because bool is read via construct(), so the return value is always unused.
Also I think it is a good opportunity to add a comment to explain why there's this exception for std::vector<bool>.
What do you think?
diff --git a/include/mp/type-vector.h b/include/mp/type-vector.h
index 25e74a6..49ca3c2 100644
--- a/include/mp/type-vector.h
+++ b/include/mp/type-vector.h
@@ -43,6 +43,11 @@ decltype(auto) CustomReadField(TypeList<std::vector<LocalType>>,
});
}
+//! 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>,
@@ -50,14 +55,15 @@ decltype(auto) CustomReadField(TypeList<std::vector<bool>>,
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