]> Dogcows Code - chaz/yoink/blob - src/stlplus/persistence/persistent_ntree.tpp
testing new non-autotools build system
[chaz/yoink] / src / stlplus / persistence / persistent_ntree.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_bool.hpp"
10 #include "persistent_int.hpp"
11 #include "persistent_xref.hpp"
12
13 namespace stlplus
14 {
15
16 ////////////////////////////////////////////////////////////////////////////////
17
18 template<typename T, typename D>
19 void dump_ntree_r(dump_context& context,
20 const ntree<T>& tree,
21 const TYPENAME ntree<T>::const_iterator& node,
22 D dump_fn)
23 throw(persistent_dump_failed)
24 {
25 // the magic key of the ntree_node is dumped as well as the contents - this is used in iterator persistence
26 std::pair<bool,unsigned> node_mapping = context.pointer_map(node.node());
27 if (node_mapping.first) throw persistent_dump_failed("ntree: already dumped this node");
28 dump_unsigned(context,node_mapping.second);
29 // now dump the contents
30 dump_fn(context,*node);
31 // dump the number of children
32 unsigned children = tree.children(node);
33 dump_unsigned(context,children);
34 // recurse on the children
35 for (unsigned i = 0; i < children; i++)
36 dump_ntree_r<T,D>(context,tree,tree.child(node,i),dump_fn);
37 }
38
39 template<typename T, typename D>
40 void dump_ntree(dump_context& context,
41 const ntree<T>& tree,
42 D dump_fn)
43 throw(persistent_dump_failed)
44 {
45 // dump a magic key to the address of the tree for use in persistence of iterators
46 // and register it as a dumped address
47 std::pair<bool,unsigned> mapping = context.pointer_map(&tree);
48 if (mapping.first) throw persistent_dump_failed("ntree: already dumped this tree");
49 dump_unsigned(context,mapping.second);
50 // now dump the tree contents - start with a flag to indicate whether the tree is empty
51 dump_bool(context, tree.empty());
52 // now recursively dump the contents
53 if (!tree.empty())
54 dump_ntree_r<T,D>(context,tree,tree.root(),dump_fn);
55 }
56
57 ////////////////////////////////////////////////////////////////////////////////
58
59 template<typename T, typename R>
60 void restore_ntree_r(restore_context& context,
61 ntree<T>& tree,
62 const TYPENAME ntree<T>::iterator& node,
63 R restore_fn)
64 throw(persistent_restore_failed)
65 {
66 // restore the node magic key, check whether it has been used before and add it to the set of known addresses
67 unsigned node_magic = 0;
68 restore_unsigned(context,node_magic);
69 std::pair<bool,void*> node_mapping = context.pointer_map(node_magic);
70 if (node_mapping.first) throw persistent_restore_failed("ntree: restored this tree node already");
71 context.pointer_add(node_magic,node.node());
72 // now restore the node contents
73 restore_fn(context,*node);
74 // restore the number of children
75 unsigned children = 0;
76 restore_unsigned(context,children);
77 // recurse on each child
78 for (unsigned i = 0; i < children; i++)
79 {
80 typename ntree<T>::iterator child = tree.insert(node,i,T());
81 restore_ntree_r<T,R>(context,tree,child,restore_fn);
82 }
83 }
84
85 template<typename T, typename R>
86 void restore_ntree(restore_context& context,
87 ntree<T>& tree,
88 R restore_fn)
89 throw(persistent_restore_failed)
90 {
91 tree.erase();
92 // restore the tree's magic key and map it onto the tree's address
93 // this is used in the persistence of iterators
94 unsigned magic = 0;
95 restore_unsigned(context,magic);
96 context.pointer_add(magic,&tree);
97 // now restore the contents
98 bool empty = true;
99 restore_bool(context, empty);
100 if (!empty)
101 {
102 typename ntree<T>::iterator node = tree.insert(T());
103 restore_ntree_r<T,R>(context,tree,node,restore_fn);
104 }
105 }
106
107 ////////////////////////////////////////////////////////////////////////////////
108
109 template<typename T, typename TRef, typename TPtr>
110 void dump_ntree_iterator(dump_context& context,
111 const ntree_iterator<T,TRef,TPtr>& data)
112 throw(persistent_dump_failed)
113 {
114 data.assert_valid();
115 dump_xref(context,data.owner());
116 dump_xref(context,data.node());
117 }
118
119 template<typename T, typename TRef, typename TPtr>
120 void restore_ntree_iterator(restore_context& context,
121 ntree_iterator<T,TRef,TPtr>& data)
122 throw(persistent_restore_failed)
123 {
124 const ntree<T>* owner = 0;
125 ntree_node<T>* node = 0;
126 restore_xref(context,owner);
127 restore_xref(context,node);
128 data = ntree_iterator<T,TRef,TPtr>(node->m_master);
129 data.assert_valid(owner);
130 }
131
132 ////////////////////////////////////////////////////////////////////////////////
133
134 template<typename T, typename TRef, typename TPtr>
135 void dump_ntree_prefix_iterator(dump_context& context,
136 const ntree_prefix_iterator<T,TRef,TPtr>& data)
137 throw(persistent_dump_failed)
138 {
139 dump_ntree_iterator(context,data.iterator());
140 }
141
142 template<typename T, typename TRef, typename TPtr>
143 void restore_ntree_prefix_iterator(restore_context& context,
144 ntree_prefix_iterator<T,TRef,TPtr>& data)
145 throw(persistent_restore_failed)
146 {
147 ntree_iterator<T,TRef,TPtr> iterator;
148 restore_ntree_iterator(context,iterator);
149 data = ntree_prefix_iterator<T,TRef,TPtr>(iterator);
150 }
151
152 ////////////////////////////////////////////////////////////////////////////////
153
154 template<typename T, typename TRef, typename TPtr>
155 void dump_ntree_postfix_iterator(dump_context& context,
156 const ntree_postfix_iterator<T,TRef,TPtr>& data)
157 throw(persistent_dump_failed)
158 {
159 dump_ntree_iterator(context,data.iterator());
160 }
161
162 template<typename T, typename TRef, typename TPtr>
163 void restore_ntree_postfix_iterator(restore_context& context,
164 ntree_postfix_iterator<T,TRef,TPtr>& data)
165 throw(persistent_restore_failed)
166 {
167 ntree_iterator<T,TRef,TPtr> iterator;
168 restore_ntree_iterator(context,iterator);
169 data = ntree_postfix_iterator<T,TRef,TPtr>(iterator);
170 }
171
172 ////////////////////////////////////////////////////////////////////////////////
173
174 } // end namespace stlplus
This page took 0.041108 seconds and 4 git commands to generate.