Coverage Report

Created: 2026-05-06 07:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/tmp/bitcoin/src/ipc/libmultiprocess/include/mp/proxy.h
Line
Count
Source
1
// Copyright (c) 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_H
6
#define MP_PROXY_H
7
8
#include <mp/util.h>
9
10
#include <cassert>
11
#include <functional>
12
#include <list>
13
#include <memory>
14
#include <stddef.h>
15
#include <tuple>
16
#include <type_traits>
17
#include <utility>
18
#include <variant> // IWYU pragma: keep
19
20
namespace mp {
21
class Connection;
22
class EventLoop;
23
//! Mapping from capnp interface type to proxy client implementation (specializations are generated by
24
//! proxy-codegen.cpp).
25
template <typename Interface> struct ProxyClient; // IWYU pragma: export
26
//! Mapping from capnp interface type to proxy server implementation (specializations are generated by
27
//! proxy-codegen.cpp).
28
template <typename Interface> struct ProxyServer; // IWYU pragma: export
29
//! Mapping from capnp method params type to method traits (specializations are generated by proxy-codegen.cpp).
30
template <typename Params> struct ProxyMethod; // IWYU pragma: export
31
//! Mapping from capnp struct type to struct traits (specializations are generated by proxy-codegen.cpp).
32
template <typename Struct> struct ProxyStruct; // IWYU pragma: export
33
//! Mapping from local c++ type to capnp type and traits (specializations are generated by proxy-codegen.cpp).
34
template <typename Type> struct ProxyType; // IWYU pragma: export
35
36
using CleanupList = std::list<std::function<void()>>;
37
using CleanupIt = typename CleanupList::iterator;
38
39
88
inline void CleanupRun(CleanupList& fns) {
40
155
    while (!fns.empty()) {
41
67
        auto fn = std::move(fns.front());
42
67
        fns.pop_front();
43
67
        fn();
44
67
    }
45
88
}
46
47
//! Event loop smart pointer automatically managing m_num_clients.
48
//! If a lock pointer argument is passed, the specified lock will be used,
49
//! otherwise EventLoop::m_mutex will be locked when needed.
50
class EventLoopRef
51
{
52
public:
53
    explicit EventLoopRef(EventLoop& loop, Lock* lock = nullptr);
54
0
    EventLoopRef(EventLoopRef&& other) noexcept : m_loop(other.m_loop) { other.m_loop = nullptr; }
55
    EventLoopRef(const EventLoopRef&) = delete;
56
    EventLoopRef& operator=(const EventLoopRef&) = delete;
57
    EventLoopRef& operator=(EventLoopRef&&) = delete;
58
332
    ~EventLoopRef() { reset(); }
59
751
    EventLoop& operator*() const { assert(m_loop); return *m_loop; }
60
851
    EventLoop* operator->() const { assert(m_loop); return m_loop; }
61
    void reset(bool relock=false);
62
63
    EventLoop* m_loop{nullptr};
64
    Lock* m_lock{nullptr};
65
};
66
67
//! Context data associated with proxy client and server classes.
68
struct ProxyContext
69
{
70
    Connection* connection;
71
    EventLoopRef loop;
72
    CleanupList cleanup_fns;
73
74
    ProxyContext(Connection* connection);
75
};
76
77
//! Base class for generated ProxyClient classes that implement a C++ interface
78
//! and forward calls to a capnp interface.
79
template <typename Interface_, typename Impl_>
80
class ProxyClientBase : public Impl_
81
{
82
public:
83
    using Interface = Interface_;
84
    using Impl = Impl_;
85
    using Sub = ProxyClient<Interface>;
86
    using Super = ProxyClientBase<Interface, Impl>;
87
88
    //! Construct libmultiprocess client object wrapping Cap'n Proto client
89
    //! object with a reference to the associated mp::Connection object.
90
    //!
91
    //! The destroy_connection option determines whether destroying this client
92
    //! object closes the connection. It is set to true for the
93
    //! ProxyClient<InitInterface> object returned by ConnectStream, to let IPC
94
    //! clients close the connection by freeing the object. It is false for
95
    //! other client objects so they can be destroyed without affecting the
96
    //! connection.
97
    ProxyClientBase(typename Interface::Client client, Connection* connection, bool destroy_connection);
98
    ~ProxyClientBase() noexcept;
99
100
    // construct/destroy methods called during client construction/destruction
101
    // that can optionally be defined in capnp interfaces to invoke code on the
102
    // server when proxy client objects are created and destroyed.
103
    //
104
    // The construct() method is not generally very useful, but can be used to
105
    // run custom code on the server automatically when a ProxyClient client is
106
    // constructed. The only current use is adding a construct method to Init
107
    // interfaces that is called automatically on construction, so client and
108
    // server exchange ThreadMap references and set Connection::m_thread_map
109
    // values as soon as the Init client is created.
110
    //
111
    //     construct @0 (threadMap: Proxy.ThreadMap) -> (threadMap: Proxy.ThreadMap);
112
    //
113
    // But construct() is not necessary for this, thread maps could be passed
114
    // through a normal method that is just called explicitly rather than
115
    // implicitly.
116
    //
117
    // The destroy() method is more generally useful than construct(), because
118
    // it ensures that the server object will be destroyed synchronously before
119
    // the client destructor returns, instead of asynchronously at some
120
    // unpredictable time after the client object is already destroyed and
121
    // client code has moved on. If the destroy method accepts a Context
122
    // parameter like:
123
    //
124
    //     destroy @0 (context: Proxy.Context) -> ();
125
    //
126
    // then it will also ensure that the destructor runs on the same thread the
127
    // client used to make other RPC calls, instead of running on the server
128
    // EventLoop thread and possibly blocking it.
129
57
    static void construct(Super&) {}
mp::ProxyClientBase<gen::FooInterface, FooImplementation>::construct(mp::ProxyClientBase<gen::FooInterface, FooImplementation>&)
Line
Count
Source
129
1
    static void construct(Super&) {}
mp::ProxyClientBase<ipc::capnp::messages::Echo, interfaces::Echo>::construct(mp::ProxyClientBase<ipc::capnp::messages::Echo, interfaces::Echo>&)
Line
Count
Source
129
6
    static void construct(Super&) {}
Unexecuted instantiation: mp::ProxyClientBase<ipc::capnp::messages::Mining, interfaces::Mining>::construct(mp::ProxyClientBase<ipc::capnp::messages::Mining, interfaces::Mining>&)
mp::ProxyClientBase<ipc::capnp::messages::Rpc, interfaces::Rpc>::construct(mp::ProxyClientBase<ipc::capnp::messages::Rpc, interfaces::Rpc>&)
Line
Count
Source
129
4
    static void construct(Super&) {}
Unexecuted instantiation: mp::ProxyClientBase<ipc::capnp::messages::BlockTemplate, interfaces::BlockTemplate>::construct(mp::ProxyClientBase<ipc::capnp::messages::BlockTemplate, interfaces::BlockTemplate>&)
mp::ProxyClientBase<mp::Thread, capnp::Void>::construct(mp::ProxyClientBase<mp::Thread, capnp::Void>&)
Line
Count
Source
129
46
    static void construct(Super&) {}
130
61
    static void destroy(Super&) {}
mp::ProxyClientBase<gen::FooInterface, FooImplementation>::destroy(mp::ProxyClientBase<gen::FooInterface, FooImplementation>&)
Line
Count
Source
130
1
    static void destroy(Super&) {}
mp::ProxyClientBase<ipc::capnp::messages::Init, interfaces::Init>::destroy(mp::ProxyClientBase<ipc::capnp::messages::Init, interfaces::Init>&)
Line
Count
Source
130
10
    static void destroy(Super&) {}
Unexecuted instantiation: mp::ProxyClientBase<ipc::capnp::messages::Mining, interfaces::Mining>::destroy(mp::ProxyClientBase<ipc::capnp::messages::Mining, interfaces::Mining>&)
mp::ProxyClientBase<ipc::capnp::messages::Rpc, interfaces::Rpc>::destroy(mp::ProxyClientBase<ipc::capnp::messages::Rpc, interfaces::Rpc>&)
Line
Count
Source
130
4
    static void destroy(Super&) {}
mp::ProxyClientBase<mp::Thread, capnp::Void>::destroy(mp::ProxyClientBase<mp::Thread, capnp::Void>&)
Line
Count
Source
130
46
    static void destroy(Super&) {}
131
132
    typename Interface::Client m_client;
133
    ProxyContext m_context;
134
};
135
136
//! Customizable (through template specialization) base class used in generated ProxyClient implementations from
137
//! proxy-codegen.cpp.
138
template <typename Interface, typename Impl>
139
class ProxyClientCustom : public ProxyClientBase<Interface, Impl>
140
{
141
    using ProxyClientBase<Interface, Impl>::ProxyClientBase;
142
};
143
144
//! Base class for generated ProxyServer classes that implement capnp server
145
//! methods and forward calls to a wrapped c++ implementation class.
146
template <typename Interface_, typename Impl_>
147
struct ProxyServerBase : public virtual Interface_::Server
148
{
149
public:
150
    using Interface = Interface_;
151
    using Impl = Impl_;
152
153
    ProxyServerBase(std::shared_ptr<Impl> impl, Connection& connection);
154
    virtual ~ProxyServerBase();
155
    void invokeDestroy();
156
    using Interface_::Server::thisCap;
157
158
    /**
159
     * Implementation pointer that may or may not be owned and deleted when this
160
     * capnp server goes out of scope. It is owned for servers created to wrap
161
     * unique_ptr<Impl> method arguments, but unowned for servers created to
162
     * wrap Impl& method arguments.
163
     *
164
     * In the case of Impl& arguments, custom code is required on other side of
165
     * the connection to delete the capnp client & server objects since native
166
     * code on that side of the connection will just be taking a plain reference
167
     * rather than a pointer, so won't be able to do its own cleanup. Right now
168
     * this is implemented with addCloseHook callbacks to delete clients at
169
     * appropriate times depending on semantics of the particular method being
170
     * wrapped. */
171
    std::shared_ptr<Impl> m_impl;
172
    ProxyContext m_context;
173
};
174
175
//! Customizable (through template specialization) base class which ProxyServer
176
//! classes produced by generated code will inherit from. The default
177
//! specialization of this class just inherits from ProxyServerBase, but custom
178
//! specializations can be defined to control ProxyServer behavior.
179
//!
180
//! Specifically, it can be useful to specialize this class to add additional
181
//! state to ProxyServer classes, for example to cache state between IPC calls.
182
//! If this is done, however, care should be taken to ensure that the extra
183
//! state can be destroyed without blocking, because ProxyServer destructors are
184
//! called from the EventLoop thread, and if they block, it could deadlock the
185
//! program. One way to do avoid blocking is to clean up the state by pushing
186
//! cleanup callbacks to the m_context.cleanup_fns list, which run after the server
187
//! m_impl object is destroyed on the same thread destroying it (which will
188
//! either be an IPC worker thread if the ProxyServer is being explicitly
189
//! destroyed by a client calling a destroy() method with a Context argument and
190
//! Context.thread value set, or the temporary EventLoop::m_async_thread used to
191
//! run destructors without blocking the event loop when no-longer used server
192
//! objects are garbage collected by Cap'n Proto.) Alternately, if cleanup needs
193
//! to run before m_impl is destroyed, the specialization can override
194
//! invokeDestroy and destructor methods to do that.
195
template <typename Interface, typename Impl>
196
struct ProxyServerCustom : public ProxyServerBase<Interface, Impl>
197
{
198
    using ProxyServerBase<Interface, Impl>::ProxyServerBase;
199
};
200
201
//! Function traits class used to get method parameter and result types, used in
202
//! generated ProxyClient and ProxyServer classes produced by gen.cpp to get C++
203
//! method type information. The generated code accesses these traits via
204
//! intermediate ProxyClientMethodTraits and ProxyServerMethodTraits classes,
205
//! which it is possible to specialize to change the way method arguments and
206
//! return values are handled.
207
//!
208
//! Fields of the trait class are:
209
//!
210
//! Params   - TypeList of C++ ClassName::methodName parameter types
211
//! Result   - Return type of ClassName::method
212
//! Param<N> - helper to access individual parameter types by index number.
213
//! Fwd<N>   - helper to forward arguments by index number.
214
//! Fields   - helper alias that appends Result type to the Params typelist if
215
//!            it not void.
216
template <class Fn>
217
struct FunctionTraits;
218
219
//! Specialization of above extracting result and params types assuming the
220
//! template argument is a pointer-to-method type,
221
//! decltype(&ClassName::methodName)
222
template <class _Class, class _Result, class... _Params>
223
struct FunctionTraits<_Result (_Class::*const)(_Params...)>
224
{
225
    using Params = TypeList<_Params...>;
226
    using Result = _Result;
227
    template <size_t N>
228
    using Param = typename std::tuple_element<N, std::tuple<_Params...>>::type;
229
    using Fields =
230
        std::conditional_t<std::is_same_v<void, Result>, Params, TypeList<_Params..., _Result>>;
231
232
    //! Enable perfect forwarding for clientInvoke calls. If parameter is a
233
    //! value type or rvalue reference type, pass it as an rvalue-reference to
234
    //! MakeClientParam and BuildField calls so it can be moved from, and if it
235
    //! is an lvalue reference, pass it an lvalue reference so it won't be moved
236
    //! from. This method does the same thing as std::forward except it takes a
237
    //! parameter number instead of a type as a template argument, so generated
238
    //! code calling this can be less repetitive and verbose.
239
    template <size_t N>
240
25
    static decltype(auto) Fwd(Param<N>& arg) { return static_cast<Param<N>&&>(arg); }
decltype(auto) mp::FunctionTraits<int (FooImplementation::* const)(int, int)>::Fwd<0ul>(std::tuple_element<0ul, std::tuple<int, int>>::type&)
Line
Count
Source
240
1
    static decltype(auto) Fwd(Param<N>& arg) { return static_cast<Param<N>&&>(arg); }
decltype(auto) mp::FunctionTraits<int (FooImplementation::* const)(int, int)>::Fwd<1ul>(std::tuple_element<1ul, std::tuple<int, int>>::type&)
Line
Count
Source
240
1
    static decltype(auto) Fwd(Param<N>& arg) { return static_cast<Param<N>&&>(arg); }
decltype(auto) mp::FunctionTraits<COutPoint (FooImplementation::* const)(COutPoint)>::Fwd<0ul>(std::tuple_element<0ul, std::tuple<COutPoint>>::type&)
Line
Count
Source
240
1
    static decltype(auto) Fwd(Param<N>& arg) { return static_cast<Param<N>&&>(arg); }
decltype(auto) mp::FunctionTraits<UniValue (FooImplementation::* const)(UniValue)>::Fwd<0ul>(std::tuple_element<0ul, std::tuple<UniValue>>::type&)
Line
Count
Source
240
1
    static decltype(auto) Fwd(Param<N>& arg) { return static_cast<Param<N>&&>(arg); }
decltype(auto) mp::FunctionTraits<std::shared_ptr<CTransaction const> (FooImplementation::* const)(std::shared_ptr<CTransaction const>)>::Fwd<0ul>(std::tuple_element<0ul, std::tuple<std::shared_ptr<CTransaction const>>>::type&)
Line
Count
Source
240
1
    static decltype(auto) Fwd(Param<N>& arg) { return static_cast<Param<N>&&>(arg); }
decltype(auto) mp::FunctionTraits<std::vector<char, std::allocator<char>> (FooImplementation::* const)(std::vector<char, std::allocator<char>>)>::Fwd<0ul>(std::tuple_element<0ul, std::tuple<std::vector<char, std::allocator<char>>>>::type&)
Line
Count
Source
240
1
    static decltype(auto) Fwd(Param<N>& arg) { return static_cast<Param<N>&&>(arg); }
decltype(auto) mp::FunctionTraits<CScript (FooImplementation::* const)(CScript)>::Fwd<0ul>(std::tuple_element<0ul, std::tuple<CScript>>::type&)
Line
Count
Source
240
1
    static decltype(auto) Fwd(Param<N>& arg) { return static_cast<Param<N>&&>(arg); }
decltype(auto) mp::FunctionTraits<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> (interfaces::Echo::* const)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)>::Fwd<0ul>(std::tuple_element<0ul, std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&>>::type&)
Line
Count
Source
240
6
    static decltype(auto) Fwd(Param<N>& arg) { return static_cast<Param<N>&&>(arg); }
Unexecuted instantiation: decltype(auto) mp::FunctionTraits<std::optional<interfaces::BlockRef> (interfaces::Mining::* const)(uint256, std::chrono::duration<double, std::ratio<1l, 1000l>>)>::Fwd<0ul>(std::tuple_element<0ul, std::tuple<uint256, std::chrono::duration<double, std::ratio<1l, 1000l>>>>::type&)
Unexecuted instantiation: decltype(auto) mp::FunctionTraits<std::optional<interfaces::BlockRef> (interfaces::Mining::* const)(uint256, std::chrono::duration<double, std::ratio<1l, 1000l>>)>::Fwd<1ul>(std::tuple_element<1ul, std::tuple<uint256, std::chrono::duration<double, std::ratio<1l, 1000l>>>>::type&)
Unexecuted instantiation: decltype(auto) mp::FunctionTraits<std::unique_ptr<interfaces::BlockTemplate, std::default_delete<interfaces::BlockTemplate>> (interfaces::Mining::* const)(node::BlockCreateOptions const&, bool)>::Fwd<0ul>(std::tuple_element<0ul, std::tuple<node::BlockCreateOptions const&, bool>>::type&)
Unexecuted instantiation: decltype(auto) mp::FunctionTraits<std::unique_ptr<interfaces::BlockTemplate, std::default_delete<interfaces::BlockTemplate>> (interfaces::Mining::* const)(node::BlockCreateOptions const&, bool)>::Fwd<1ul>(std::tuple_element<1ul, std::tuple<node::BlockCreateOptions const&, bool>>::type&)
Unexecuted instantiation: decltype(auto) mp::FunctionTraits<bool (interfaces::Mining::* const)(CBlock const&, node::BlockCheckOptions const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&)>::Fwd<0ul>(std::tuple_element<0ul, std::tuple<CBlock const&, node::BlockCheckOptions const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&>>::type&)
Unexecuted instantiation: decltype(auto) mp::FunctionTraits<bool (interfaces::Mining::* const)(CBlock const&, node::BlockCheckOptions const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&)>::Fwd<1ul>(std::tuple_element<1ul, std::tuple<CBlock const&, node::BlockCheckOptions const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&>>::type&)
Unexecuted instantiation: decltype(auto) mp::FunctionTraits<bool (interfaces::Mining::* const)(CBlock const&, node::BlockCheckOptions const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&)>::Fwd<2ul>(std::tuple_element<2ul, std::tuple<CBlock const&, node::BlockCheckOptions const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&>>::type&)
Unexecuted instantiation: decltype(auto) mp::FunctionTraits<bool (interfaces::Mining::* const)(CBlock const&, node::BlockCheckOptions const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&)>::Fwd<3ul>(std::tuple_element<3ul, std::tuple<CBlock const&, node::BlockCheckOptions const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&>>::type&)
Unexecuted instantiation: decltype(auto) mp::FunctionTraits<bool (interfaces::BlockTemplate::* const)(unsigned int, unsigned int, unsigned int, std::shared_ptr<CTransaction const>)>::Fwd<0ul>(std::tuple_element<0ul, std::tuple<unsigned int, unsigned int, unsigned int, std::shared_ptr<CTransaction const>>>::type&)
Unexecuted instantiation: decltype(auto) mp::FunctionTraits<bool (interfaces::BlockTemplate::* const)(unsigned int, unsigned int, unsigned int, std::shared_ptr<CTransaction const>)>::Fwd<1ul>(std::tuple_element<1ul, std::tuple<unsigned int, unsigned int, unsigned int, std::shared_ptr<CTransaction const>>>::type&)
Unexecuted instantiation: decltype(auto) mp::FunctionTraits<bool (interfaces::BlockTemplate::* const)(unsigned int, unsigned int, unsigned int, std::shared_ptr<CTransaction const>)>::Fwd<2ul>(std::tuple_element<2ul, std::tuple<unsigned int, unsigned int, unsigned int, std::shared_ptr<CTransaction const>>>::type&)
Unexecuted instantiation: decltype(auto) mp::FunctionTraits<bool (interfaces::BlockTemplate::* const)(unsigned int, unsigned int, unsigned int, std::shared_ptr<CTransaction const>)>::Fwd<3ul>(std::tuple_element<3ul, std::tuple<unsigned int, unsigned int, unsigned int, std::shared_ptr<CTransaction const>>>::type&)
Unexecuted instantiation: decltype(auto) mp::FunctionTraits<std::unique_ptr<interfaces::BlockTemplate, std::default_delete<interfaces::BlockTemplate>> (interfaces::BlockTemplate::* const)(node::BlockWaitOptions)>::Fwd<0ul>(std::tuple_element<0ul, std::tuple<node::BlockWaitOptions>>::type&)
decltype(auto) mp::FunctionTraits<UniValue (interfaces::Rpc::* const)(UniValue, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)>::Fwd<0ul>(std::tuple_element<0ul, std::tuple<UniValue, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>::type&)
Line
Count
Source
240
4
    static decltype(auto) Fwd(Param<N>& arg) { return static_cast<Param<N>&&>(arg); }
decltype(auto) mp::FunctionTraits<UniValue (interfaces::Rpc::* const)(UniValue, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)>::Fwd<1ul>(std::tuple_element<1ul, std::tuple<UniValue, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>::type&)
Line
Count
Source
240
4
    static decltype(auto) Fwd(Param<N>& arg) { return static_cast<Param<N>&&>(arg); }
decltype(auto) mp::FunctionTraits<UniValue (interfaces::Rpc::* const)(UniValue, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)>::Fwd<2ul>(std::tuple_element<2ul, std::tuple<UniValue, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>::type&)
Line
Count
Source
240
4
    static decltype(auto) Fwd(Param<N>& arg) { return static_cast<Param<N>&&>(arg); }
241
};
242
243
//! Traits class for a proxy method, providing the same
244
//! Params/Result/Param/Fields described in the FunctionTraits class above, plus
245
//! an additional invoke() method that calls the C++ method which is being
246
//! proxied, forwarding any arguments.
247
//!
248
//! The template argument should be the InterfaceName::MethodNameParams class
249
//! (generated by Cap'n Proto) associated with the method.
250
//!
251
//! Note: The class definition here is just the fallback definition used when
252
//! the other specialization below doesn't match. The fallback is only used for
253
//! capnp methods which do not have corresponding C++ methods, which in practice
254
//! is just the two special construct() and destroy() methods described in \ref
255
//! ProxyClientBase. These methods don't have any C++ parameters or return
256
//! types, so the trait information below reflects that.
257
template <typename MethodParams, typename Enable = void>
258
struct ProxyMethodTraits
259
{
260
    using Params = TypeList<>;
261
    using Result = void;
262
    using Fields = Params;
263
264
    template <typename ServerContext>
265
    static void invoke(ServerContext&)
266
10
    {
267
10
    }
268
};
269
270
//! Specialization of above for proxy methods that have a
271
//! ProxyMethod<InterfaceName::MethodNameParams>::impl pointer-to-method
272
//! constant defined by generated code. This includes all functions defined in
273
//! the capnp interface except any construct() or destroy() methods, that are
274
//! assumed not to correspond to real member functions in the C++ class, and
275
//! will use the fallback traits definition above. The generated code this
276
//! specialization relies on looks like:
277
//!
278
//! struct ProxyMethod<InterfaceName::MethodNameParams>
279
//! {
280
//!     static constexpr auto impl = &ClassName::methodName;
281
//! };
282
template <typename MethodParams>
283
struct ProxyMethodTraits<MethodParams, Require<decltype(ProxyMethod<MethodParams>::impl)>>
284
    : public FunctionTraits<decltype(ProxyMethod<MethodParams>::impl)>
