Skip to content
Merged
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
11 changes: 11 additions & 0 deletions include/mp/proxy-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,17 @@ struct ListOutput<::capnp::List<T, kind>>
// clang-format on
};

template <typename LocalType, typename Value, typename Output>
void BuildList(TypeList<LocalType>, InvokeContext& invoke_context, Output&& output, Value&& value)
{
auto list = output.init(value.size());
size_t i = 0;
for (const auto& elem : value) {
BuildField(TypeList<LocalType>(), invoke_context, ListOutput<typename decltype(list)::Builds>(list, i), elem);
++i;
}
}

template <typename LocalType, typename Value, typename Output>
void CustomBuildField(TypeList<LocalType>, Priority<0>, InvokeContext& invoke_context, Value&& value, Output&& output)
{
Expand Down
9 changes: 1 addition & 8 deletions include/mp/type-map.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,7 @@ void CustomBuildField(TypeList<std::map<KeyLocalType, ValueLocalType>>,
Value&& value,
Output&& output)
{
// FIXME dededup with vector handler above
auto list = output.init(value.size());
size_t i = 0;
for (const auto& elem : value) {
BuildField(TypeList<std::pair<KeyLocalType, ValueLocalType>>(), invoke_context,
ListOutput<typename decltype(list)::Builds>(list, i), elem);
++i;
}
BuildList(TypeList<std::pair<KeyLocalType, ValueLocalType>>(), invoke_context, output, value);
}

// Replacement for `m.emplace(piecewise_construct, t1, t2)` to work around a
Expand Down
8 changes: 1 addition & 7 deletions include/mp/type-set.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,7 @@ void CustomBuildField(TypeList<std::set<LocalType>>,
Value&& value,
Output&& output)
{
// FIXME dededup with vector handler above
auto list = output.init(value.size());
size_t i = 0;
for (const auto& elem : value) {
BuildField(TypeList<LocalType>(), invoke_context, ListOutput<typename decltype(list)::Builds>(list, i), elem);
++i;
}
BuildList(TypeList<LocalType>(), invoke_context, output, value);
}

template <typename LocalType, typename Input, typename ReadDest>
Expand Down
43 changes: 43 additions & 0 deletions include/mp/type-unordered-set.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef MP_PROXY_TYPE_UNORDERED_SET_H
#define MP_PROXY_TYPE_UNORDERED_SET_H

#include <mp/proxy-types.h>
#include <mp/util.h>
#include <unordered_set>

namespace mp {
template <typename LocalType, typename Value, typename Output>
void CustomBuildField(TypeList<std::unordered_set<LocalType>>,
Priority<1>,
InvokeContext& invoke_context,
Value&& value,
Output&& output)
{
BuildList(TypeList<LocalType>(), invoke_context, output, value);
}

template <typename LocalType, typename Input, typename ReadDest>
decltype(auto) CustomReadField(TypeList<std::unordered_set<LocalType>>,
Priority<1>,
InvokeContext& invoke_context,
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;
}));
}
});
}
} // namespace mp

#endif // MP_PROXY_TYPE_UNORDERED_SET_H
7 changes: 1 addition & 6 deletions include/mp/type-vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,7 @@ void CustomBuildField(TypeList<std::vector<LocalType>>,
Value&& value,
Output&& output)
{
// FIXME dedup with set handler below
auto list = output.init(value.size());
size_t i = 0;
for (auto it = value.begin(); it != value.end(); ++it, ++i) {
BuildField(TypeList<LocalType>(), invoke_context, ListOutput<typename decltype(list)::Builds>(list, i), *it);
}
BuildList(TypeList<LocalType>(), invoke_context, output, value);
}

