Classdesc 3.44
pack_graph.h
Go to the documentation of this file.
1/*
2 @copyright Russell Standish 2000-2013
3 @author Russell Standish
4 This file is part of Classdesc
5
6 Open source licensed under the MIT license. See LICENSE for details.
7*/
8
12
13#ifndef CLASSDESC_PACK_GRAPH_H
14#define CLASSDESC_PACK_GRAPH_H
15
16#include <vector>
17#include <map>
18
19#include <pack_base.h>
20/*
21 treenodes should really be deprecated in favour of graphnodes
22*/
23
24namespace classdesc
25{
27 template <class T>
28 void pack(pack_t& targ, const string& desc, is_treenode dum, const T* const& arg)
29 {
30 int valid=0;
31 if (arg==NULL)
32 pack(targ,desc,valid);
33 else
34 {
35 valid=1;
36 pack(targ,desc,valid);
37 pack(targ,desc,*arg);
38 }
39 }
40
42
43 template <class T>
44 void unpack(unpack_t& targ, const string& desc, is_treenode dum, T*& arg)
45 {
46 int valid;
47 unpack(targ,desc,valid);
48 if (valid)
49 {
50 // arg=new T;
51 // targ->alloced.push_back(arg);
52 targ.alloced.push_back(new classdesc::PtrStore<T>);
53 arg=static_cast<T*>(targ.alloced.back().data());
54 unpack(targ,desc,*arg);
55 }
56 }
57
58 /*
59 pack up a graph (possibly containing cycles).
60 T must have the following members:
61 V& operator*() - dereference operator
62 operator bool() - returns true if valid, false otherwise
63 T& operator=(const T&) - assignable x=y => &*x==&*y
64 T() - construct an invalid object
65 T(const T&) - copyable
66
67 Alloc<T>(T& x) - allocates a new object referenced by x
68
69 V must be serialisable.
70 */
71
73 template <class T> struct Alloc;
74 template <class T>
75 struct Alloc<T*>
76 {
77 void operator()(pack_t& buf, T*& x) {
78 buf.alloced.push_back(new PtrStore<T>);
79 x=static_cast<T*>(buf.alloced.back().data());
80 }
81 };
82
83 template <class T>
84 inline void pack_graph(pack_t& buf, T& arg)
85 {
86 static std::map<T,int> graph_map;
87 static std::vector<T*> restart;
88 static unsigned recur_level=0;
89 int nought=0;
90
91 if (recur_level==0)
92 pack(buf,string(),buf.recur_max);
93 recur_level++;
94
95 if (recur_level==buf.recur_max)
96 restart.push_back(&arg); //save ref for restart
97 else if (!arg) //reference is invalid
98 pack(buf,string(),nought);
99 else if (graph_map.count(arg)==0)
100 {
101 int ID=graph_map.size()+1;
102 graph_map[arg]=ID;
103 pack(buf,string(),ID);
104 pack(buf,string(),*arg);
105 }
106 else
107 pack(buf,string(),graph_map[arg]);
108
109 recur_level--;
110 if (recur_level==0) //process restarts
111 {
112 while (restart.size())
113 {
114 T& aa=*restart.back(); //we need to pop_back() before packing
115 restart.pop_back(); //in case further restarts are needed
116 pack_graph(buf,aa);
117 }
118 graph_map.clear();
119 }
120 }
121
122 template <class T>
123 void unpack_graph(pack_t& buf, T& arg)
124 {
125 static std::map<int,T> graph_map;
126 static std::vector<T*> restart;
127 static unsigned recur_level=0;
128 int myid;
129 Alloc<T> alloc;
130
131 if (recur_level==0)
132 unpack(buf,string(),buf.recur_max);
133 recur_level++;
134
135 if (recur_level==buf.recur_max)
136 restart.push_back(&arg); //save ref for restart
137 else
138 {
139 unpack(buf,string(),myid);
140 if (myid==0)
141 arg=T(); //reset arg to invalid state
142 else if (graph_map.count(myid))
143 arg=graph_map[myid];
144 else
145 {
146 alloc(buf,arg);
147 graph_map[myid]=arg;
148 unpack(buf,string(),*arg);
149 }
150
151 }
152 recur_level--;
153 if (recur_level==0) //process restarts
154 {
155 while (restart.size())
156 {
157 T& aa=*restart.back(); //we need to pop_back() before packing
158 restart.pop_back(); //in case further restarts are needed
159 unpack_graph(buf,aa);
160 }
161 graph_map.clear();
162 }
163
164 }
165
167
168
169 template <class T>
170 inline void pack(pack_t& targ, const string& desc,is_graphnode dum,const T& arg)
171 {pack_graph(targ,arg);}
172
174
175 template <class T>
176 inline void unpack(pack_t& targ, const string& desc,is_graphnode dum,T& arg)
177 {unpack_graph(targ,arg);}
178
179}
180#endif
Definition classdesc.h:931
Definition classdesc.h:930
Definition pack_base.h:138
unsigned recur_max
recursion limit for pack_graph
Definition pack_base.h:166
Contains definitions related to classdesc functionality.
void pack(pack_t &targ, const string &desc, is_treenode dum, const T *const &arg)
serialise a tree (or DAG)
Definition pack_graph.h:28
void unpack(unpack_t &targ, const string &desc, is_treenode dum, T *&arg)
unserialise a tree.
Definition pack_graph.h:44
serialisation descriptor
Definition pack_graph.h:73
Definition pack_base.h:114