0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-09 10:43:19 -05:00

Add FORMATTER_METHODS, similar to SERIALIZE_METHODS, but for formatters

This commit is contained in:
Pieter Wuille 2020-01-18 07:32:31 -08:00
parent a654626f07
commit ca34c5cba5

View file

@ -199,6 +199,30 @@ template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
SerializationOp(s, CSerActionUnserialize()); \ SerializationOp(s, CSerActionUnserialize()); \
} }
/**
* Implement the Ser and Unser methods needed for implementing a formatter (see Using below).
*
* Both Ser and Unser are delegated to a single static method SerializationOps, which is polymorphic
* in the serialized/deserialized type (allowing it to be const when serializing, and non-const when
* deserializing).
*
* Example use:
* struct FooFormatter {
* FORMATTER_METHODS(Class, obj) { READWRITE(obj.val1, VARINT(obj.val2)); }
* }
* would define a class FooFormatter that defines a serialization of Class objects consisting
* of serializing its val1 member using the default serialization, and its val2 member using
* VARINT serialization. That FooFormatter can then be used in statements like
* READWRITE(Using<FooFormatter>(obj.bla)).
*/
#define FORMATTER_METHODS(cls, obj) \
template<typename Stream> \
static void Ser(Stream& s, const cls& obj) { SerializationOps(obj, s, CSerActionSerialize()); } \
template<typename Stream> \
static void Unser(Stream& s, cls& obj) { SerializationOps(obj, s, CSerActionUnserialize()); } \
template<typename Stream, typename Type, typename Operation> \
static inline void SerializationOps(Type& obj, Stream& s, Operation ser_action) \
/** /**
* Implement the Serialize and Unserialize methods by delegating to a single templated * Implement the Serialize and Unserialize methods by delegating to a single templated
* static method that takes the to-be-(de)serialized object as a parameter. This approach * static method that takes the to-be-(de)serialized object as a parameter. This approach
@ -211,17 +235,15 @@ template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
void Serialize(Stream& s) const \ void Serialize(Stream& s) const \
{ \ { \
static_assert(std::is_same<const cls&, decltype(*this)>::value, "Serialize type mismatch"); \ static_assert(std::is_same<const cls&, decltype(*this)>::value, "Serialize type mismatch"); \
SerializationOps(*this, s, CSerActionSerialize()); \ Ser(s, *this); \
} \ } \
template<typename Stream> \ template<typename Stream> \
void Unserialize(Stream& s) \ void Unserialize(Stream& s) \
{ \ { \
static_assert(std::is_same<cls&, decltype(*this)>::value, "Unserialize type mismatch"); \ static_assert(std::is_same<cls&, decltype(*this)>::value, "Unserialize type mismatch"); \
SerializationOps(*this, s, CSerActionUnserialize()); \ Unser(s, *this); \
} \ } \
template<typename Stream, typename Type, typename Operation> \ FORMATTER_METHODS(cls, obj)
static inline void SerializationOps(Type& obj, Stream& s, Operation ser_action) \
#ifndef CHAR_EQUALS_INT8 #ifndef CHAR_EQUALS_INT8
template<typename Stream> inline void Serialize(Stream& s, char a ) { ser_writedata8(s, a); } // TODO Get rid of bare char template<typename Stream> inline void Serialize(Stream& s, char a ) { ser_writedata8(s, a); } // TODO Get rid of bare char