diff options
author | Kamil Domanski <kdomanski@kdemail.net> | 2014-08-20 08:42:31 +0200 |
---|---|---|
committer | Kamil Domanski <kdomanski@kdemail.net> | 2014-08-31 02:14:20 +0200 |
commit | 3d796f89962842e91e7d88e57c1d2d579f01052e (patch) | |
tree | d4be736c23fbc4d453a1e4e281eafb4f51cdffd8 /src/serialize.h | |
parent | 9f3d47677973cb894fdbb437b9b322e2062a1bf1 (diff) |
overhaul serialization code
The implementation of each class' serialization/deserialization is no longer
passed within a macro. The implementation now lies within a template of form:
template <typename T, typename Stream, typename Operation>
inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) {
size_t nSerSize = 0;
/* CODE */
return nSerSize;
}
In cases when codepath should depend on whether or not we are just deserializing
(old fGetSize, fWrite, fRead flags) an additional clause can be used:
bool fRead = boost::is_same<Operation, CSerActionUnserialize>();
The IMPLEMENT_SERIALIZE macro will now be a freestanding clause added within
class' body (similiar to Qt's Q_OBJECT) to implement GetSerializeSize,
Serialize and Unserialize. These are now wrappers around
the "SerializationOp" template.
Diffstat (limited to 'src/serialize.h')
-rw-r--r-- | src/serialize.h | 68 |
1 files changed, 28 insertions, 40 deletions
diff --git a/src/serialize.h b/src/serialize.h index 17cb724bee..7e0ecc2edf 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -22,6 +22,7 @@ #include <boost/tuple/tuple.hpp> #include <boost/type_traits/is_fundamental.hpp> +#include <boost/typeof/typeof.hpp> class CAutoFile; class CDataStream; @@ -37,6 +38,14 @@ inline T& REF(const T& val) return const_cast<T&>(val); } +// Used to acquire a const pointer "this" and generate a const +// serialization operation from a template +template<typename T> +inline T MAKE_CONST(T val) +{ + return const_cast<const T>(val); +} + /** Get begin pointer of vector (non-const version). * @note These functions avoid the undefined case of indexing into an empty * vector, as well as that of indexing after the end of the vector. @@ -79,48 +88,27 @@ enum SER_GETHASH = (1 << 2), }; -#define IMPLEMENT_SERIALIZE(statements) \ - unsigned int GetSerializeSize(int nType, int nVersion) const \ - { \ - CSerActionGetSerializeSize ser_action; \ - const bool fGetSize = true; \ - const bool fWrite = false; \ - const bool fRead = false; \ - unsigned int nSerSize = 0; \ - ser_streamplaceholder s; \ - assert(fGetSize||fWrite||fRead); /* suppress warning */ \ - s.nType = nType; \ - s.nVersion = nVersion; \ - {statements} \ - return nSerSize; \ - } \ - template<typename Stream> \ - void Serialize(Stream& s, int nType, int nVersion) const \ - { \ - CSerActionSerialize ser_action; \ - const bool fGetSize = false; \ - const bool fWrite = true; \ - const bool fRead = false; \ - unsigned int nSerSize = 0; \ - assert(fGetSize||fWrite||fRead); /* suppress warning */ \ - {statements} \ - } \ - template<typename Stream> \ - void Unserialize(Stream& s, int nType, int nVersion) \ - { \ - CSerActionUnserialize ser_action; \ - const bool fGetSize = false; \ - const bool fWrite = false; \ - const bool fRead = true; \ - unsigned int nSerSize = 0; \ - assert(fGetSize||fWrite||fRead); /* suppress warning */ \ - {statements} \ - } - #define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action)) - - +/* Implement three methods for serializable objects. These are actually wrappers over + * "SerializationOp" template, which implements the body of each class' serialization + * code. Adding "IMPLEMENT_SERIALIZE" in the body of the class causes these wrappers to be + * added as members. */ +#define IMPLEMENT_SERIALIZE \ + size_t GetSerializeSize(int nType, int nVersion) const { \ + ser_streamplaceholder s; \ + s.nType = nType; \ + s.nVersion = nVersion; \ + return SerializationOp(MAKE_CONST(this), s, CSerActionGetSerializeSize(), nType, nVersion); \ + } \ + template<typename Stream> \ + void Serialize(Stream& s, int nType, int nVersion) const { \ + SerializationOp(MAKE_CONST(this), s, CSerActionSerialize(), nType, nVersion); \ + } \ + template<typename Stream> \ + void Unserialize(Stream& s, int nType, int nVersion) { \ + SerializationOp(this, s, CSerActionUnserialize(), nType, nVersion); \ + } |