inline static bool BuildPrimitive(InvokeContext& invoke_context, std::vector<bool>::const_reference value, TypeList<bool>)
Expand Down
1 change: 1 addition & 0 deletions test/mp/test/foo-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <mp/type-string.h>
#include <mp/type-struct.h>
#include <mp/type-threadmap.h>
#include <mp/type-unordered-set.h>
#include <mp/type-vector.h>
#include <string>
#include <type_traits>
Expand Down
5 changes: 3 additions & 2 deletions test/mp/test/foo.capnp
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ interface FooFn $Proxy.wrap("ProxyCallback<std::function<int()>>") {

struct FooStruct $Proxy.wrap("mp::test::FooStruct") {
name @0 :Text;
setint @1 :List(Int32);
vbool @2 :List(Bool);
setInt @1 :List(Int32) $Proxy.name("set_int");
vBool @2 :List(Bool) $Proxy.name("v_bool");
optionalInt @3 :Int32 $Proxy.name("optional_int");
hasOptionalInt @4 :Bool;
unorderedSetInt @5 :List(Int32) $Proxy.name("unordered_set_int");
}

struct FooCustom $Proxy.wrap("mp::test::FooCustom") {
Expand Down
6 changes: 4 additions & 2 deletions test/mp/test/foo.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <optional>
#include <string>
#include <set>
#include <unordered_set>
#include <vector>

namespace mp {
Expand All @@ -20,9 +21,10 @@ namespace test {
struct FooStruct
{
std::string name;
std::set<int> setint;
std::vector<bool> vbool;
std::set<int> set_int;
std::vector<bool> v_bool;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In commit "test: use camelCase + $Proxy.name for FooStruct fields" (9de4b88)

Not important but vector_bool would seem more consistent with other field names

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. If in the future I touch these code lines again I will apply this suggestion. Thanks for the feedback!

std::optional<int> optional_int;
std::unordered_set<int> unordered_set_int;
};

enum class FooEnum : uint8_t { ONE = 1, TWO = 2, };
Expand Down
27 changes: 17 additions & 10 deletions test/mp/test/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <string_view>
#include <thread>
#include <type_traits>
#include <unordered_set>
#include <utility>
#include <vector>

Expand Down Expand Up @@ -141,21 +142,27 @@ KJ_TEST("Call FooInterface methods")

FooStruct in;
in.name = "name";
in.setint.insert(2);
in.setint.insert(1);
in.vbool.push_back(false);
in.vbool.push_back(true);
in.vbool.push_back(false);
in.set_int.insert(2);
in.set_int.insert(1);
in.unordered_set_int.insert(2);
in.unordered_set_int.insert(1);
in.v_bool.push_back(false);
in.v_bool.push_back(true);
in.v_bool.push_back(false);
in.optional_int = 3;
FooStruct out = foo->pass(in);
KJ_EXPECT(in.name == out.name);
KJ_EXPECT(in.setint.size() == out.setint.size());
for (auto init{in.setint.begin()}, outit{out.setint.begin()}; init != in.setint.end() && outit != out.setint.end(); ++init, ++outit) {
KJ_EXPECT(in.set_int.size() == out.set_int.size());
for (auto init{in.set_int.begin()}, outit{out.set_int.begin()}; init != in.set_int.end() && outit != out.set_int.end(); ++init, ++outit) {
KJ_EXPECT(*init == *outit);
}
KJ_EXPECT(in.vbool.size() == out.vbool.size());
for (size_t i = 0; i < in.vbool.size(); ++i) {
KJ_EXPECT(in.vbool[i] == out.vbool[i]);
KJ_EXPECT(in.unordered_set_int.size() == out.unordered_set_int.size());
for (const auto& elem : in.unordered_set_int) {
KJ_EXPECT(out.unordered_set_int.count(elem) == 1);
}
KJ_EXPECT(in.v_bool.size() == out.v_bool.size());
for (size_t i = 0; i < in.v_bool.size(); ++i) {
KJ_EXPECT(in.v_bool[i] == out.v_bool[i]);
}
KJ_EXPECT(in.optional_int == out.optional_int);

Expand Down
Loading