Branch data Line data Source code
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_TYPE_POINTER_H
6 : : #define MP_PROXY_TYPE_POINTER_H
7 : :
8 : : #include <mp/util.h>
9 : :
10 : : namespace mp {
11 : : template <typename LocalType, typename Value, typename Output>
12 : : void CustomBuildField(TypeList<LocalType*>, Priority<3>, InvokeContext& invoke_context, Value&& value, Output&& output)
13 : : {
14 : : if (value) {
15 : : BuildField(TypeList<LocalType>(), invoke_context, output, *value);
16 : : }
17 : : }
18 : :
19 : : template <typename LocalType, typename Value, typename Output>
20 : 2 : void CustomBuildField(TypeList<std::shared_ptr<LocalType>>,
21 : : Priority<1>,
22 : : InvokeContext& invoke_context,
23 : : Value&& value,
24 : : Output&& output)
25 : : {
26 [ + - ]: 2 : if (value) {
27 : 2 : BuildField(TypeList<LocalType>(), invoke_context, output, *value);
28 : : }
29 : 2 : }
30 : :
31 : : template <typename LocalType, typename Input, typename ReadDest>
32 : : decltype(auto) CustomReadField(TypeList<LocalType*>,
33 : : Priority<1>,
34 : : InvokeContext& invoke_context,
35 : : Input&& input,
36 : : ReadDest&& read_dest)
37 : : {
38 : : return read_dest.update([&](auto& value) {
39 : : if (value) {
40 : : ReadField(TypeList<LocalType>(), invoke_context, std::forward<Input>(input), ReadDestUpdate(*value));
41 : : }
42 : : });
43 : : }
44 : :
45 : : template <typename LocalType, typename Input, typename ReadDest>
46 : : decltype(auto) CustomReadField(TypeList<std::shared_ptr<LocalType>>,
47 : : Priority<0>,
48 : : InvokeContext& invoke_context,
49 : : Input&& input,
50 : : ReadDest&& read_dest)
51 : : {
52 : : return read_dest.update([&](auto& value) {
53 : : if (!input.has()) {
54 : : value.reset();
55 : : } else if (value) {
56 : : ReadField(TypeList<LocalType>(), invoke_context, input, ReadDestUpdate(*value));
57 : : } else {
58 : : ReadField(TypeList<LocalType>(), invoke_context, input,
59 : : ReadDestEmplace(TypeList<LocalType>(), [&](auto&&... args) -> auto& {
60 : : value = std::make_shared<LocalType>(std::forward<decltype(args)>(args)...);
61 : : return *value;
62 : : }));
63 : : }
64 : : });
65 : : }
66 : :
67 : : template <typename LocalType, typename Input, typename ReadDest>
68 : 2 : decltype(auto) CustomReadField(TypeList<std::shared_ptr<const LocalType>>,
69 : : Priority<1>,
70 : : InvokeContext& invoke_context,
71 : : Input&& input,
72 : : ReadDest&& read_dest)
73 : : {
74 : 2 : return read_dest.update([&](auto& value) {
75 [ - + ]: 2 : if (!input.has()) {
76 : 0 : value.reset();
77 : 0 : return;
78 : : }
79 : 2 : ReadField(TypeList<LocalType>(), invoke_context, std::forward<Input>(input),
80 : 4 : ReadDestEmplace(TypeList<LocalType>(), [&](auto&&... args) -> auto& {
81 [ - + ]: 2 : value = std::make_shared<LocalType>(std::forward<decltype(args)>(args)...);
82 : 2 : return *value;
83 : : }));
84 : 2 : });
85 : : }
86 : :
87 : : //! PassField override for C++ pointer arguments.
88 : : template <typename Accessor, typename LocalType, typename ServerContext, typename Fn, typename... Args>
89 : : void PassField(Priority<1>, TypeList<LocalType*>, ServerContext& server_context, const Fn& fn, Args&&... args)
90 : : {
91 : : const auto& params = server_context.call_context.getParams();
92 : : const auto& input = Make<StructField, Accessor>(params);
93 : :
94 : : if (!input.want()) {
95 : : fn.invoke(server_context, std::forward<Args>(args)..., nullptr);
96 : : return;
97 : : }
98 : :
99 : : InvokeContext& invoke_context = server_context;
100 : : Decay<LocalType> param;
101 : :
102 : : MaybeReadField(std::integral_constant<bool, Accessor::in>(), TypeList<LocalType>(), invoke_context, input,
103 : : ReadDestUpdate(param));
104 : :
105 : : fn.invoke(server_context, std::forward<Args>(args)..., ¶m);
106 : :
107 : : auto&& results = server_context.call_context.getResults();
108 : : MaybeBuildField(std::integral_constant<bool, Accessor::out>(), TypeList<LocalType>(), invoke_context,
109 : : Make<StructField, Accessor>(results), param);
110 : : }
111 : : } // namespace mp
112 : :
113 : : #endif // MP_PROXY_TYPE_POINTER_H
|