diff --git a/src/ipc/capnp/common-types.h b/src/ipc/capnp/common-types.h index 39e368491b4..3e238648cfc 100644 --- a/src/ipc/capnp/common-types.h +++ b/src/ipc/capnp/common-types.h @@ -6,6 +6,7 @@ #define BITCOIN_IPC_CAPNP_COMMON_TYPES_H #include +#include #include #include @@ -16,33 +17,6 @@ namespace ipc { namespace capnp { -//! Use SFINAE to define Serializeable trait which is true if type T has a -//! Serialize(stream) method, false otherwise. -template -struct Serializable { -private: - template - static std::true_type test(decltype(std::declval().Serialize(std::declval()))*); - template - static std::false_type test(...); - -public: - static constexpr bool value = decltype(test(nullptr))::value; -}; - -//! Use SFINAE to define Unserializeable trait which is true if type T has -//! an Unserialize(stream) method, false otherwise. -template -struct Unserializable { -private: - template - static std::true_type test(decltype(std::declval().Unserialize(std::declval()))*); - template - static std::false_type test(...); - -public: - static constexpr bool value = decltype(test(nullptr))::value; -}; } // namespace capnp } // namespace ipc @@ -50,18 +24,16 @@ public: namespace mp { //! Overload multiprocess library's CustomBuildField hook to allow any //! serializable object to be stored in a capnproto Data field or passed to a -//! canproto interface. Use Priority<1> so this hook has medium priority, and +//! capnproto interface. Use Priority<1> so this hook has medium priority, and //! higher priority hooks could take precedence over this one. template -void CustomBuildField( - TypeList, Priority<1>, InvokeContext& invoke_context, Value&& value, Output&& output, - // Enable if serializeable and if LocalType is not cv or reference - // qualified. If LocalType is cv or reference qualified, it is important to - // fall back to lower-priority Priority<0> implementation of this function - // that strips cv references, to prevent this CustomBuildField overload from - // taking precedence over more narrow overloads for specific LocalTypes. - std::enable_if_t::value && - std::is_same_v>>>* enable = nullptr) +void CustomBuildField(TypeList, Priority<1>, InvokeContext& invoke_context, Value&& value, Output&& output) +// Enable if serializeable and if LocalType is not cv or reference qualified. If +// LocalType is cv or reference qualified, it is important to fall back to +// lower-priority Priority<0> implementation of this function that strips cv +// references, to prevent this CustomBuildField overload from taking precedence +// over more narrow overloads for specific LocalTypes. +requires Serializable && std::is_same_v>> { DataStream stream; value.Serialize(stream); @@ -71,12 +43,11 @@ void CustomBuildField( //! Overload multiprocess library's CustomReadField hook to allow any object //! with an Unserialize method to be read from a capnproto Data field or -//! returned from canproto interface. Use Priority<1> so this hook has medium +//! returned from capnproto interface. Use Priority<1> so this hook has medium //! priority, and higher priority hooks could take precedence over this one. template -decltype(auto) -CustomReadField(TypeList, Priority<1>, InvokeContext& invoke_context, Input&& input, ReadDest&& read_dest, - std::enable_if_t::value>* enable = nullptr) +decltype(auto) CustomReadField(TypeList, Priority<1>, InvokeContext& invoke_context, Input&& input, ReadDest&& read_dest) +requires Unserializable { return read_dest.update([&](auto& value) { if (!input.has()) return; @@ -86,6 +57,8 @@ CustomReadField(TypeList, Priority<1>, InvokeContext& invoke_context, }); } +//! Overload CustomBuildField and CustomReadField to serialize UniValue +//! parameters and return values as JSON strings. template void CustomBuildField(TypeList, Priority<1>, InvokeContext& invoke_context, Value&& value, Output&& output) {