summaryrefslogtreecommitdiff
path: root/cpp/src/qpid/Serializer.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/qpid/Serializer.h')
-rw-r--r--cpp/src/qpid/Serializer.h131
1 files changed, 85 insertions, 46 deletions
diff --git a/cpp/src/qpid/Serializer.h b/cpp/src/qpid/Serializer.h
index 12bcded0f7..6ff701f346 100644
--- a/cpp/src/qpid/Serializer.h
+++ b/cpp/src/qpid/Serializer.h
@@ -22,82 +22,121 @@
*
*/
-#include <boost/utility/enable_if.hpp>
-#include <boost/type_traits/is_base_and_derived.hpp>
+#include <algorithm>
namespace qpid {
-namespace serialize {
-
-/** Wrapper to pass serializer functors by reference. */
-template <class S> struct SRef {
- S& s;
- SRef(S& ss) : s(ss) {}
- template <class T> typename S::result_type operator()(T& x) { return s(x); }
- template <class T> typename S::result_type operator()(const T& x) { return s(x); }
-};
-
-template <class S> SRef<S> ref(S& s) { return SRef<S>(s); }
-// FIXME aconway 2008-03-03: Document.
-// Encoder/Decoder concept: add op() for primitive types, raw(),
-// op()(Iter, Iter). Note split, encode, decode.
-//
+/**
+ * Overload for types that do not provide a serialize() member.
+ * It should retrun a wrapper holding a reference to t that implements
+ * serialize()
+ */
+template <class T> T& serializable(T& t) { return t; }
-// FIXME aconway 2008-03-09: document - non-intrusive serialzation.
-// Default rule calls member. Enums must provide an override rule.
+/** Serialize std::pair */
+template <class T, class U> struct SerializablePair {
+ std::pair<T,U>& value;
+ SerializablePair(std::pair<T,U>& x) : value(x) {}
+ template <class S> void serialize(S& s) { s(value.first)(value.second); }
+};
-/** Overload for types that do not provide a serialize() member.*/
-template <class T> T& serializable(T& t) { return t; }
+template <class T, class U>
+SerializablePair<T,U> serializable(std::pair<T,U>& p) {
+ return SerializablePair<T,U>(p);
+}
-template <class Derived> class Encoder {
+/**
+ * Base class for all serializers.
+ * Derived serializers inherit from either Encoder or Decoder.
+ * Serializers can be used as functors or static_visitors.
+ */
+template <class Derived> class Serializer {
public:
typedef Derived& result_type; // unary functor requirement.
- /** Default op() calls serializable() free function */
- template <class T>
- Derived& operator()(const T& t) {
+ /** Wrapper functor to pass serializer functors by reference. */
+ template <class S> struct Ref {
+ typedef typename S::result_type result_type;
+ S& s;
+ Ref(S& ss) : s(ss) {}
+ template <class T> result_type operator()(T& x) { return s(x); }
+ template <class T> result_type operator()(const T& x) { return s(x); }
+ };
+
+ /** Reference wrapper to pass serializers by reference,
+ * e.g. to std:: functions that take functors.
+ */
+ template <class S> static Ref<S> ref(S& s) { return Ref<S>(s); }
+
+ /** Generic rule to serialize an iterator range */
+ template <class Iter> Derived& operator()(Iter begin, Iter end) {
+ std::for_each(begin, end, ref(this->self()));
+ return self();
+ }
+
+ protected:
+ Derived& self() { return *static_cast<Derived*>(this); }
+};
+
+/**
+ * Base class for encoders, provides generic encode functions.
+ *
+ * A derived encoder must provide operator(const T&) to encode all
+ * primitive types T.
+ */
+template <class Derived> class EncoderBase : public Serializer<Derived> {
+ public:
+ using Serializer<Derived>::operator();
+ using Serializer<Derived>::self;
+
+ /** Default op() for non-primitive types. */
+ template <class T> Derived& operator()(const T& t) {
serializable(const_cast<T&>(t)).serialize(self()); return self();
}
/** Split serialize() into encode()/decode() */
- template <class T>
- Derived& split(const T& t) { t.encode(self()); return self(); }
-
- private:
- Derived& self() { return *static_cast<Derived*>(this); }
+ template <class T> Derived& split(const T& t) {
+ t.encode(self()); return self();
+ }
};
-template <class Derived> class Decoder {
+/**
+ * Base class for decoders, provides generic decode functions.
+ *
+ * A derived encoder must provide operator(T&) to encode all
+ * primitive types T.
+ */
+template <class Derived> class DecoderBase : public Serializer<Derived> {
public:
- typedef Derived& result_type; // unary functor requirement.
+ using Serializer<Derived>::operator();
+ using Serializer<Derived>::self;
- /** Default op() calls serializable() free function */
- template <class T>
- Derived& operator()(T& t) {
+ /** Default op() for non-primitive types. */
+ 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); }
+ template <class T> Derived& split(T& t) {
+ t.decode(self()); return self();
+ }
};
-/** Serialize a type by converting it to/from another type */
+/** Serialize a type by converting it to/from another type.
+ * To serialize type Foo by converting to/from type Bar create
+ * a serializable() overload like this:
+ *
+ * SerializeAs<Foo,Bar> serializable(Foo& t) { return SerializeAs<Foo,Bar>(t); }
+ */
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; }
+ template <class S> void decode(S& s) { AsType x; s(x); value=Type(x); }
};
-}} // namespace qpid::serialize
+} // namespace qpid
-// FIXME aconway 2008-03-09: rename to serialize.h
-//
#endif /*!QPID_SERIALIZER_H*/