Templates
The Serialization package can stream objects of template classes and ordinary classes. It can also stream a template class that uses a base class pointer (polymorphism and templates). Although template classes don’t often inherit from a base class, this technique is useful for situations such as storing a mixed set of primitive types together in a collection.
Serialization support for templates requires use of special macro RW_DEFINE_STREAMABLE_TEMPLATE_POINTER() because the normal RW_DEFINE_STREAMABLE_POINTER() and RW_DEFINE_STREAMABLE_AS_SELF() macros don’t work with template classes. Calls to the RW_DEFINE_STREAMABLE_AS_BASE() macro must be placed in a source file for each type of pointer that will be used to stream an object of that template class.
The RW_DEFINE_STREAMABLE_TEMPLATE_POINTER() macro cannot be called with a template class directly; it must be called using typedefs for specific instantiations of the template. At present, only templates with a single parameter are supported, and the macro uses the name T for that parameter.
In the next example, a residential property has one or more pet_door objects parameterized by the type of pet: t_pet_door<class kind_of_pet>.
// examples\serial\template\pet_door.h
struct pet_door { // 1
RW_DECLARE_VIRTUAL_STREAM_FNS(pet_door)
public:
virtual ~pet_door() { }
};
template <typename T>
struct t_pet_door : public pet_door {
RW_DECLARE_VIRTUAL_STREAM_FNS(t_pet_door<T>) // 2
public:
virtual ~t_pet_door() { }
};
struct cat { }; // 3
struct monkey { };
// Allow object streaming of residential class
RW_DECLARE_STREAMABLE_AS_SELF(pet_door)
RW_DECLARE_STREAMABLE_POINTER(pet_door)
// Typedefs to allow streaming by reference
typedef t_pet_door<cat> cat_door; // 4
typedef t_pet_door<monkey> monkey_door;
RW_DECLARE_STREAMABLE_AS_SELF(cat_door)
RW_DECLARE_STREAMABLE_AS_BASE(cat_door, pet_door)
RW_DECLARE_STREAMABLE_POINTER(cat_door)
RW_DECLARE_STREAMABLE_AS_SELF(monkey_door)
RW_DECLARE_STREAMABLE_AS_BASE(monkey_door, pet_door)
RW_DECLARE_STREAMABLE_POINTER(monkey_door)
RW_DEFINE_STREAMABLE_TEMPLATE_POINTER(t_pet_door) // 5
template <class T> // 6
RW_BEGIN_STREAM_CONTENTS(t_pet_door<T>)
{
RW_STREAM_PARENT(pet_door)
}
RW_END_STREAM_CONTENTS
The following source code for pet_door is from: examples\serial\template\pet_door.cpp.
RW_BEGIN_STREAM_CONTENTS(pet_door) // 1
RW_END_STREAM_CONTENTS
// Allow object streaming of pet_door class
RW_DEFINE_STREAMABLE_AS_SELF(pet_door)
RW_DEFINE_STREAMABLE_POINTER(pet_door)
// Allow template specialization streaming by reference
RW_DEFINE_STREAMABLE_AS_SELF(cat_door) // 2
RW_DEFINE_STREAMABLE_AS_BASE(cat_door,pet_door)
RW_DEFINE_STREAMABLE_POINTER(cat_door)
RW_DEFINE_STREAMABLE_AS_SELF(monkey_door)
RW_DEFINE_STREAMABLE_AS_BASE(monkey_door,pet_door)
RW_DEFINE_STREAMABLE_POINTER(monkey_door)