--- /dev/null
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+// Author: Andy Rushton\r
+// Copyright: (c) Southampton University 1999-2004\r
+// (c) Andy Rushton 2004-2009\r
+// License: BSD License, see ../docs/license.html\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+#include "persistent_bool.hpp"\r
+#include "persistent_int.hpp"\r
+#include "persistent_xref.hpp"\r
+\r
+namespace stlplus\r
+{\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+ template<typename T, typename D>\r
+ void dump_ntree_r(dump_context& context,\r
+ const ntree<T>& tree, \r
+ const TYPENAME ntree<T>::const_iterator& node,\r
+ D dump_fn)\r
+ throw(persistent_dump_failed)\r
+ {\r
+ // the magic key of the ntree_node is dumped as well as the contents - this is used in iterator persistence\r
+ std::pair<bool,unsigned> node_mapping = context.pointer_map(node.node());\r
+ if (node_mapping.first) throw persistent_dump_failed("ntree: already dumped this node");\r
+ dump_unsigned(context,node_mapping.second);\r
+ // now dump the contents\r
+ dump_fn(context,*node);\r
+ // dump the number of children\r
+ unsigned children = tree.children(node);\r
+ dump_unsigned(context,children);\r
+ // recurse on the children\r
+ for (unsigned i = 0; i < children; i++)\r
+ dump_ntree_r<T,D>(context,tree,tree.child(node,i),dump_fn);\r
+ }\r
+\r
+ template<typename T, typename D>\r
+ void dump_ntree(dump_context& context,\r
+ const ntree<T>& tree,\r
+ D dump_fn)\r
+ throw(persistent_dump_failed)\r
+ {\r
+ // dump a magic key to the address of the tree for use in persistence of iterators\r
+ // and register it as a dumped address\r
+ std::pair<bool,unsigned> mapping = context.pointer_map(&tree);\r
+ if (mapping.first) throw persistent_dump_failed("ntree: already dumped this tree");\r
+ dump_unsigned(context,mapping.second);\r
+ // now dump the tree contents - start with a flag to indicate whether the tree is empty\r
+ dump_bool(context, tree.empty());\r
+ // now recursively dump the contents\r
+ if (!tree.empty())\r
+ dump_ntree_r<T,D>(context,tree,tree.root(),dump_fn);\r
+ }\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+ template<typename T, typename R>\r
+ void restore_ntree_r(restore_context& context,\r
+ ntree<T>& tree,\r
+ const TYPENAME ntree<T>::iterator& node,\r
+ R restore_fn)\r
+ throw(persistent_restore_failed)\r
+ {\r
+ // restore the node magic key, check whether it has been used before and add it to the set of known addresses\r
+ unsigned node_magic = 0;\r
+ restore_unsigned(context,node_magic);\r
+ std::pair<bool,void*> node_mapping = context.pointer_map(node_magic);\r
+ if (node_mapping.first) throw persistent_restore_failed("ntree: restored this tree node already");\r
+ context.pointer_add(node_magic,node.node());\r
+ // now restore the node contents\r
+ restore_fn(context,*node);\r
+ // restore the number of children\r
+ unsigned children = 0;\r
+ restore_unsigned(context,children);\r
+ // recurse on each child\r
+ for (unsigned i = 0; i < children; i++)\r
+ {\r
+ typename ntree<T>::iterator child = tree.insert(node,i,T());\r
+ restore_ntree_r<T,R>(context,tree,child,restore_fn);\r
+ }\r
+ }\r
+\r
+ template<typename T, typename R>\r
+ void restore_ntree(restore_context& context,\r
+ ntree<T>& tree,\r
+ R restore_fn)\r
+ throw(persistent_restore_failed)\r
+ {\r
+ tree.erase();\r
+ // restore the tree's magic key and map it onto the tree's address\r
+ // this is used in the persistence of iterators\r
+ unsigned magic = 0;\r
+ restore_unsigned(context,magic);\r
+ context.pointer_add(magic,&tree);\r
+ // now restore the contents\r
+ bool empty = true;\r
+ restore_bool(context, empty);\r
+ if (!empty)\r
+ {\r
+ typename ntree<T>::iterator node = tree.insert(T());\r
+ restore_ntree_r<T,R>(context,tree,node,restore_fn);\r
+ }\r
+ }\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+ template<typename T, typename TRef, typename TPtr>\r
+ void dump_ntree_iterator(dump_context& context,\r
+ const ntree_iterator<T,TRef,TPtr>& data) \r
+ throw(persistent_dump_failed)\r
+ {\r
+ data.assert_valid();\r
+ dump_xref(context,data.owner());\r
+ dump_xref(context,data.node());\r
+ }\r
+\r
+ template<typename T, typename TRef, typename TPtr>\r
+ void restore_ntree_iterator(restore_context& context,\r
+ ntree_iterator<T,TRef,TPtr>& data)\r
+ throw(persistent_restore_failed)\r
+ {\r
+ const ntree<T>* owner = 0;\r
+ ntree_node<T>* node = 0;\r
+ restore_xref(context,owner);\r
+ restore_xref(context,node);\r
+ data = ntree_iterator<T,TRef,TPtr>(node->m_master);\r
+ data.assert_valid(owner);\r
+ }\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+ template<typename T, typename TRef, typename TPtr>\r
+ void dump_ntree_prefix_iterator(dump_context& context,\r
+ const ntree_prefix_iterator<T,TRef,TPtr>& data)\r
+ throw(persistent_dump_failed)\r
+ {\r
+ dump_ntree_iterator(context,data.iterator());\r
+ }\r
+\r
+ template<typename T, typename TRef, typename TPtr>\r
+ void restore_ntree_prefix_iterator(restore_context& context,\r
+ ntree_prefix_iterator<T,TRef,TPtr>& data)\r
+ throw(persistent_restore_failed)\r
+ {\r
+ ntree_iterator<T,TRef,TPtr> iterator;\r
+ restore_ntree_iterator(context,iterator);\r
+ data = ntree_prefix_iterator<T,TRef,TPtr>(iterator);\r
+ }\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+ template<typename T, typename TRef, typename TPtr>\r
+ void dump_ntree_postfix_iterator(dump_context& context,\r
+ const ntree_postfix_iterator<T,TRef,TPtr>& data)\r
+ throw(persistent_dump_failed)\r
+ {\r
+ dump_ntree_iterator(context,data.iterator());\r
+ }\r
+\r
+ template<typename T, typename TRef, typename TPtr>\r
+ void restore_ntree_postfix_iterator(restore_context& context,\r
+ ntree_postfix_iterator<T,TRef,TPtr>& data)\r
+ throw(persistent_restore_failed)\r
+ {\r
+ ntree_iterator<T,TRef,TPtr> iterator;\r
+ restore_ntree_iterator(context,iterator);\r
+ data = ntree_postfix_iterator<T,TRef,TPtr>(iterator);\r
+ }\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+} // end namespace stlplus\r