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_smart_ptr(dump_context& context, const smart_ptr<T>& data,
22 throw(persistent_dump_failed)
24 // similar to the simple pointer routines, but use the address of the holder to tell which objects are aliases
25 // Many smart pointers can point to the same object.
26 // I could have used the address of the object to differentiate,
27 // but that would not have differentiated between different null smart pointers
28 // so I use the address of the substructure to differentiate between different objects.
29 // get a magic key for the substructure - this also returns a flag saying whether its been seen before
30 std::pair<bool,unsigned> mapping = context.pointer_map(data._handle());
32 dump_unsigned(context,mapping.second);
33 // dump the contents but only if this is the first time this object has been seen
34 // use the existing routines for ordinary pointers to dump the contents
36 dump_pointer(context,data.pointer(),dump_element);
39 template<typename T, typename RE>
40 void restore_smart_ptr(restore_context& context, smart_ptr<T>& data,
42 throw(persistent_restore_failed)
44 // get the old substructure magic key
46 restore_unsigned(context,magic);
47 // lookup this magic number to see if we have seen this already
48 std::pair<bool,void*> mapping = context.pointer_map(magic);
51 // this holder has already been restored
52 // dealias the existing holder and replace it with the seen-before holder to make this object an alias of it
53 data._make_alias((smart_ptr_holder<T>*)mapping.second);
57 // this is the first contact with this holder
58 // make sure this smart pointer is unique to prevent side-effects
60 // map the magic key onto this structure's holder
61 // do this before restoring the object so that self-referential structures restore correctly
62 context.pointer_add(magic,data._handle());
63 // now restore the object
65 restore_pointer(context,value,restore_element);
70 ////////////////////////////////////////////////////////////////////////////////
71 // smart_ptr_clone using callbacks
74 void dump_smart_ptr_clone_callback(dump_context& context, const smart_ptr_clone<T>& data)
75 throw(persistent_dump_failed)
77 // similar to the simple pointer routines, but use the address of the holder to tell which objects are aliases
78 // Many smart pointers can point to the same object.
79 // I could have used the address of the object to differentiate,
80 // but that would not have differentiated between different null smart pointers
81 // so I use the address of the substructure to differentiate between different objects.
82 // get a magic key for the substructure - this also returns a flag saying whether its been seen before
83 std::pair<bool,unsigned> mapping = context.pointer_map(data._handle());
85 dump_unsigned(context,mapping.second);
86 // dump the contents but only if this is the first time this object has been seen
87 // use the existing routines for ordinary pointers to dump the contents
89 dump_callback(context,data.pointer());
93 void restore_smart_ptr_clone_callback(restore_context& context, smart_ptr_clone<T>& data)
94 throw(persistent_restore_failed)
96 // get the old substructure magic key
98 restore_unsigned(context,magic);
99 // lookup this magic number to see if we have seen this already
100 std::pair<bool,void*> mapping = context.pointer_map(magic);
103 // this holder has already been restored
104 // dealias the existing holder and replace it with the seen-before holder to make this object an alias of it
105 data._make_alias((smart_ptr_holder<T>*)mapping.second);
109 // this is the first contact with this holder
110 // make sure this smart pointer is unique to prevent side-effects
112 // map the magic key onto this structure's holder
113 // do this before restoring the object so that self-referential structures restore correctly
114 context.pointer_add(magic,data._handle());
115 // now restore the object
117 restore_callback(context,value);
122 ////////////////////////////////////////////////////////////////////////////////
123 // smart_ptr_clone using interface
126 void dump_smart_ptr_clone_interface(dump_context& context, const smart_ptr_clone<T>& data)
127 throw(persistent_dump_failed)
129 // similar to the simple pointer routines, but use the address of the holder to tell which objects are aliases
130 // Many smart pointers can point to the same object.
131 // I could have used the address of the object to differentiate,
132 // but that would not have differentiated between different null smart pointers
133 // so I use the address of the substructure to differentiate between different objects.
134 // get a magic key for the substructure - this also returns a flag saying whether its been seen before
135 std::pair<bool,unsigned> mapping = context.pointer_map(data._handle());
136 // dump the magic key
137 dump_unsigned(context,mapping.second);
138 // dump the contents but only if this is the first time this object has been seen
139 // use the existing routines for ordinary pointers to dump the contents
141 dump_interface(context,data.pointer());
145 void restore_smart_ptr_clone_interface(restore_context& context, smart_ptr_clone<T>& data)
146 throw(persistent_restore_failed)
148 // get the old substructure magic key
150 restore_unsigned(context,magic);
151 // lookup this magic number to see if we have seen this already
152 std::pair<bool,void*> mapping = context.pointer_map(magic);
155 // this holder has already been restored
156 // dealias the existing holder and replace it with the seen-before holder to make this object an alias of it
157 data._make_alias((smart_ptr_holder<T>*)mapping.second);
161 // this is the first contact with this holder
162 // make sure this smart pointer is unique to prevent side-effects
164 // map the magic key onto this structure's holder
165 // do this before restoring the object so that self-referential structures restore correctly
166 context.pointer_add(magic,data._handle());
167 // now restore the object
169 restore_interface(context,value);
174 ////////////////////////////////////////////////////////////////////////////////
176 } // end namespace stlplus