Skip to content

Commit 8969d5a

Browse files
committed
moveonly: add mp/type-message.h
1 parent 11b418f commit 8969d5a

File tree

4 files changed

+66
-52
lines changed

4 files changed

+66
-52
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ set(MP_PUBLIC_HEADERS
5050
include/mp/type-function.h
5151
include/mp/type-interface.h
5252
include/mp/type-map.h
53+
include/mp/type-message.h
5354
include/mp/type-number.h
5455
include/mp/type-optional.h
5556
include/mp/type-pair.h

include/mp/proxy-types.h

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -141,19 +141,6 @@ struct ReadDestUpdate
141141
Value& m_value;
142142
};
143143

144-
//! Overload CustomReadField to serialize objects that have CustomReadMessage
145-
//! overloads. Defining a CustomReadMessage overload is simpler than defining a
146-
//! CustomReadField overload because it only requires defining a normal
147-
//! function, not a template function, but less flexible.
148-
template <typename LocalType, typename Reader, typename ReadDest>
149-
decltype(auto) CustomReadField(TypeList<LocalType>, Priority<2>, InvokeContext& invoke_context, Reader&& reader,
150-
ReadDest&& read_dest,
151-
decltype(CustomReadMessage(invoke_context, reader.get(),
152-
std::declval<LocalType&>()))* enable = nullptr)
153-
{
154-
return read_dest.update([&](auto& value) { if (reader.has()) CustomReadMessage(invoke_context, reader.get(), value); });
155-
}
156-
157144
template <typename... LocalTypes, typename... Args>
158145
decltype(auto) ReadField(TypeList<LocalTypes...>, Args&&... args)
159146
{
@@ -189,17 +176,6 @@ bool CustomHasValue(InvokeContext& invoke_context, Values&&... value)
189176
return true;
190177
}
191178

192-
//! Overload CustomBuildField to serialize objects that have CustomBuildMessage
193-
//! overloads. Defining a CustomBuildMessage overload is simpler than defining a
194-
//! CustomBuildField overload because it only requires defining a normal
195-
//! function, not a template function, but less flexible.
196-
template <typename LocalType, typename Value, typename Output>
197-
void CustomBuildField(TypeList<LocalType>, Priority<2>, InvokeContext& invoke_context, Value&& value, Output&& output,
198-
decltype(CustomBuildMessage(invoke_context, value, std::move(output.get())))* enable = nullptr)
199-
{
200-
CustomBuildMessage(invoke_context, value, std::move(output.init()));
201-
}
202-
203179
template <typename... LocalTypes, typename Context, typename... Values, typename Output>
204180
void BuildField(TypeList<LocalTypes...>, Context& context, Output&& output, Values&&... values)
205181
{
@@ -592,34 +568,6 @@ ::capnp::Void MaybeGet(...)
592568
return {};
593569
}
594570

595-
//! Helper for CustomPassField below. Call Accessor::init method if it has one,
596-
//! otherwise do nothing.
597-
template <typename Accessor, typename Message>
598-
decltype(auto) MaybeInit(Message&& message, decltype(Accessor::get(message))* enable = nullptr)
599-
{
600-
return Accessor::init(message);
601-
}
602-
603-
template <typename Accessor>
604-
::capnp::Void MaybeInit(...)
605-
{
606-
return {};
607-
}
608-
609-
//! Overload CustomPassField to serialize objects that have CustomPassMessage
610-
//! overloads. Defining a CustomPassMessage overload is simpler than defining a
611-
//! CustomPassField overload because it only requires defining a normal
612-
//! function, not a template function, but less flexible.
613-
template <typename Accessor, typename... LocalTypes, typename ServerContext, typename Fn, typename... Args>
614-
auto CustomPassField(TypeList<LocalTypes...>, ServerContext& server_context, Fn&& fn, Args&&... args)
615-
-> decltype(CustomPassMessage(server_context, MaybeGet<Accessor>(server_context.call_context.getParams()),
616-
MaybeGet<Accessor>(server_context.call_context.getResults()), nullptr))
617-
{
618-
CustomPassMessage(server_context, MaybeGet<Accessor>(server_context.call_context.getParams()),
619-
MaybeInit<Accessor>(server_context.call_context.getResults()),
620-
[&](LocalTypes... param) { fn.invoke(server_context, std::forward<Args>(args)..., param...); });
621-
}
622-
623571
template <class Accessor>
624572
void CustomPassField();
625573

