+template<> struct Protocol::Traits<bool>: BasicTraits<bool, 'B'> { };
+template<> struct Protocol::Traits<std::int8_t>: BasicTraits<std::int8_t, 'I'> { };
+template<> struct Protocol::Traits<std::uint8_t>: BasicTraits<std::uint8_t, 'U'> { };
+template<> struct Protocol::Traits<std::int16_t>: BasicTraits<std::int16_t, 'I'> { };
+template<> struct Protocol::Traits<std::uint16_t>: BasicTraits<std::uint16_t, 'U'> { };
+template<> struct Protocol::Traits<std::int32_t>: BasicTraits<std::int32_t, 'I'> { };
+template<> struct Protocol::Traits<std::uint32_t>: BasicTraits<std::uint32_t, 'U'> { };
+template<> struct Protocol::Traits<std::int64_t>: BasicTraits<std::int64_t, 'I'> { };
+template<> struct Protocol::Traits<std::uint64_t>: BasicTraits<std::uint64_t, 'U'> { };
+template<> struct Protocol::Traits<float>: BasicTraits<float, 'F'> { };
+template<> struct Protocol::Traits<double>: BasicTraits<double, 'F'> { };
+
+template<> struct Protocol::Traits<std::string>
+{
+ static const std::uint16_t signature = 'S';
+ typedef StringSerializer Serializer;
+};
+
+template<typename T>
+struct Protocol::Traits<std::vector<T> >
+{
+ static const std::uint16_t signature = 'A';
+ typedef ArraySerializer<std::vector<T> > Serializer;
+};
+
+
+
+template<typename C, typename S>
+Protocol::CompoundDef<C, S>::CompoundDef(const S &s):
+ serializer(s)
+{ }
+
+template<typename C, typename S>
+std::string Protocol::CompoundDef<C, S>::describe() const
+{
+ return "{"+serializer.describe()+"}";
+}
+
+template<typename C, typename S>
+char *Protocol::CompoundDef<C, S>::serialize(const C &com, char *buf, char *end) const
+{
+ return serializer.serialize(com, buf, end);
+}
+
+template<typename C, typename S>
+const char *Protocol::CompoundDef<C, S>::deserialize(C &com, const char *buf, const char *end) const
+{
+ return serializer.deserialize(com, buf, end);
+}
+
+
+template<typename A>
+Protocol::ArraySerializer<A>::ArraySerializer(const Protocol &proto):
+ length_serializer(proto),
+ element_serializer(proto)
+{ }
+
+template<typename A>
+std::string Protocol::ArraySerializer<A>::describe() const
+{
+ return "["+element_serializer.describe()+"]";
+}
+
+template<typename A>
+char *Protocol::ArraySerializer<A>::serialize(const A &array, char *buf, char *end) const
+{
+ buf = length_serializer.serialize(array.size(), buf, end);
+ for(typename A::const_iterator i=array.begin(); i!=array.end(); ++i)
+ buf = element_serializer.serialize(*i, buf, end);
+ return buf;
+}
+
+template<typename A>
+const char *Protocol::ArraySerializer<A>::deserialize(A &array, const char *buf, const char *end) const
+{
+ std::uint16_t length;
+ buf = length_serializer.deserialize(length, buf, end);
+ array.resize(length);
+ for(unsigned i=0; i<length; ++i)
+ buf = element_serializer.deserialize(array[i], buf, end);
+ return buf;
+}
+
+
+template<typename C>
+Protocol::CompoundSerializer<C>::CompoundSerializer(const Protocol &proto):
+ def(proto.get_packet_by_class<C>().get_compound())
+{ }
+
+template<typename C>
+char *Protocol::CompoundSerializer<C>::serialize(const C &com, char *buf, char *end) const
+{
+ return def.serialize(com, buf, end);
+}
+
+template<typename C>
+const char *Protocol::CompoundSerializer<C>::deserialize(C &com, const char *buf, const char *end) const
+{
+ return def.deserialize(com, buf, end);
+}
+
+
+template<typename P, typename Head, typename S>
+Protocol::Serializer<P, Head, S>::Serializer(const Head &h, Pointer p, const Protocol &proto):
+ Head(h),
+ ptr(p),
+ ser(proto)
+{ }
+
+template<typename P, typename Head, typename S>
+std::string Protocol::Serializer<P, Head, S>::describe() const
+{
+ return Head::describe()+ser.describe();
+}
+
+template<typename P, typename Head, typename S>
+char *Protocol::Serializer<P, Head, S>::serialize(const P &pkt, char *buf, char *end) const
+{
+ buf = Head::serialize(pkt, buf, end);
+ return ser.serialize(pkt.*ptr, buf, end);
+}
+
+template<typename P, typename Head, typename S>
+const char *Protocol::Serializer<P, Head, S>::deserialize(P &pkt, const char *buf, const char *end) const
+{
+ buf = Head::deserialize(pkt, buf, end);
+ return ser.deserialize(pkt.*ptr, buf, end);
+}
+
+
+template<typename P>
+Protocol::PacketTypeDef<P>::PacketTypeDef(unsigned i):
+ PacketDefBase(i),
+ compound(new CompoundDef<P, NullSerializer<P> >(NullSerializer<P>()))
+{ }
+
+template<typename P>
+Protocol::PacketTypeDef<P>::~PacketTypeDef()
+{
+ delete compound;
+}
+
+template<typename P>
+template<typename S>
+void Protocol::PacketTypeDef<P>::set_serializer(const S &ser)
+{
+ delete compound;
+ compound = new CompoundDef<P, S>(ser);
+}
+
+template<typename P>
+char *Protocol::PacketTypeDef<P>::serialize(const P &pkt, char *buf, char *end) const
+{
+ return compound->serialize(pkt, buf, end);
+}
+