285
{
286
    template <typename ServerContext, typename... Args>
287
    static decltype(auto) invoke(ServerContext& server_context, Args&&... args)
288
26
    {
289
26
        return (server_context.proxy_server.m_impl.get()->*ProxyMethod<MethodParams>::impl)(std::forward<Args>(args)...);
290
26
    }
decltype(auto) mp::ProxyMethodTraits<gen::FooInterface::AddParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<gen::FooInterface>, capnp::CallContext<gen::FooInterface::AddParams, gen::FooInterface::AddResults>>, int, int>(mp::ServerInvokeContext<mp::ProxyServer<gen::FooInterface>, capnp::CallContext<gen::FooInterface::AddParams, gen::FooInterface::AddResults>>&, int&&, int&&)
Line
Count
Source
288
1
    {
289
1
        return (server_context.proxy_server.m_impl.get()->*ProxyMethod<MethodParams>::impl)(std::forward<Args>(args)...);
290
1
    }
decltype(auto) mp::ProxyMethodTraits<gen::FooInterface::PassOutPointParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<gen::FooInterface>, capnp::CallContext<gen::FooInterface::PassOutPointParams, gen::FooInterface::PassOutPointResults>>, COutPoint>(mp::ServerInvokeContext<mp::ProxyServer<gen::FooInterface>, capnp::CallContext<gen::FooInterface::PassOutPointParams, gen::FooInterface::PassOutPointResults>>&, COutPoint&&)
Line
Count
Source
288
1
    {
289
1
        return (server_context.proxy_server.m_impl.get()->*ProxyMethod<MethodParams>::impl)(std::forward<Args>(args)...);
290
1
    }
decltype(auto) mp::ProxyMethodTraits<gen::FooInterface::PassUniValueParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<gen::FooInterface>, capnp::CallContext<gen::FooInterface::PassUniValueParams, gen::FooInterface::PassUniValueResults>>, UniValue>(mp::ServerInvokeContext<mp::ProxyServer<gen::FooInterface>, capnp::CallContext<gen::FooInterface::PassUniValueParams, gen::FooInterface::PassUniValueResults>>&, UniValue&&)
Line
Count
Source
288
1
    {
289
1
        return (server_context.proxy_server.m_impl.get()->*ProxyMethod<MethodParams>::impl)(std::forward<Args>(args)...);
290
1
    }
decltype(auto) mp::ProxyMethodTraits<gen::FooInterface::PassTransactionParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<gen::FooInterface>, capnp::CallContext<gen::FooInterface::PassTransactionParams, gen::FooInterface::PassTransactionResults>>, std::shared_ptr<CTransaction const>>(mp::ServerInvokeContext<mp::ProxyServer<gen::FooInterface>, capnp::CallContext<gen::FooInterface::PassTransactionParams, gen::FooInterface::PassTransactionResults>>&, std::shared_ptr<CTransaction const>&&)
Line
Count
Source
288
1
    {
289
1
        return (server_context.proxy_server.m_impl.get()->*ProxyMethod<MethodParams>::impl)(std::forward<Args>(args)...);
290
1
    }
decltype(auto) mp::ProxyMethodTraits<gen::FooInterface::PassVectorCharParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<gen::FooInterface>, capnp::CallContext<gen::FooInterface::PassVectorCharParams, gen::FooInterface::PassVectorCharResults>>, std::vector<char, std::allocator<char>>>(mp::ServerInvokeContext<mp::ProxyServer<gen::FooInterface>, capnp::CallContext<gen::FooInterface::PassVectorCharParams, gen::FooInterface::PassVectorCharResults>>&, std::vector<char, std::allocator<char>>&&)
Line
Count
Source
288
1
    {
289
1
        return (server_context.proxy_server.m_impl.get()->*ProxyMethod<MethodParams>::impl)(std::forward<Args>(args)...);
290
1
    }
decltype(auto) mp::ProxyMethodTraits<gen::FooInterface::PassScriptParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<gen::FooInterface>, capnp::CallContext<gen::FooInterface::PassScriptParams, gen::FooInterface::PassScriptResults>>, CScript>(mp::ServerInvokeContext<mp::ProxyServer<gen::FooInterface>, capnp::CallContext<gen::FooInterface::PassScriptParams, gen::FooInterface::PassScriptResults>>&, CScript&&)
Line
Count
Source
288
1
    {
289
1
        return (server_context.proxy_server.m_impl.get()->*ProxyMethod<MethodParams>::impl)(std::forward<Args>(args)...);
290
1
    }
decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::Init::MakeEchoParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Init>, capnp::CallContext<ipc::capnp::messages::Init::MakeEchoParams, ipc::capnp::messages::Init::MakeEchoResults>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Init>, capnp::CallContext<ipc::capnp::messages::Init::MakeEchoParams, ipc::capnp::messages::Init::MakeEchoResults>>&)
Line
Count
Source
288
6
    {
289
6
        return (server_context.proxy_server.m_impl.get()->*ProxyMethod<MethodParams>::impl)(std::forward<Args>(args)...);
290
6
    }
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::Init::MakeMiningOld2Params, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Init>, capnp::CallContext<ipc::capnp::messages::Init::MakeMiningOld2Params, ipc::capnp::messages::Init::MakeMiningOld2Results>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Init>, capnp::CallContext<ipc::capnp::messages::Init::MakeMiningOld2Params, ipc::capnp::messages::Init::MakeMiningOld2Results>>&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::Init::MakeMiningParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Init>, capnp::CallContext<ipc::capnp::messages::Init::MakeMiningParams, ipc::capnp::messages::Init::MakeMiningResults>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Init>, capnp::CallContext<ipc::capnp::messages::Init::MakeMiningParams, ipc::capnp::messages::Init::MakeMiningResults>>&)
decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::Init::MakeRpcParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Init>, capnp::CallContext<ipc::capnp::messages::Init::MakeRpcParams, ipc::capnp::messages::Init::MakeRpcResults>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Init>, capnp::CallContext<ipc::capnp::messages::Init::MakeRpcParams, ipc::capnp::messages::Init::MakeRpcResults>>&)
Line
Count
Source
288
4
    {
289
4
        return (server_context.proxy_server.m_impl.get()->*ProxyMethod<MethodParams>::impl)(std::forward<Args>(args)...);
290
4
    }
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::Mining::IsTestChainParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::IsTestChainParams, ipc::capnp::messages::Mining::IsTestChainResults>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::IsTestChainParams, ipc::capnp::messages::Mining::IsTestChainResults>>&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::Mining::IsInitialBlockDownloadParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::IsInitialBlockDownloadParams, ipc::capnp::messages::Mining::IsInitialBlockDownloadResults>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::IsInitialBlockDownloadParams, ipc::capnp::messages::Mining::IsInitialBlockDownloadResults>>&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::Mining::GetTipParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::GetTipParams, ipc::capnp::messages::Mining::GetTipResults>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::GetTipParams, ipc::capnp::messages::Mining::GetTipResults>>&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::Mining::WaitTipChangedParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitTipChangedParams, ipc::capnp::messages::Mining::WaitTipChangedResults>>, uint256, std::chrono::duration<double, std::ratio<1l, 1000l>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::WaitTipChangedParams, ipc::capnp::messages::Mining::WaitTipChangedResults>>&, uint256&&, std::chrono::duration<double, std::ratio<1l, 1000l>>&&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::Mining::CreateNewBlockParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::CreateNewBlockParams, ipc::capnp::messages::Mining::CreateNewBlockResults>>, node::BlockCreateOptions const&, bool>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::CreateNewBlockParams, ipc::capnp::messages::Mining::CreateNewBlockResults>>&, node::BlockCreateOptions const&, bool&&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::Mining::CheckBlockParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::CheckBlockParams, ipc::capnp::messages::Mining::CheckBlockResults>>, CBlock const&, node::BlockCheckOptions const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::CheckBlockParams, ipc::capnp::messages::Mining::CheckBlockResults>>&, CBlock const&, node::BlockCheckOptions const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::Mining::InterruptParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::InterruptParams, ipc::capnp::messages::Mining::InterruptResults>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Mining>, capnp::CallContext<ipc::capnp::messages::Mining::InterruptParams, ipc::capnp::messages::Mining::InterruptResults>>&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::BlockTemplate::GetBlockHeaderParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::GetBlockHeaderParams, ipc::capnp::messages::BlockTemplate::GetBlockHeaderResults>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::GetBlockHeaderParams, ipc::capnp::messages::BlockTemplate::GetBlockHeaderResults>>&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::BlockTemplate::GetBlockParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::GetBlockParams, ipc::capnp::messages::BlockTemplate::GetBlockResults>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::GetBlockParams, ipc::capnp::messages::BlockTemplate::GetBlockResults>>&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::BlockTemplate::GetTxFeesParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::GetTxFeesParams, ipc::capnp::messages::BlockTemplate::GetTxFeesResults>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::GetTxFeesParams, ipc::capnp::messages::BlockTemplate::GetTxFeesResults>>&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::BlockTemplate::GetTxSigopsParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::GetTxSigopsParams, ipc::capnp::messages::BlockTemplate::GetTxSigopsResults>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::GetTxSigopsParams, ipc::capnp::messages::BlockTemplate::GetTxSigopsResults>>&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::BlockTemplate::GetCoinbaseTxParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::GetCoinbaseTxParams, ipc::capnp::messages::BlockTemplate::GetCoinbaseTxResults>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::GetCoinbaseTxParams, ipc::capnp::messages::BlockTemplate::GetCoinbaseTxResults>>&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::BlockTemplate::GetCoinbaseMerklePathParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::GetCoinbaseMerklePathParams, ipc::capnp::messages::BlockTemplate::GetCoinbaseMerklePathResults>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::GetCoinbaseMerklePathParams, ipc::capnp::messages::BlockTemplate::GetCoinbaseMerklePathResults>>&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::BlockTemplate::SubmitSolutionParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::SubmitSolutionParams, ipc::capnp::messages::BlockTemplate::SubmitSolutionResults>>, unsigned int, unsigned int, unsigned int, std::shared_ptr<CTransaction const>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::SubmitSolutionParams, ipc::capnp::messages::BlockTemplate::SubmitSolutionResults>>&, unsigned int&&, unsigned int&&, unsigned int&&, std::shared_ptr<CTransaction const>&&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::BlockTemplate::WaitNextParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>, node::BlockWaitOptions>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::WaitNextParams, ipc::capnp::messages::BlockTemplate::WaitNextResults>>&, node::BlockWaitOptions&&)
Unexecuted instantiation: decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::BlockTemplate::InterruptWaitParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::InterruptWaitParams, ipc::capnp::messages::BlockTemplate::InterruptWaitResults>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::BlockTemplate>, capnp::CallContext<ipc::capnp::messages::BlockTemplate::InterruptWaitParams, ipc::capnp::messages::BlockTemplate::InterruptWaitResults>>&)
decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::Rpc::ExecuteRpcParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Rpc>, capnp::CallContext<ipc::capnp::messages::Rpc::ExecuteRpcParams, ipc::capnp::messages::Rpc::ExecuteRpcResults>>, UniValue, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Rpc>, capnp::CallContext<ipc::capnp::messages::Rpc::ExecuteRpcParams, ipc::capnp::messages::Rpc::ExecuteRpcResults>>&, UniValue&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&&)
Line
Count
Source
288
4
    {
289
4
        return (server_context.proxy_server.m_impl.get()->*ProxyMethod<MethodParams>::impl)(std::forward<Args>(args)...);
290
4
    }
