mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-21 14:05:06 +02:00
multiprocess: update common-types.h to use C++20 concepts
Idea came from review comment by ion- https://github.com/bitcoin/bitcoin/pull/30510#discussion_r1757372497
This commit is contained in:
parent
206c6e78ee
commit
69dfeb1876
@ -6,6 +6,7 @@
|
||||
#define BITCOIN_IPC_CAPNP_COMMON_TYPES_H
|
||||
|
||||
#include <clientversion.h>
|
||||
#include <serialize.h>
|
||||
#include <streams.h>
|
||||
#include <univalue.h>
|
||||
|
||||
@ -16,33 +17,6 @@
|
||||
|
||||
namespace ipc {
|
||||
namespace capnp {
|
||||
//! Use SFINAE to define Serializeable<T> trait which is true if type T has a
|
||||
//! Serialize(stream) method, false otherwise.
|
||||
template <typename T>
|
||||
struct Serializable {
|
||||
private:
|
||||
template <typename C>
|
||||
static std::true_type test(decltype(std::declval<C>().Serialize(std::declval<std::nullptr_t&>()))*);
|
||||
template <typename>
|
||||
static std::false_type test(...);
|
||||
|
||||
public:
|
||||
static constexpr bool value = decltype(test<T>(nullptr))::value;
|
||||
};
|
||||
|
||||
//! Use SFINAE to define Unserializeable<T> trait which is true if type T has
|
||||
//! an Unserialize(stream) method, false otherwise.
|
||||
template <typename T>
|
||||
struct Unserializable {
|
||||
private:
|
||||
template <typename C>
|
||||
static std::true_type test(decltype(std::declval<C>().Unserialize(std::declval<std::nullptr_t&>()))*);
|
||||
template <typename>
|
||||
static std::false_type test(...);
|
||||
|
||||
public:
|
||||
static constexpr bool value = decltype(test<T>(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 <typename LocalType, typename Value, typename Output>
|
||||
void CustomBuildField(
|
||||
TypeList<LocalType>, 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<ipc::capnp::Serializable<LocalType>::value &&
|
||||
std::is_same_v<LocalType, std::remove_cv_t<std::remove_reference_t<LocalType>>>>* enable = nullptr)
|
||||
void CustomBuildField(TypeList<LocalType>, 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<LocalType, DataStream> && std::is_same_v<LocalType, std::remove_cv_t<std::remove_reference_t<LocalType>>>
|
||||
{
|
||||
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 <typename LocalType, typename Input, typename ReadDest>
|
||||
decltype(auto)
|
||||
CustomReadField(TypeList<LocalType>, Priority<1>, InvokeContext& invoke_context, Input&& input, ReadDest&& read_dest,
|
||||
std::enable_if_t<ipc::capnp::Unserializable<LocalType>::value>* enable = nullptr)
|
||||
decltype(auto) CustomReadField(TypeList<LocalType>, Priority<1>, InvokeContext& invoke_context, Input&& input, ReadDest&& read_dest)
|
||||
requires Unserializable<LocalType, DataStream>
|
||||
{
|
||||
return read_dest.update([&](auto& value) {
|
||||
if (!input.has()) return;
|
||||
@ -86,6 +57,8 @@ CustomReadField(TypeList<LocalType>, Priority<1>, InvokeContext& invoke_context,
|
||||
});
|
||||
}
|
||||
|
||||
//! Overload CustomBuildField and CustomReadField to serialize UniValue
|
||||
//! parameters and return values as JSON strings.
|
||||
template <typename Value, typename Output>
|
||||
void CustomBuildField(TypeList<UniValue>, Priority<1>, InvokeContext& invoke_context, Value&& value, Output&& output)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user