+////////////////////////////////////////////////////////////////////////////////\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_int.hpp"\r
+#include "persistent_xref.hpp"\r
+\r
+namespace stlplus\r
+{\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+ template<typename NT, typename AT, typename DN, typename DA>\r
+ void dump_digraph(dump_context& context, const digraph<NT,AT>& data,\r
+ DN dump_node, DA dump_arc)\r
+ throw(persistent_dump_failed)\r
+ {\r
+ // dump a magic key to the address of the graph for use in persistence of iterators\r
+ // and register it as a dumped address\r
+ std::pair<bool,unsigned> mapping = context.pointer_map(&data);\r
+ if (mapping.first) throw persistent_dump_failed("digraph: already dumped this graph");\r
+ dump_unsigned(context,mapping.second);\r
+ // dump the nodes\r
+ dump_unsigned(context,data.size());\r
+ for (typename digraph<NT,AT>::const_iterator node = data.begin(); node != data.end(); node++)\r
+ {\r
+ // nodes are keyed by the magic key to the node address\r
+ // this key is then used in dumping the arc from/to pointers\r
+ std::pair<bool,unsigned> node_mapping = context.pointer_map(node.node());\r
+ if (node_mapping.first) throw persistent_dump_failed("digraph: already dumped this node");\r
+ dump_unsigned(context,node_mapping.second);\r
+ // finally, dump the node contents\r
+ dump_node(context,*node);\r
+ }\r
+ // dump the arcs\r
+ dump_unsigned(context,data.arc_size());\r
+ for (typename digraph<NT,AT>::const_arc_iterator arc = data.arc_begin(); arc != data.arc_end(); arc++)\r
+ {\r
+ // dump the magic key to the arc address\r
+ // this is used by iterator persistence too\r
+ std::pair<bool,unsigned> arc_mapping = context.pointer_map(arc.node());\r
+ if (arc_mapping.first) throw persistent_dump_failed("digraph: already dumped this arc");\r
+ dump_unsigned(context,arc_mapping.second);\r
+ // now dump the from/to pointers as cross-references\r
+ dump_xref(context,data.arc_from(arc).node());\r
+ dump_xref(context,data.arc_to(arc).node());\r
+ // now dump the arc's data\r
+ dump_arc(context,*arc);\r
+ }\r
+ }\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+ template<typename NT, typename AT, typename RN, typename RA>\r
+ void restore_digraph(restore_context& context, digraph<NT,AT>& data,\r
+ RN restore_node, RA restore_arc)\r
+ throw(persistent_restore_failed)\r
+ {\r
+ data.clear();\r
+ // restore the graph's magic key and map it onto the graph'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,&data);\r
+ // restore the nodes\r
+ unsigned nodes = 0;\r
+ restore_unsigned(context, nodes);\r
+ for (unsigned n = 0; n < nodes; n++)\r
+ {\r
+ unsigned node_magic = 0;\r
+ restore_unsigned(context,node_magic);\r
+ // create a new node and map the magic key onto the new address\r
+ typename digraph<NT,AT>::iterator node = data.insert(NT());\r
+ context.pointer_add(node_magic,node.node());\r
+ // now restore the user's data\r
+ restore_node(context,*node);\r
+ }\r
+ // restore the arcs\r
+ unsigned arcs = 0;\r
+ restore_unsigned(context, arcs);\r
+ for (unsigned a = 0; a < arcs; a++)\r
+ {\r
+ unsigned arc_magic = 0;\r
+ restore_unsigned(context,arc_magic);\r
+ // restore the from and to cross-references\r
+ digraph_node<NT,AT>* from = 0;\r
+ digraph_node<NT,AT>* to = 0;\r
+ restore_xref(context,from);\r
+ restore_xref(context,to);\r
+ // create an arc with these from/to pointers\r
+ digraph_arc_iterator<NT,AT,AT&,AT*> arc = \r
+ data.arc_insert(digraph_iterator<NT,AT,NT&,NT*>(from), \r
+ digraph_iterator<NT,AT,NT&,NT*>(to));\r
+ context.pointer_add(arc_magic,arc.node());\r
+ // restore the user data\r
+ restore_arc(context,*arc);\r
+ }\r
+ }\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+ template<typename NT, typename AT, typename NRef, typename NPtr>\r
+ void dump_digraph_iterator(dump_context& context, \r
+ const digraph_iterator<NT,AT,NRef,NPtr>& data)\r
+ throw(persistent_dump_failed)\r
+ {\r
+ dump_xref(context,data.owner());\r
+ dump_xref(context,data.node());\r
+ }\r
+\r
+ template<typename NT, typename AT, typename NRef, typename NPtr>\r
+ void restore_digraph_iterator(restore_context& context, \r
+ digraph_iterator<NT,AT,NRef,NPtr>& data)\r
+ throw(persistent_restore_failed)\r
+ {\r
+ digraph<NT,AT>* owner = 0;\r
+ digraph_node<NT,AT>* node = 0;\r
+ restore_xref(context,owner);\r
+ restore_xref(context,node);\r
+ data = digraph_iterator<NT,AT,NRef,NPtr>(node);\r
+ data.assert_owner(owner);\r
+ }\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+ template<typename NT, typename AT, typename NRef, typename NPtr>\r
+ void dump_digraph_arc_iterator(dump_context& context,\r
+ const digraph_arc_iterator<NT,AT,NRef,NPtr>& data)\r
+ throw(persistent_dump_failed)\r
+ {\r
+ dump_xref(context,data.owner());\r
+ dump_xref(context,data.node());\r
+ }\r
+\r
+ template<typename NT, typename AT, typename NRef, typename NPtr>\r
+ void restore_digraph_arc_iterator(restore_context& context, \r
+ digraph_arc_iterator<NT,AT,NRef,NPtr>& data)\r
+ throw(persistent_restore_failed)\r
+ {\r
+ digraph<NT,AT>* owner = 0;\r
+ digraph_arc<NT,AT>* arc = 0;\r
+ restore_xref(context,owner);\r
+ restore_xref(context,arc);\r
+ data = digraph_arc_iterator<NT,AT,NRef,NPtr>(arc);\r
+ data.assert_owner(owner);\r
+ }\r
+\r
+ ////////////////////////////////////////////////////////////////////////////////\r
+\r
+} // end namespace stlplus\r