From 3df497456b9b1d57dec1b03dc1052b8a8258fa30 Mon Sep 17 00:00:00 2001 From: Ryan Ofsky Date: Tue, 19 Sep 2023 11:22:44 -0400 Subject: [PATCH] Remove naming requirement for std::pair/std::tuple When converting C++ std::pair and length 2 std::tuple values to and from capn'proto structs, no longer require the struct to have fields named "key" and "value". Instead always map the first pair/tuple element to the first struct field, and the second element to the second field. This allows anonymous std::pair and std::tuple types used in the C++ interface to have names and custom Read/Build logic when they are serialized as capn'proto messages. For now only length-2 tuples are supported but this could be extended to support converting c++ tuples of arbitrary length to capn'proto structs with the same number of fields. --- include/mp/proxy-types.h | 28 ++++++++++++++-------------- test/mp/test/foo.capnp | 6 +++--- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/include/mp/proxy-types.h b/include/mp/proxy-types.h index 9f4b0345..d3d5dfc5 100644 --- a/include/mp/proxy-types.h +++ b/include/mp/proxy-types.h @@ -410,13 +410,12 @@ decltype(auto) CustomReadField(TypeList> ReadDest&& read_dest) { const auto& pair = input.get(); - using KeyAccessor = typename ProxyStruct::Reads>::KeyAccessor; - using ValueAccessor = typename ProxyStruct::Reads>::ValueAccessor; + using Accessors = typename ProxyStruct::Reads>::Accessors; - ReadField(TypeList(), invoke_context, Make(pair), + ReadField(TypeList(), invoke_context, Make>(pair), ReadDestEmplace(TypeList(), [&](auto&&... key_args) -> auto& { KeyLocalType* key = nullptr; - ReadField(TypeList(), invoke_context, Make(pair), + ReadField(TypeList(), invoke_context, Make>(pair), ReadDestEmplace(TypeList(), [&](auto&&... value_args) -> auto& { auto& ret = read_dest.construct(std::piecewise_construct, std::forward_as_tuple(key_args...), std::forward_as_tuple(value_args...)); @@ -427,6 +426,7 @@ decltype(auto) CustomReadField(TypeList> })); } +// TODO: Should generalize this to work with arbitrary length tuples, not just length 2-tuples. template decltype(auto) CustomReadField(TypeList>, Priority<1>, @@ -437,9 +437,10 @@ decltype(auto) CustomReadField(TypeList return read_dest.update([&](auto& value) { const auto& pair = input.get(); using Struct = ProxyStruct::Reads>; - ReadField(TypeList(), invoke_context, Make(pair), + using Accessors = typename Struct::Accessors; + ReadField(TypeList(), invoke_context, Make>(pair), ReadDestValue(std::get<0>(value))); - ReadField(TypeList(), invoke_context, Make(pair), + ReadField(TypeList(), invoke_context, Make>(pair), ReadDestValue(std::get<1>(value))); }); } @@ -930,12 +931,12 @@ void CustomBuildField(TypeList>, Output&& output) { auto pair = output.init(); - using KeyAccessor = typename ProxyStruct::KeyAccessor; - using ValueAccessor = typename ProxyStruct::ValueAccessor; - BuildField(TypeList(), invoke_context, Make(pair), value.first); - BuildField(TypeList(), invoke_context, Make(pair), value.second); + using Accessors = typename ProxyStruct::Accessors; + BuildField(TypeList(), invoke_context, Make>(pair), value.first); + BuildField(TypeList(), invoke_context, Make>(pair), value.second); } +// TODO: Should generalize this to work with arbitrary length tuples, not just length 2-tuples. template void CustomBuildField(TypeList>, Priority<1>, @@ -944,10 +945,9 @@ void CustomBuildField(TypeList>, Output&& output) { auto pair = output.init(); - using KeyAccessor = typename ProxyStruct::KeyAccessor; - using ValueAccessor = typename ProxyStruct::ValueAccessor; - BuildField(TypeList(), invoke_context, Make(pair), std::get<0>(value)); - BuildField(TypeList(), invoke_context, Make(pair), std::get<1>(value)); + using Accessors = typename ProxyStruct::Accessors; + BuildField(TypeList(), invoke_context, Make>(pair), std::get<0>(value)); + BuildField(TypeList(), invoke_context, Make>(pair), std::get<1>(value)); } template diff --git a/test/mp/test/foo.capnp b/test/mp/test/foo.capnp index a227c1ee..409c4531 100644 --- a/test/mp/test/foo.capnp +++ b/test/mp/test/foo.capnp @@ -44,7 +44,7 @@ struct FooCustom $Proxy.wrap("mp::test::FooCustom") { v2 @1 :Int32; } -struct Pair(Key, Value) { - key @0 :Key; - value @1 :Value; +struct Pair(T1, T2) { + first @0 :T1; + second @1 :T2; }