// Copyright (c) 2025 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_POINTER_H #define MP_PROXY_TYPE_POINTER_H #include namespace mp { template void CustomBuildField(TypeList, Priority<3>, InvokeContext& invoke_context, Value&& value, Output&& output) { if (value) { BuildField(TypeList(), invoke_context, output, *value); } } template void CustomBuildField(TypeList>, Priority<1>, InvokeContext& invoke_context, Value&& value, Output&& output) { if (value) { BuildField(TypeList(), invoke_context, output, *value); } } template decltype(auto) CustomReadField(TypeList, Priority<1>, InvokeContext& invoke_context, Input&& input, ReadDest&& read_dest) { return read_dest.update([&](auto& value) { if (value) { ReadField(TypeList(), invoke_context, std::forward(input), ReadDestUpdate(*value)); } }); } template decltype(auto) CustomReadField(TypeList>, Priority<0>, InvokeContext& invoke_context, Input&& input, ReadDest&& read_dest) { return read_dest.update([&](auto& value) { if (!input.has()) { value.reset(); } else if (value) { ReadField(TypeList(), invoke_context, input, ReadDestUpdate(*value)); } else { ReadField(TypeList(), invoke_context, input, ReadDestEmplace(TypeList(), [&](auto&&... args) -> auto& { value = std::make_shared(std::forward(args)...); return *value; })); } }); } template decltype(auto) CustomReadField(TypeList>, Priority<1>, InvokeContext& invoke_context, Input&& input, ReadDest&& read_dest) { return read_dest.update([&](auto& value) { if (!input.has()) { value.reset(); return; } ReadField(TypeList(), invoke_context, std::forward(input), ReadDestEmplace(TypeList(), [&](auto&&... args) -> auto& { value = std::make_shared(std::forward(args)...); return *value; })); }); } //! PassField override for C++ pointer arguments. template void PassField(Priority<1>, TypeList, ServerContext& server_context, const Fn& fn, Args&&... args) { const auto& params = server_context.call_context.getParams(); const auto& input = Make(params); if (!input.want()) { fn.invoke(server_context, std::forward(args)..., nullptr); return; } InvokeContext& invoke_context = server_context; Decay param; MaybeReadField(std::integral_constant(), TypeList(), invoke_context, input, ReadDestUpdate(param)); fn.invoke(server_context, std::forward(args)..., ¶m); auto&& results = server_context.call_context.getResults(); MaybeBuildField(std::integral_constant(), TypeList(), invoke_context, Make(results), param); } } // namespace mp #endif // MP_PROXY_TYPE_POINTER_H