include/mp/type-message.h

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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_MESSAGE_H
6+
#define MP_PROXY_TYPE_MESSAGE_H
7+
8+
#include <mp/util.h>
9+
10+
namespace mp {
11+
//! Overload CustomBuildField to serialize objects that have CustomBuildMessage
12+
//! overloads. Defining a CustomBuildMessage overload is simpler than defining a
13+
//! CustomBuildField overload because it only requires defining a normal
14+
//! function, not a template function, but less flexible.
15+
template <typename LocalType, typename Value, typename Output>
16+
void CustomBuildField(TypeList<LocalType>, Priority<2>, InvokeContext& invoke_context, Value&& value, Output&& output,
17+
decltype(CustomBuildMessage(invoke_context, value, std::move(output.get())))* enable = nullptr)
18+
{
19+
CustomBuildMessage(invoke_context, value, std::move(output.init()));
20+
}
21+
22+
//! Overload CustomReadField to serialize objects that have CustomReadMessage
23+
//! overloads. Defining a CustomReadMessage overload is simpler than defining a
24+
//! CustomReadField overload because it only requires defining a normal
25+
//! function, not a template function, but less flexible.
26+
template <typename LocalType, typename Reader, typename ReadDest>
27+
decltype(auto) CustomReadField(TypeList<LocalType>, Priority<2>, InvokeContext& invoke_context, Reader&& reader,
28+
ReadDest&& read_dest,
29+
decltype(CustomReadMessage(invoke_context, reader.get(),
30+
std::declval<LocalType&>()))* enable = nullptr)
31+
{
32+
return read_dest.update([&](auto& value) { if (reader.has()) CustomReadMessage(invoke_context, reader.get(), value); });
33+
}
34+
35+
//! Helper for CustomPassField below. Call Accessor::init method if it has one,
36+
//! otherwise do nothing.
37+
template <typename Accessor, typename Message>
38+
decltype(auto) MaybeInit(Message&& message, decltype(Accessor::get(message))* enable = nullptr)
39+
{
40+
return Accessor::init(message);
41+
}
42+
43+
template <typename Accessor>
44+
::capnp::Void MaybeInit(...)
45+
{
46+
return {};
47+
}
48+
49+
//! Overload CustomPassField to serialize objects that have CustomPassMessage
50+
//! overloads. Defining a CustomPassMessage overload is simpler than defining a
51+
//! CustomPassField overload because it only requires defining a normal
52+
//! function, not a template function, but less flexible.
53+
template <typename Accessor, typename... LocalTypes, typename ServerContext, typename Fn, typename... Args>
54+
auto CustomPassField(TypeList<LocalTypes...>, ServerContext& server_context, Fn&& fn, Args&&... args)
55+
-> decltype(CustomPassMessage(server_context, MaybeGet<Accessor>(server_context.call_context.getParams()),
56+
MaybeGet<Accessor>(server_context.call_context.getResults()), nullptr))
57+
{
58+
CustomPassMessage(server_context, MaybeGet<Accessor>(server_context.call_context.getParams()),
59+
MaybeInit<Accessor>(server_context.call_context.getResults()),
60+
[&](LocalTypes... param) { fn.invoke(server_context, std::forward<Args>(args)..., param...); });
61+
}
62+
} // namespace mp
63+
64+
#endif // MP_PROXY_TYPE_MESSAGE_H

test/mp/test/foo-types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <mp/type-context.h>
1010
#include <mp/type-interface.h>
1111
#include <mp/type-map.h>
12+
#include <mp/type-message.h>
1213
#include <mp/type-number.h>
1314
#include <mp/type-set.h>
1415
#include <mp/type-string.h>

0 commit comments

Comments
 (0)