1 ////////////////////////////////////////////////////////////////////////////////
3 // Author: Andy Rushton
4 // Copyright: (c) Southampton University 1999-2004
5 // (c) Andy Rushton 2004-2009
6 // License: BSD License, see ../docs/license.html
8 ////////////////////////////////////////////////////////////////////////////////
9 #include "persistent_int.hpp"
10 #include "persistent_pointer.hpp"
11 #include "persistent_callback.hpp"
12 #include "persistent_interface.hpp"
17 ////////////////////////////////////////////////////////////////////////////////
19 template<typename T, typename DE>
20 void dump_simple_ptr(dump_context& context, const simple_ptr<T>& data,
22 throw(persistent_dump_failed)
24 // Many smart pointers can point to the same object.
25 // I could have used the address of the object to differentiate,
26 // but that would not have differentiated between different null smart pointers
27 // so I use the address of the count to differentiate between different objects.
28 // get a magic key for the substructure - this also returns a flag saying whether its been seen before
29 std::pair<bool,unsigned> mapping = context.pointer_map(data._count());
30 // dump the magic key for the count
31 dump_unsigned(context,mapping.second);
32 // dump the contents always - this is because I need to rely on the pointer routines dumping a second magic key
33 // use the existing routines for ordinary pointers to dump the contents
34 dump_pointer(context,data._pointer(),dump_element);
37 template<typename T, typename RE>
38 void restore_simple_ptr(restore_context& context, simple_ptr<T>& data,
40 throw(persistent_restore_failed)
42 // get the old counter magic key
44 restore_unsigned(context,magic);
45 // lookup this magic number to see if we have seen this already
46 std::pair<bool,void*> mapping = context.pointer_map(magic);
49 // this holder has already been restored
50 // now restore the object and rely on the pointer routines to return the existing object
52 restore_pointer(context,value,restore_element);
53 // dealias the existing holder and replace it with the seen-before holder to make this object an alias of it
54 data._make_alias(value, (unsigned*)mapping.second);
58 // this is the first contact with this holder
59 // make sure this smart pointer is unique to prevent side-effects
61 // map the magic key onto this structure's holder
62 // do this before restoring the object so that self-referential structures restore correctly
63 context.pointer_add(magic,data._count());
64 // now restore the object
66 restore_pointer(context,value,restore_element);
67 // and add it to the pointer
72 ////////////////////////////////////////////////////////////////////////////////
73 // simple_ptr_clone using callbacks
76 void dump_simple_ptr_clone_callback(dump_context& context, const simple_ptr_clone<T>& data)
77 throw(persistent_dump_failed)
79 std::pair<bool,unsigned> mapping = context.pointer_map(data._count());
80 dump_unsigned(context,mapping.second);
81 dump_callback(context,data._pointer());
85 void restore_simple_ptr_clone_callback(restore_context& context, simple_ptr_clone<T>& data)
86 throw(persistent_restore_failed)
89 restore_unsigned(context,magic);
90 std::pair<bool,void*> mapping = context.pointer_map(magic);
94 restore_callback(context,value);
95 data._make_alias(value, (unsigned*)mapping.second);
100 context.pointer_add(magic,data._count());
102 restore_callback(context,value);
107 ////////////////////////////////////////////////////////////////////////////////
108 // simple_ptr_clone using interface
111 void dump_simple_ptr_clone_interface(dump_context& context, const simple_ptr_clone<T>& data)
112 throw(persistent_dump_failed)
114 std::pair<bool,unsigned> mapping = context.pointer_map(data._count());
115 dump_unsigned(context,mapping.second);
116 dump_interface(context,data._pointer());
120 void restore_simple_ptr_clone_interface(restore_context& context, simple_ptr_clone<T>& data)
121 throw(persistent_restore_failed)
124 restore_unsigned(context,magic);
125 std::pair<bool,void*> mapping = context.pointer_map(magic);
129 restore_interface(context,value);
130 data._make_alias(value, (unsigned*)mapping.second);
135 context.pointer_add(magic,data._count());
137 restore_interface(context,value);
142 ////////////////////////////////////////////////////////////////////////////////
144 } // end namespace stlplus