]> Dogcows Code - chaz/yoink/blobdiff - src/stlplus/persistence/persistent_ntree.tpp
testing new non-autotools build system
[chaz/yoink] / src / stlplus / persistence / persistent_ntree.tpp
diff --git a/src/stlplus/persistence/persistent_ntree.tpp b/src/stlplus/persistence/persistent_ntree.tpp
new file mode 100644 (file)
index 0000000..d50ba17
--- /dev/null
@@ -0,0 +1,174 @@
+////////////////////////////////////////////////////////////////////////////////\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
This page took 0.025061 seconds and 4 git commands to generate.