Features include:
For objects of a class to be savable with this library the class must inherit SavableState which in turn inherits DescribedClass. SavableState must be inherited with the virtual qualifier. Also, a constructor taking a StateIn& argument and a save_data_state(StateOut&) member must be provided. If the class has virtual base classes other than SavableState, then a save_vbase_state(StateOut&) member must also be provided.
class C: virtual public SavableState { private: int i; public: C(StateIn&); void save_data_state(StateOut&); };
Here is the implementation for the above:
static ClassDesc C_cd(typeid(C),"C",1,"virtual public SavableState", 0, 0, create<C>); void C::save_data_state(StateOut&so) { so.put(i); } C::C(StateIn&si): SavableState(si) { si.get(i); }
class C: public B { private: int i; public: C(StateIn&); void save_data_state(StateOut&); };
Here is the implementation for the above:
static ClassDesc C_cd(typeid(C),"C",1,"public B", 0, 0, create<C>); void C::save_data_state(StateOut&so) { B::save_data_state(so); so.put(i); } C::C(StateIn&si): SavableState(si), B(si) { si.get(i); }
Note that B (or one of its parents) virtually inherits from SavableState, so the StateIn constructor for SavableState is called explicitly from the class C constructor.
class C: public B, virtual public E { private: int i; public: C(StateIn&); void save_vbase_state(StateOut&); void save_data_state(StateOut&); };
In this case a save_vbase_state member is required since virtual base classes besides SavableState exist. This member function must save the virtual base classes in the same order that virtual base classes are initialized in constructors. Virtual base classes are initialized before all other base classes in a depth first, left to right transversal of the directed acyclic graph of parent classes. In this example, B and E inherit virtually from SavableState. Here is the implementation:
static ClassDesc C_cd(typeid(C),"C",1,"public B, virtual public E", 0, 0, create<C>); void C::save_vbase_state(StateOut&sio) { SavableState::save_data_state(so); E::save_data_state(sio); } void C::save_data_state(StateOut&so) { B::save_parent_state(so); so.put(i); } C::C(StateIn&si): SavableState(si), B(si), E(si) { si.get(i); }
class C: virtual public SavableState { private: A* ap; // A is also a SavableState public: C(StateIn&); void save_data_state(StateOut&); };
Here is the implementation for the above:
static ClassDesc C_cd(typeid(C),"C",1,"virtual public SavableState", 0, 0, create<C>); void C::save_data_state(StateOut&so) { SavableState::save_state(ap,so); } C::C(StateIn&si): SavableState(si) { ap = dynamic_cast(SavableState::restore_state(si)); }
class C: virtual public SavableState { private: Ref a; // A is also a SavableState public: C(StateIn&); void save_data_state(StateOut&); };
Here is the implementation for the above:
static ClassDesc C_cd(typeid(C),"C",1,"virtual public SavableState", 0, 0, create<C>); void C::save_data_state(StateOut&so) { SavableState::save_state(a.pointer(),so); } C::C(StateIn&si): SavableState(si) { a << SavableState::restore_state(so); }
class C: virtual public SavableState { private: int vecsize; double *vec; int n1; int n2; double **array; public: C(StateIn&); void save_data_state(StateOut&); };
Here is the implementation for the above:
static ClassDesc C_cd(typeid(C),"C",1,"virtual public SavableState", 0, 0, create<C>); void C::save_data_state(StateOut&so) { so.put(vecsize); so.put_array_double(vec,vecsize);
so.put(n1); so.put(n2); for (int i=0; i<n1; i++) { so.put_array_double(array[i],n2); } } C::C(StateIn&si): SavableState(si) { si.get(vecsize); vec = new double[vecsize]; si.get_array_double(vec,vecsize);
si.get(n1); si.get(n2);
array = new double*[n1]; for (int i=0; i<n1; i++) { array[i] = new double[n2]; si.get_array_double(array[i],n2); } }