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_bool.hpp"
10 #include "persistent_int.hpp"
11 #include "persistent_xref.hpp"
16 ////////////////////////////////////////////////////////////////////////////////
18 template<typename T, typename D>
19 void dump_ntree_r(dump_context& context,
21 const TYPENAME ntree<T>::const_iterator& node,
23 throw(persistent_dump_failed)
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);
39 template<typename T, typename D>
40 void dump_ntree(dump_context& context,
43 throw(persistent_dump_failed)
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
54 dump_ntree_r<T,D>(context,tree,tree.root(),dump_fn);
57 ////////////////////////////////////////////////////////////////////////////////
59 template<typename T, typename R>
60 void restore_ntree_r(restore_context& context,
62 const TYPENAME ntree<T>::iterator& node,
64 throw(persistent_restore_failed)
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++)
80 typename ntree<T>::iterator child = tree.insert(node,i,T());
81 restore_ntree_r<T,R>(context,tree,child,restore_fn);
85 template<typename T, typename R>
86 void restore_ntree(restore_context& context,
89 throw(persistent_restore_failed)
92 // restore the tree's magic key and map it onto the tree's address
93 // this is used in the persistence of iterators
95 restore_unsigned(context,magic);
96 context.pointer_add(magic,&tree);
97 // now restore the contents
99 restore_bool(context, empty);
102 typename ntree<T>::iterator node = tree.insert(T());
103 restore_ntree_r<T,R>(context,tree,node,restore_fn);
107 ////////////////////////////////////////////////////////////////////////////////
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)
115 dump_xref(context,data.owner());
116 dump_xref(context,data.node());
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)
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);
132 ////////////////////////////////////////////////////////////////////////////////
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)
139 dump_ntree_iterator(context,data.iterator());
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)
147 ntree_iterator<T,TRef,TPtr> iterator;
148 restore_ntree_iterator(context,iterator);
149 data = ntree_prefix_iterator<T,TRef,TPtr>(iterator);
152 ////////////////////////////////////////////////////////////////////////////////
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)
159 dump_ntree_iterator(context,data.iterator());
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)
167 ntree_iterator<T,TRef,TPtr> iterator;
168 restore_ntree_iterator(context,iterator);
169 data = ntree_postfix_iterator<T,TRef,TPtr>(iterator);
172 ////////////////////////////////////////////////////////////////////////////////
174 } // end namespace stlplus