Skip to content

Commit 0d2f939

Browse files
committed
moveonly: add mp/type-interface.h
1 parent 5417716 commit 0d2f939

File tree

5 files changed

+115
-101
lines changed

5 files changed

+115
-101
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ set(MP_PUBLIC_HEADERS
4747
include/mp/proxy.h
4848
include/mp/type-char.h
4949
include/mp/type-context.h
50+
include/mp/type-interface.h
5051
include/mp/type-map.h
5152
include/mp/type-number.h
5253
include/mp/type-optional.h

example/types.h

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define EXAMPLE_TYPES_H
77

88
#include <mp/type-context.h>
9+
#include <mp/type-interface.h>
910
#include <mp/type-string.h>
1011

1112
#endif // EXAMPLE_TYPES_H

include/mp/proxy-types.h

-101
Original file line numberDiff line numberDiff line change
@@ -141,51 +141,6 @@ struct ReadDestUpdate
141141
Value& m_value;
142142
};
143143

144-
template <typename Interface, typename Impl>
145-
std::unique_ptr<Impl> MakeProxyClient(InvokeContext& context, typename Interface::Client&& client)
146-
{
147-
return std::make_unique<ProxyClient<Interface>>(
148-
std::move(client), &context.connection, /* destroy_connection= */ false);
149-
}
150-
151-
template <typename Interface, typename Impl>
152-
std::unique_ptr<Impl> CustomMakeProxyClient(InvokeContext& context, typename Interface::Client&& client)
153-
{
154-
return MakeProxyClient<Interface, Impl>(context, kj::mv(client));
155-
}
156-
157-
template <typename LocalType, typename Input, typename ReadDest>
158-
decltype(auto) CustomReadField(TypeList<std::unique_ptr<LocalType>>,
159-
Priority<1>,
160-
InvokeContext& invoke_context,
161-
Input&& input,
162-
ReadDest&& read_dest,
163-
typename Decay<decltype(input.get())>::Calls* enable = nullptr)
164-
{
165-
using Interface = typename Decay<decltype(input.get())>::Calls;
166-
if (input.has()) {
167-
return read_dest.construct(
168-
CustomMakeProxyClient<Interface, LocalType>(invoke_context, std::move(input.get())));
169-
}
170-
return read_dest.construct();
171-
}
172-
173-
template <typename LocalType, typename Input, typename ReadDest>
174-
decltype(auto) CustomReadField(TypeList<std::shared_ptr<LocalType>>,
175-
Priority<1>,
176-
InvokeContext& invoke_context,
177-
Input&& input,
178-
ReadDest&& read_dest,
179-
typename Decay<decltype(input.get())>::Calls* enable = nullptr)
180-
{
181-
using Interface = typename Decay<decltype(input.get())>::Calls;
182-
if (input.has()) {
183-
return read_dest.construct(
184-
CustomMakeProxyClient<Interface, LocalType>(invoke_context, std::move(input.get())));
185-
}
186-
return read_dest.construct();
187-
}
188-
189144
// ProxyCallFn class is needed because c++11 doesn't support auto lambda parameters.
190145
// It's equivalent c++14: [invoke_context](auto&& params) {
191146
// invoke_context->call(std::forward<decltype(params)>(params)...)
@@ -345,62 +300,6 @@ void CustomBuildField(TypeList<std::function<FnR(FnParams...)>>,
345300
std::make_shared<Callback>(std::forward<Value>(value)), invoke_context.connection));
346301
}
347302
}
348-
349-
template <typename Interface, typename Impl>
350-
kj::Own<typename Interface::Server> MakeProxyServer(InvokeContext& context, std::shared_ptr<Impl> impl)
351-
{
352-
return kj::heap<ProxyServer<Interface>>(std::move(impl), context.connection);
353-
}
354-
355-
template <typename Interface, typename Impl>
356-
kj::Own<typename Interface::Server> CustomMakeProxyServer(InvokeContext& context, std::shared_ptr<Impl>&& impl)
357-
{
358-
return MakeProxyServer<Interface, Impl>(context, std::move(impl));
359-
}
360-
361-
template <typename Impl, typename Value, typename Output>
362-
void CustomBuildField(TypeList<std::unique_ptr<Impl>>,
363-
Priority<1>,
364-
InvokeContext& invoke_context,
365-
Value&& value,
366-
Output&& output,
367-
typename Decay<decltype(output.get())>::Calls* enable = nullptr)
368-
{
369-
if (value) {
370-
using Interface = typename decltype(output.get())::Calls;
371-
output.set(CustomMakeProxyServer<Interface, Impl>(invoke_context, std::shared_ptr<Impl>(value.release())));
372-
}
373-
}
374-
375-
template <typename Impl, typename Value, typename Output>
376-
void CustomBuildField(TypeList<std::shared_ptr<Impl>>,
377-
Priority<2>,
378-
InvokeContext& invoke_context,
379-
Value&& value,
380-
Output&& output,
381-
typename Decay<decltype(output.get())>::Calls* enable = nullptr)
382-
{
383-
if (value) {
384-
using Interface = typename decltype(output.get())::Calls;
385-
output.set(CustomMakeProxyServer<Interface, Impl>(invoke_context, std::move(value)));
386-
}
387-
}
388-
389-
template <typename Impl, typename Output>
390-
void CustomBuildField(TypeList<Impl&>,
391-
Priority<1>,
392-
InvokeContext& invoke_context,
393-
Impl& value,
394-
Output&& output,
395-
typename decltype(output.get())::Calls* enable = nullptr)
396-
{
397-
// Disable deleter so proxy server object doesn't attempt to delete the
398-
// wrapped implementation when the proxy client is destroyed or
399-
// disconnected.
400-
using Interface = typename decltype(output.get())::Calls;
401-
output.set(CustomMakeProxyServer<Interface, Impl>(invoke_context, std::shared_ptr<Impl>(&value, [](Impl*){})));
402-
}
403-
404303
// Adapter to let BuildField overloads methods work set & init list elements as
405304
// if they were fields of a struct. If BuildField is changed to use some kind of
406305
// accessor class instead of calling method pointers, then then maybe this could

