+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::uint64_t Protocol::CompoundDef<C, S>::get_hash() const
+{
+ return hash_round<64>(serializer.get_hash(), 'C');
+}
+
+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);
+}
+
+
+inline std::uint64_t Protocol::StringSerializer::get_hash() const
+{
+ return Traits<std::string>::signature;
+}
+
+
+template<typename A>
+Protocol::ArraySerializer<A>::ArraySerializer(const Protocol &proto):
+ length_serializer(proto),
+ element_serializer(proto)
+{ }
+
+template<typename A>
+std::uint64_t Protocol::ArraySerializer<A>::get_hash() const
+{
+ return hash_round<64>(element_serializer.get_hash(), 'A');
+}
+
+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(const auto &e: array)
+ buf = element_serializer.serialize(e, 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::uint64_t Protocol::Serializer<P, Head, S>::get_hash() const
+{
+ return hash_update<64>(Head::get_hash(), ser.get_hash());
+}
+
+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);
+}
+