Skip to content

Commit

Permalink
Add FORMATTER_METHODS, similar to SERIALIZE_METHODS, but for formatters
Browse files Browse the repository at this point in the history
  • Loading branch information
sipa authored and furszy committed Jul 3, 2021
1 parent 3e38199 commit aa35991
Showing 1 changed file with 27 additions and 4 deletions.
31 changes: 27 additions & 4 deletions src/serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,30 @@ template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
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
* static method that takes the to-be-(de)serialized object as a parameter. This approach
Expand All @@ -210,16 +234,15 @@ template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
void Serialize(Stream& s) const \
{ \
static_assert(std::is_same<const cls&, decltype(*this)>::value, "Serialize type mismatch"); \
SerializationOps(*this, s, CSerActionSerialize()); \
Ser(s, *this); \
} \
template<typename Stream> \
void Unserialize(Stream& s) \
{ \
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> \
static inline void SerializationOps(Type& obj, Stream& s, Operation ser_action) \
FORMATTER_METHODS(cls, obj)

/*
* Basic Types
Expand Down

0 comments on commit aa35991

Please sign in to comment.