]> Dogcows Code - chaz/yoink/blob - src/stlplus/persistence/persistent_simple_ptr.tpp
testing new non-autotools build system
[chaz/yoink] / src / stlplus / persistence / persistent_simple_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_simple_ptr(dump_context& context, const simple_ptr<T>& data,
21 DE dump_element)
22 throw(persistent_dump_failed)
23 {
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);
35 }
36
37 template<typename T, typename RE>
38 void restore_simple_ptr(restore_context& context, simple_ptr<T>& data,
39 RE restore_element)
40 throw(persistent_restore_failed)
41 {
42 // get the old counter magic key
43 unsigned magic = 0;
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);
47 if (mapping.first)
48 {
49 // this holder has already been restored
50 // now restore the object and rely on the pointer routines to return the existing object
51 T* value = 0;
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);
55 }
56 else
57 {
58 // this is the first contact with this holder
59 // make sure this smart pointer is unique to prevent side-effects
60 data.clear_unique();
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
65 T* value = 0;
66 restore_pointer(context,value,restore_element);
67 // and add it to the pointer
68 data.set(value);
69 }
70 }
71
72 ////////////////////////////////////////////////////////////////////////////////
73 // simple_ptr_clone using callbacks
74
75 template<typename T>
76 void dump_simple_ptr_clone_callback(dump_context& context, const simple_ptr_clone<T>& data)
77 throw(persistent_dump_failed)
78 {
79 std::pair<bool,unsigned> mapping = context.pointer_map(data._count());
80 dump_unsigned(context,mapping.second);
81 dump_callback(context,data._pointer());
82 }
83
84 template<typename T>
85 void restore_simple_ptr_clone_callback(restore_context& context, simple_ptr_clone<T>& data)
86 throw(persistent_restore_failed)
87 {
88 unsigned magic = 0;
89 restore_unsigned(context,magic);
90 std::pair<bool,void*> mapping = context.pointer_map(magic);
91 if (mapping.first)
92 {
93 T* value = 0;
94 restore_callback(context,value);
95 data._make_alias(value, (unsigned*)mapping.second);
96 }
97 else
98 {
99 data.clear_unique();
100 context.pointer_add(magic,data._count());
101 T* value = 0;
102 restore_callback(context,value);
103 data.set(value);
104 }
105 }
106
107 ////////////////////////////////////////////////////////////////////////////////
108 // simple_ptr_clone using interface
109
110 template<typename T>
111 void dump_simple_ptr_clone_interface(dump_context& context, const simple_ptr_clone<T>& data)
112 throw(persistent_dump_failed)
113 {
114 std::pair<bool,unsigned> mapping = context.pointer_map(data._count());
115 dump_unsigned(context,mapping.second);
116 dump_interface(context,data._pointer());
117 }
118
119 template<typename T>
120 void restore_simple_ptr_clone_interface(restore_context& context, simple_ptr_clone<T>& data)
121 throw(persistent_restore_failed)
122 {
123 unsigned magic = 0;
124 restore_unsigned(context,magic);
125 std::pair<bool,void*> mapping = context.pointer_map(magic);
126 if (mapping.first)
127 {
128 T* value = 0;
129 restore_interface(context,value);
130 data._make_alias(value, (unsigned*)mapping.second);
131 }
132 else
133 {
134 data.clear_unique();
135 context.pointer_add(magic,data._count());
136 T* value = 0;
137 restore_interface(context,value);
138 data.set(value);
139 }
140 }
141
142 ////////////////////////////////////////////////////////////////////////////////
143
144 } // end namespace stlplus
This page took 0.034974 seconds and 4 git commands to generate.