]> Dogcows Code - chaz/yoink/blob - src/stlplus/persistence/persistent_smart_ptr.tpp
testing new non-autotools build system
[chaz/yoink] / src / stlplus / persistence / persistent_smart_ptr.tpp
1 ////////////////////////////////////////////////////////////////////////////////
2
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
7
8 ////////////////////////////////////////////////////////////////////////////////
9 #include "persistent_int.hpp"
10 #include "persistent_pointer.hpp"
11 #include "persistent_callback.hpp"
12 #include "persistent_interface.hpp"
13
14 namespace stlplus
15 {
16
17 ////////////////////////////////////////////////////////////////////////////////
18
19 template<typename T, typename DE>
20 void dump_smart_ptr(dump_context& context, const smart_ptr<T>& data,
21 DE dump_element)
22 throw(persistent_dump_failed)
23 {
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());
31 // dump the magic key
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
35 if (!mapping.first)
36 dump_pointer(context,data.pointer(),dump_element);
37 }
38
39 template<typename T, typename RE>
40 void restore_smart_ptr(restore_context& context, smart_ptr<T>& data,
41 RE restore_element)
42 throw(persistent_restore_failed)
43 {
44 // get the old substructure magic key
45 unsigned magic = 0;
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);
49 if (mapping.first)
50 {
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);
54 }
55 else
56 {
57 // this is the first contact with this holder
58 // make sure this smart pointer is unique to prevent side-effects
59 data.clear_unique();
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
64 T* value = 0;
65 restore_pointer(context,value,restore_element);
66 data.set(value);
67 }
68 }
69
70 ////////////////////////////////////////////////////////////////////////////////
71 // smart_ptr_clone using callbacks
72
73 template<typename T>
74 void dump_smart_ptr_clone_callback(dump_context& context, const smart_ptr_clone<T>& data)
75 throw(persistent_dump_failed)
76 {
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());
84 // dump the magic key
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
88 if (!mapping.first)
89 dump_callback(context,data.pointer());
90 }
91
92 template<typename T>
93 void restore_smart_ptr_clone_callback(restore_context& context, smart_ptr_clone<T>& data)
94 throw(persistent_restore_failed)
95 {
96 // get the old substructure magic key
97 unsigned magic = 0;
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);
101 if (mapping.first)
102 {
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);
106 }
107 else
108 {
109 // this is the first contact with this holder
110 // make sure this smart pointer is unique to prevent side-effects
111 data.clear_unique();
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
116 T* value = 0;
117 restore_callback(context,value);
118 data.set(value);
119 }
120 }
121
122 ////////////////////////////////////////////////////////////////////////////////
123 // smart_ptr_clone using interface
124
125 template<typename T>
126 void dump_smart_ptr_clone_interface(dump_context& context, const smart_ptr_clone<T>& data)
127 throw(persistent_dump_failed)
128 {
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
140 if (!mapping.first)
141 dump_interface(context,data.pointer());
142 }
143
144 template<typename T>
145 void restore_smart_ptr_clone_interface(restore_context& context, smart_ptr_clone<T>& data)
146 throw(persistent_restore_failed)
147 {
148 // get the old substructure magic key
149 unsigned magic = 0;
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);
153 if (mapping.first)
154 {
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);
158 }
159 else
160 {
161 // this is the first contact with this holder
162 // make sure this smart pointer is unique to prevent side-effects
163 data.clear_unique();
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
168 T* value = 0;
169 restore_interface(context,value);
170 data.set(value);
171 }
172 }
173
174 ////////////////////////////////////////////////////////////////////////////////
175
176 } // end namespace stlplus
This page took 0.037825 seconds and 4 git commands to generate.