include/mp/type-interface.h

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Copyright (c) 2025 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef MP_PROXY_TYPE_INTERFACE_H
6+
#define MP_PROXY_TYPE_INTERFACE_H
7+
8+
#include <mp/util.h>
9+
10+
namespace mp {
11+
template <typename Interface, typename Impl>
12+
kj::Own<typename Interface::Server> MakeProxyServer(InvokeContext& context, std::shared_ptr<Impl> impl)
13+
{
14+
return kj::heap<ProxyServer<Interface>>(std::move(impl), context.connection);
15+
}
16+
17+
template <typename Interface, typename Impl>
18+
kj::Own<typename Interface::Server> CustomMakeProxyServer(InvokeContext& context, std::shared_ptr<Impl>&& impl)
19+
{
20+
return MakeProxyServer<Interface, Impl>(context, std::move(impl));
21+
}
22+
23+
template <typename Impl, typename Value, typename Output>
24+
void CustomBuildField(TypeList<std::unique_ptr<Impl>>,
25+
Priority<1>,
26+
InvokeContext& invoke_context,
27+
Value&& value,
28+
Output&& output,
29+
typename Decay<decltype(output.get())>::Calls* enable = nullptr)
30+
{
31+
if (value) {
32+
using Interface = typename decltype(output.get())::Calls;
33+
output.set(CustomMakeProxyServer<Interface, Impl>(invoke_context, std::shared_ptr<Impl>(value.release())));
34+
}
35+
}
36+
37+
template <typename Impl, typename Value, typename Output>
38+
void CustomBuildField(TypeList<std::shared_ptr<Impl>>,
39+
Priority<2>,
40+
InvokeContext& invoke_context,
41+
Value&& value,
42+
Output&& output,
43+
typename Decay<decltype(output.get())>::Calls* enable = nullptr)
44+
{
45+
if (value) {
46+
using Interface = typename decltype(output.get())::Calls;
47+
output.set(CustomMakeProxyServer<Interface, Impl>(invoke_context, std::move(value)));
48+
}
49+
}
50+
51+
template <typename Impl, typename Output>
52+
void CustomBuildField(TypeList<Impl&>,
53+
Priority<1>,
54+
InvokeContext& invoke_context,
55+
Impl& value,
56+
Output&& output,
57+
typename decltype(output.get())::Calls* enable = nullptr)
58+
{
59+
// Disable deleter so proxy server object doesn't attempt to delete the
60+
// wrapped implementation when the proxy client is destroyed or
61+
// disconnected.
62+
using Interface = typename decltype(output.get())::Calls;
63+
output.set(CustomMakeProxyServer<Interface, Impl>(invoke_context, std::shared_ptr<Impl>(&value, [](Impl*){})));
64+
}
65+
66+
template <typename Interface, typename Impl>
67+
std::unique_ptr<Impl> MakeProxyClient(InvokeContext& context, typename Interface::Client&& client)
68+
{
69+
return std::make_unique<ProxyClient<Interface>>(
70+
std::move(client), &context.connection, /* destroy_connection= */ false);
71+
}
72+
73+
template <typename Interface, typename Impl>
74+
std::unique_ptr<Impl> CustomMakeProxyClient(InvokeContext& context, typename Interface::Client&& client)
75+
{
76+
return MakeProxyClient<Interface, Impl>(context, kj::mv(client));
77+
}
78+
79+
template <typename LocalType, typename Input, typename ReadDest>
80+
decltype(auto) CustomReadField(TypeList<std::unique_ptr<LocalType>>,
81+
Priority<1>,
82+
InvokeContext& invoke_context,
83+
Input&& input,
84+
ReadDest&& read_dest,
85+
typename Decay<decltype(input.get())>::Calls* enable = nullptr)
86+
{
87+
using Interface = typename Decay<decltype(input.get())>::Calls;
88+
if (input.has()) {
89+
return read_dest.construct(
90+
CustomMakeProxyClient<Interface, LocalType>(invoke_context, std::move(input.get())));
91+
}
92+
return read_dest.construct();
93+
}
94+
95+
template <typename LocalType, typename Input, typename ReadDest>
96+
decltype(auto) CustomReadField(TypeList<std::shared_ptr<LocalType>>,
97+
Priority<1>,
98+
InvokeContext& invoke_context,
99+
Input&& input,
100+
ReadDest&& read_dest,
101+
typename Decay<decltype(input.get())>::Calls* enable = nullptr)
102+
{
103+
using Interface = typename Decay<decltype(input.get())>::Calls;
104+
if (input.has()) {
105+
return read_dest.construct(
106+
CustomMakeProxyClient<Interface, LocalType>(invoke_context, std::move(input.get())));
107+
}
108+
return read_dest.construct();
109+
}
110+
} // namespace mp
111+
112+
#endif // MP_PROXY_TYPE_INTERFACE_H

test/mp/test/foo-types.h

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <mp/proxy-types.h>
99
#include <mp/type-context.h>
10+
#include <mp/type-interface.h>
1011
#include <mp/type-map.h>
1112
#include <mp/type-number.h>
1213
#include <mp/type-set.h>

0 commit comments

Comments
 (0)