diff options
Diffstat (limited to 'cpp/src/qpid/Serializer.h')
| -rw-r--r-- | cpp/src/qpid/Serializer.h | 84 |
1 files changed, 48 insertions, 36 deletions
diff --git a/cpp/src/qpid/Serializer.h b/cpp/src/qpid/Serializer.h index 34b95d3ffd..e0e29e24fd 100644 --- a/cpp/src/qpid/Serializer.h +++ b/cpp/src/qpid/Serializer.h @@ -23,59 +23,71 @@ */ #include <boost/utility/enable_if.hpp> -#include <boost/static_assert.hpp> -#include <boost/type_traits/is_class.hpp> -#include <algorithm> +#include <boost/type_traits/is_base_and_derived.hpp> namespace qpid { +namespace serialize { -// FIXME aconway 2008-03-03: Doc - esp decoding -template <class Derived> class Serializer { - public: - typedef Serializer result_type; // unary functor requirement. +// FIXME aconway 2008-03-03: Document. +// Encoder/Decoder concept: add op() for primitive types, raw(), +// op()(Iter, Iter). Note split, encode, decode. +// - static const bool IS_DECODER=false; +// FIXME aconway 2008-03-09: document - non-intrusive serialzation. +// Default rule calls member. Enums must provide an override rule. - /** Generic handler for class objects, call serialize() */ - template <class T> - typename boost::enable_if<boost::is_class<T>, Derived&>::type - operator()(T& t) { - t.serialize(self()); - return self(); - } +/** Overload for types that do not provide a serialize() member.*/ +template <class T> T& serializable(T& t) { return t; } + +template <class Derived> class Encoder { + public: + typedef Derived& result_type; // unary functor requirement. - /** Generic handler for const class objects, call serialize() */ + /** Default op() calls serializable() free function */ template <class T> - typename boost::enable_if<boost::is_class<T>, Derived&>::type - operator()(const T& t) { - assert(!Derived::IS_DECODER); // We won't modify the value. - // const_cast so we don't need 2 serialize() members for every class. - const_cast<T&>(t).serialize(self()); - return self(); + Derived& operator()(const T& t) { + serializable(const_cast<T&>(t)).serialize(self()); return self(); } - template <class T, bool=false> struct Split { - Split(Derived& s, T& t) { t.encode(s); } - }; - - template <class T> struct Split<T,true> { - Split(Derived& s, T& t) { t.decode(s); } - }; - /** - * Called by classes that want to receive separate - * encode()/decode() calls. - */ + /** Split serialize() into encode()/decode() */ template <class T> - void split(T& t) { Split<T, Derived::IS_DECODER>(self(),t); } - + Derived& split(const T& t) { t.encode(self()); return self(); } + private: Derived& self() { return *static_cast<Derived*>(this); } }; +template <class Derived> class Decoder { + public: + typedef Derived& result_type; // unary functor requirement. + + /** Default op() calls serializable() free function */ + template <class T> + Derived& operator()(T& t) { + serializable(t).serialize(self()); return self(); + } + /** Split serialize() into encode()/decode() */ + template <class T> + Derived& split(T& t) { t.decode(self()); return self(); } + + private: + Derived& self() { return *static_cast<Derived*>(this); } +}; +/** Serialize a type by converting it to/from another type */ +template <class Type, class AsType> +struct SerializeAs { + Type& value; + SerializeAs(Type & t) : value(t) {} + template <class S> void serialize(S& s) { s.split(*this); } + template <class S> void encode(S& s) const { s(AsType(value)); } + template <class S> void decode(S& s) { AsType x; s(x); value=x; } +}; -} // namespace qpid +}} // namespace qpid::serialize +// FIXME aconway 2008-03-09: rename to serialize.h +// #endif /*!QPID_SERIALIZER_H*/ |