decltype(auto) mp::ProxyMethodTraits<ipc::capnp::messages::Echo::EchoParams, void>::invoke<mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Echo>, capnp::CallContext<ipc::capnp::messages::Echo::EchoParams, ipc::capnp::messages::Echo::EchoResults>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&>(mp::ServerInvokeContext<mp::ProxyServer<ipc::capnp::messages::Echo>, capnp::CallContext<ipc::capnp::messages::Echo::EchoParams, ipc::capnp::messages::Echo::EchoResults>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
Line
Count
Source
288
6
    {
289
6
        return (server_context.proxy_server.m_impl.get()->*ProxyMethod<MethodParams>::impl)(std::forward<Args>(args)...);
290
6
    }
291
};
292
293
//! Customizable (through template specialization) traits class used in generated ProxyClient implementations from
294
//! proxy-codegen.cpp.
295
template <typename MethodParams>
296
struct ProxyClientMethodTraits : public ProxyMethodTraits<MethodParams>
297
{
298
};
299
300
//! Customizable (through template specialization) traits class used in generated ProxyServer implementations from
301
//! proxy-codegen.cpp.
302
template <typename MethodParams>
303
struct ProxyServerMethodTraits : public ProxyMethodTraits<MethodParams>
304
{
305
};
306
307
static constexpr int FIELD_IN = 1;
308
static constexpr int FIELD_OUT = 2;
309
static constexpr int FIELD_OPTIONAL = 4;
310
static constexpr int FIELD_REQUESTED = 8;
311
static constexpr int FIELD_BOXED = 16;
312
313
//! Accessor type holding flags that determine how to access a message field.
314
template <typename Field, int flags>
315
struct Accessor : public Field
316
{
317
    static const bool in = flags & FIELD_IN;
318
    static const bool out = flags & FIELD_OUT;
319
    static const bool optional = flags & FIELD_OPTIONAL;
320
    static const bool requested = flags & FIELD_REQUESTED;
321
    static const bool boxed = flags & FIELD_BOXED;
322
};
323
324
//! Wrapper around std::function for passing std::function objects between client and servers.
325
template <typename Fn>
326
class ProxyCallback;
327
328
//! Specialization of above to separate Result and Arg types.
329
template <typename Result, typename... Args>
330
class ProxyCallback<std::function<Result(Args...)>>
331
{
332
public:
333
    virtual Result call(Args&&... args) = 0;
334
};
335
336
} // namespace mp
337
338
#endif // MP_PROXY_H