diff --git a/src/serialize.h b/src/serialize.h --- a/src/serialize.h +++ b/src/serialize.h @@ -536,6 +536,45 @@ } } +/** + * Simple wrapper class to serialize objects using a formatter; used by + * Using(). + */ +template class Wrapper { + static_assert(std::is_lvalue_reference::value, + "Wrapper needs an lvalue reference type T"); + +protected: + T m_object; + +public: + explicit Wrapper(T obj) : m_object(obj) {} + template void Serialize(Stream &s) const { + Formatter().Ser(s, m_object); + } + template void Unserialize(Stream &s) { + Formatter().Unser(s, m_object); + } +}; + +/** + * Cause serialization/deserialization of an object to be done using a + * specified formatter class. + * + * To use this, you need a class Formatter that has public functions Ser(stream, + * const object&) for serialization, and Unser(stream, object&) for + * deserialization. Serialization routines (inside READWRITE, or directly with + * << and >> operators), can then use Using(object). + * + * This works by constructing a Wrapper-wrapped version of object, + * where T is const during serialization, and non-const during deserialization, + * which maintains const correctness. + */ +template +static inline Wrapper Using(T &&t) { + return Wrapper(t); +} + #define VARINT(obj, ...) WrapVarInt<__VA_ARGS__>(REF(obj)) #define COMPACTSIZE(obj) CCompactSize(REF(obj)) #define LIMITED_STRING(obj, n) LimitedString(REF(obj))