@@ -199,6 +199,30 @@ template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
199199 SerializationOp (s, CSerActionUnserialize ()); \
200200 }
201201
202+ /* *
203+ * Implement the Ser and Unser methods needed for implementing a formatter (see Using below).
204+ *
205+ * Both Ser and Unser are delegated to a single static method SerializationOps, which is polymorphic
206+ * in the serialized/deserialized type (allowing it to be const when serializing, and non-const when
207+ * deserializing).
208+ *
209+ * Example use:
210+ * struct FooFormatter {
211+ * FORMATTER_METHODS(Class, obj) { READWRITE(obj.val1, VARINT(obj.val2)); }
212+ * }
213+ * would define a class FooFormatter that defines a serialization of Class objects consisting
214+ * of serializing its val1 member using the default serialization, and its val2 member using
215+ * VARINT serialization. That FooFormatter can then be used in statements like
216+ * READWRITE(Using<FooFormatter>(obj.bla)).
217+ */
218+ #define FORMATTER_METHODS (cls, obj ) \
219+ template <typename Stream> \
220+ static void Ser (Stream& s, const cls& obj) { SerializationOps (obj, s, CSerActionSerialize ()); } \
221+ template <typename Stream> \
222+ static void Unser (Stream& s, cls& obj) { SerializationOps (obj, s, CSerActionUnserialize ()); } \
223+ template <typename Stream, typename Type, typename Operation> \
224+ static inline void SerializationOps (Type& obj, Stream& s, Operation ser_action) \
225+
202226/* *
203227 * Implement the Serialize and Unserialize methods by delegating to a single templated
204228 * 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; }
211235 void Serialize (Stream& s) const \
212236 { \
213237 static_assert (std::is_same<const cls&, decltype (*this )>::value, " Serialize type mismatch" ); \
214- SerializationOps (* this , s, CSerActionSerialize ()); \
238+ Ser ( s, * this ); \
215239 } \
216240 template <typename Stream> \
217241 void Unserialize (Stream& s) \
218242 { \
219243 static_assert (std::is_same<cls&, decltype (*this )>::value, " Unserialize type mismatch" ); \
220- SerializationOps (* this , s, CSerActionUnserialize ()); \
244+ Unser ( s, * this ); \
221245 } \
222- template <typename Stream, typename Type, typename Operation> \
223- static inline void SerializationOps (Type& obj, Stream& s, Operation ser_action) \
224-
246+ FORMATTER_METHODS (cls, obj)
225247
226248#ifndef CHAR_EQUALS_INT8
227249template <typename Stream> inline void Serialize (Stream& s, char a ) { ser_writedata8 (s, a); } // TODO Get rid of bare char
0 commit comments