From 4d0f8db5f993de9d4fe2337bb31a9cc7a0f4a326 Mon Sep 17 00:00:00 2001 From: ViniciusCestarii Date: Wed, 3 Jun 2026 14:32:15 -0300 Subject: [PATCH 1/2] proxy: add ReadList helper and dedup map/set/vector read handlers --- include/mp/proxy-types.h | 15 +++++++++++++ include/mp/type-map.h | 18 +++++---------- include/mp/type-set.h | 16 +++++--------- include/mp/type-unordered-set.h | 18 +++++++-------- include/mp/type-vector.h | 39 +++++++++------------------------ 5 files changed, 45 insertions(+), 61 deletions(-) diff --git a/include/mp/proxy-types.h b/include/mp/proxy-types.h index 1ccf423f..f1127da5 100644 --- a/include/mp/proxy-types.h +++ b/include/mp/proxy-types.h @@ -291,6 +291,21 @@ void BuildList(TypeList, InvokeContext& invoke_context, Output&& outp } } +template +decltype(auto) ReadList(TypeList, InvokeContext& invoke_context, Input&& input, ReadDest&& read_dest, InitFn&& init, EmplaceFn&& emplace) +{ + return read_dest.update([&](auto& value) { + auto data = input.get(); + init(value, data.size()); + for (auto item : data) { + ReadField(TypeList(), invoke_context, Make(item), + ReadDestEmplace(TypeList(), [&emplace, &value](auto&&... args) -> decltype(auto) { + return emplace(value, std::forward(args)...); + })); + } + }); +} + template void CustomBuildField(TypeList, Priority<0>, InvokeContext& invoke_context, Value&& value, Output&& output) { diff --git a/include/mp/type-map.h b/include/mp/type-map.h index 213ed811..e00a7813 100644 --- a/include/mp/type-map.h +++ b/include/mp/type-map.h @@ -56,18 +56,12 @@ decltype(auto) CustomReadField(TypeList>, Input&& input, ReadDest&& read_dest) { - return read_dest.update([&](auto& value) { - auto data = input.get(); - value.clear(); - for (auto item : data) { - ReadField(TypeList>(), invoke_context, - Make(item), - ReadDestEmplace( - TypeList>(), [&](auto&&... args) -> auto& { - return *EmplacePiecewiseSafe(value, std::forward(args)...).first; - })); - } - }); + return ReadList( + TypeList>(), invoke_context, input, read_dest, + [&](auto& value, size_t) { value.clear(); }, + [&](auto& value, auto&&... args) -> auto& { + return *EmplacePiecewiseSafe(value, std::forward(args)...).first; + }); } } // namespace mp diff --git a/include/mp/type-set.h b/include/mp/type-set.h index f051f738..902dd614 100644 --- a/include/mp/type-set.h +++ b/include/mp/type-set.h @@ -26,16 +26,12 @@ decltype(auto) CustomReadField(TypeList>, Input&& input, ReadDest&& read_dest) { - return read_dest.update([&](auto& value) { - auto data = input.get(); - value.clear(); - for (auto item : data) { - ReadField(TypeList(), invoke_context, Make(item), - ReadDestEmplace(TypeList(), [&](auto&&... args) -> auto& { - return *value.emplace(std::forward(args)...).first; - })); - } - }); + return ReadList( + TypeList(), invoke_context, input, read_dest, + [&](auto& value, size_t) { value.clear(); }, + [&](auto& value, auto&&... args) -> auto& { + return *value.emplace(std::forward(args)...).first; + }); } } // namespace mp diff --git a/include/mp/type-unordered-set.h b/include/mp/type-unordered-set.h index ad4c0ab8..716e4c8a 100644 --- a/include/mp/type-unordered-set.h +++ b/include/mp/type-unordered-set.h @@ -27,16 +27,14 @@ decltype(auto) CustomReadField(TypeList>, Input&& input, ReadDest&& read_dest) { - return read_dest.update([&](auto& value) { - auto data = input.get(); - value.clear(); - for (auto item : data) { - ReadField(TypeList(), invoke_context, Make(item), - ReadDestEmplace(TypeList(), [&](auto&&... args) -> auto& { - return *value.emplace(std::forward(args)...).first; - })); - } - }); + return ReadList( + TypeList(), invoke_context, input, read_dest, + [&](auto& value, size_t) { + value.clear(); + }, + [&](auto& value, auto&&... args) -> auto& { + return *value.emplace(std::forward(args)...).first; + }); } } // namespace mp diff --git a/include/mp/type-vector.h b/include/mp/type-vector.h index 648fda5d..7b5197ff 100644 --- a/include/mp/type-vector.h +++ b/include/mp/type-vector.h @@ -31,35 +31,16 @@ decltype(auto) CustomReadField(TypeList>, 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(), invoke_context, Make(item), - ReadDestEmplace(TypeList(), [&](auto&&... args) -> auto& { - value.emplace_back(std::forward(args)...); - return value.back(); - })); - } - }); -} - -template -decltype(auto) CustomReadField(TypeList>, - 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(), invoke_context, Make(item), ReadDestTemp())); - } - }); + return ReadList( + TypeList(), invoke_context, input, read_dest, + [&](auto& value, size_t size) { + value.clear(); + value.reserve(size); + }, + [&](auto& value, auto&&... args) -> decltype(auto) { + value.emplace_back(std::forward(args)...); + return value.back(); + }); } } // namespace mp From 6450345c985cecd623951af41f0de9414e523e14 Mon Sep 17 00:00:00 2001 From: ViniciusCestarii Date: Wed, 3 Jun 2026 14:33:57 -0300 Subject: [PATCH 2/2] type: reserve first when reading std::unordered_set --- include/mp/type-unordered-set.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/mp/type-unordered-set.h b/include/mp/type-unordered-set.h index 716e4c8a..d1c714b2 100644 --- a/include/mp/type-unordered-set.h +++ b/include/mp/type-unordered-set.h @@ -29,8 +29,9 @@ decltype(auto) CustomReadField(TypeList>, { return ReadList( TypeList(), invoke_context, input, read_dest, - [&](auto& value, size_t) { + [&](auto& value, size_t size) { value.clear(); + value.reserve(size); }, [&](auto& value, auto&&... args) -> auto& { return *value.emplace(std::forward(args)...).first;