OverSim
hashWatch.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 //
18 
24 #ifndef __WATCHABLECONTAINERS_H__
25 #define __WATCHABLECONTAINERS_H__
26 
27 #include <omnetpp.h>
28 
29 #include <map>
30 #include <deque>
31 #include <oversim_mapset.h>
32 
33 template<class T>
34 class SIM_API cHashSetWatcher : public cStdVectorWatcherBase
35 {
36  protected:
37  UNORDERED_SET<T>& v;
38  std::string classname;
39  mutable typename UNORDERED_SET<T>::iterator it;
40  mutable int itPos;
41  public:
42  cHashSetWatcher(const char *name, UNORDERED_SET<T>& var) : cStdVectorWatcherBase(name), v(var) {
43  itPos=-1;
44  classname = std::string("unordered_set<")+opp_typename(typeid(T))+">";
45  }
46  const char *getClassName() const {return classname.c_str();}
47  virtual const char *getElemTypeName() const {return opp_typename(typeid(T));}
48  virtual int size() const {return v.size();}
49  virtual std::string at(int i) const {
50  if (i==0) {
51  it=v.begin(); itPos=0;
52  } else if (i==itPos+1 && it!=v.end()) {
53  ++it; ++itPos;
54  } else {
55  it=v.begin();
56  for (int k=0; k<i && it!=v.end(); k++) ++it;
57  itPos=i;
58  }
59  if (it==v.end()) {
60  return std::string("out of bounds");
61  }
62  return atIt();
63  }
64  virtual std::string atIt() const {
65  std::stringstream out;
66  out << (*it);
67  return out.str();
68  }
69 };
70 
71 template <class T>
72 void createHashSetWatcher(const char *varname, UNORDERED_SET<T>& v)
73 {
74  new cHashSetWatcher<T>(varname, v);
75 };
76 
77 template<class T>
78 class SIM_API cDequeWatcher : public cStdVectorWatcherBase
79 {
80  protected:
81  std::deque<T>& v;
82  std::string classname;
83  mutable typename std::deque<T>::iterator it;
84  mutable int itPos;
85  public:
86  cDequeWatcher(const char *name, std::deque<T>& var) : cStdVectorWatcherBase(name), v(var) {
87  itPos=-1;
88  classname = std::string("deque<")+opp_typename(typeid(T))+">";
89  }
90  const char *className() const {return classname.c_str();}
91  virtual const char *getElemTypeName() const {return opp_typename(typeid(T));}
92  virtual int size() const {return v.size();}
93  virtual std::string at(int i) const {
94  if (i==0) {
95  it=v.begin(); itPos=0;
96  } else if (i==itPos+1 && it!=v.end()) {
97  ++it; ++itPos;
98  } else {
99  it=v.begin();
100  for (int k=0; k<i && it!=v.end(); k++) ++it;
101  itPos=i;
102  }
103  if (it==v.end()) {
104  return std::string("out of bounds");
105  }
106  return atIt();
107  }
108  virtual std::string atIt() const {
109  std::stringstream out;
110  out << (*it);
111  return out.str();
112  }
113 };
114 
115 template <class T>
116 void createDequeWatcher(const char *varname, std::deque<T>& v)
117 {
118  new cDequeWatcher<T>(varname, v);
119 };
120 
121 template<class KeyT, class ValueT, class CmpT>
122 class SIM_API cHashMapWatcher : public cStdVectorWatcherBase
123 {
124  protected:
125  UNORDERED_MAP<KeyT,ValueT,CmpT>& m;
126  mutable typename UNORDERED_MAP<KeyT,ValueT,CmpT>::iterator it;
127  mutable int itPos;
128  std::string classname;
129  public:
130  cHashMapWatcher(const char *name, UNORDERED_MAP<KeyT,ValueT,CmpT>& var) : cStdVectorWatcherBase(name), m(var) {
131  itPos=-1;
132  classname = std::string("unordered_map<")+opp_typename(typeid(KeyT))+","+opp_typename(typeid(ValueT))+">";
133  }
134  const char *getClassName() const {return classname.c_str();}
135  virtual const char *getElemTypeName() const {return "struct pair<*,*>";}
136  virtual int size() const {return m.size();}
137  virtual std::string at(int i) const {
138  if (i==0) {
139  it=m.begin(); itPos=0;
140  } else if (i==itPos+1 && it!=m.end()) {
141  ++it; ++itPos;
142  } else {
143  it=m.begin();
144  for (int k=0; k<i && it!=m.end(); k++) ++it;
145  itPos=i;
146  }
147  if (it==m.end()) {
148  return std::string("out of bounds");
149  }
150  return atIt();
151  }
152  virtual std::string atIt() const {
153  std::stringstream out;
154  out << it->first << " ==> " << it->second;
155  return out.str();
156  }
157 };
158 
159 template <class KeyT, class ValueT, class CmpT>
160 void createHashMapWatcher(const char *varname, UNORDERED_MAP<KeyT,ValueT,CmpT>& m)
161 {
162  new cHashMapWatcher<KeyT,ValueT,CmpT>(varname, m);
163 };
164 
165 template<class KeyT, class ValueT, class CmpT>
166 class SIM_API cConstHashMapWatcher : public cStdVectorWatcherBase
167 {
168  protected:
169  const UNORDERED_MAP<KeyT,ValueT,CmpT>& m;
170  mutable typename UNORDERED_MAP<KeyT,ValueT,CmpT>::const_iterator it;
171  mutable int itPos;
172  std::string classname;
173  public:
174  cConstHashMapWatcher(const char *name, const UNORDERED_MAP<KeyT,ValueT,CmpT>& var) : cStdVectorWatcherBase(name), m(var) {
175  itPos=-1;
176  classname = std::string("unordered_map<")+opp_typename(typeid(KeyT))+","+opp_typename(typeid(ValueT))+">";
177  }
178  const char *getClassName() const {return classname.c_str();}
179  virtual const char *getElemTypeName() const {return "struct pair<*,*>";}
180  virtual int size() const {return m.size();}
181  virtual std::string at(int i) const {
182  if (i==0) {
183  it=m.begin(); itPos=0;
184  } else if (i==itPos+1 && it!=m.end()) {
185  ++it; ++itPos;
186  } else {
187  it=m.begin();
188  for (int k=0; k<i && it!=m.end(); k++) ++it;
189  itPos=i;
190  }
191  if (it==m.end()) {
192  return std::string("out of bounds");
193  }
194  return atIt();
195  }
196  virtual std::string atIt() const {
197  std::stringstream out;
198  out << it->first << " ==> " << it->second;
199  return out.str();
200  }
201 };
202 
203 template <class KeyT, class ValueT, class CmpT>
204 void createHashMapWatcher(const char *varname, const UNORDERED_MAP<KeyT,ValueT,CmpT>& m)
205 {
207 };
208 
209 template<class KeyT, class ValueT, class CmpT>
210 class SIM_API cPointerMapWatcher : public cStdVectorWatcherBase
211 {
212  protected:
213  std::map<KeyT,ValueT,CmpT>& m;
214  mutable typename std::map<KeyT,ValueT,CmpT>::iterator it;
215  mutable int itPos;
216  std::string classname;
217  public:
218  cPointerMapWatcher(const char *name, std::map<KeyT,ValueT,CmpT>& var) : cStdVectorWatcherBase(name), m(var) {
219  itPos=-1;
220  classname = std::string("pointer_map<")+opp_typename(typeid(KeyT))+","+opp_typename(typeid(ValueT))+">";
221  }
222  const char *getClassName() const {return classname.c_str();}
223  virtual const char *getElemTypeName() const {return "struct pair<*,*>";}
224  virtual int size() const {return m.size();}
225  virtual std::string at(int i) const {
226  if (i==0) {
227  it=m.begin(); itPos=0;
228  } else if (i==itPos+1 && it!=m.end()) {
229  ++it; ++itPos;
230  } else {
231  it=m.begin();
232  for (int k=0; k<i && it!=m.end(); k++) ++it;
233  itPos=i;
234  }
235  if (it==m.end()) {
236  return std::string("out of bounds");
237  }
238  return atIt();
239  }
240  virtual std::string atIt() const {
241  std::stringstream out;
242  out << it->first << " ==> " << *(it->second);
243  return out.str();
244  }
245 };
246 
247 template <class KeyT, class ValueT, class CmpT>
248 void createPointerMapWatcher(const char *varname, std::map<KeyT,ValueT,CmpT>& m)
249 {
250  new cPointerMapWatcher<KeyT,ValueT,CmpT>(varname, m);
251 };
252 
253 template<class KeyT, class ValueT, class CmpT>
254 class cStdMultiMapWatcher : public cStdVectorWatcherBase
255 {
256  protected:
257  std::multimap<KeyT,ValueT,CmpT>& m;
258  mutable typename std::multimap<KeyT,ValueT,CmpT>::iterator it;
259  mutable int itPos;
260  std::string classname;
261  public:
262  cStdMultiMapWatcher(const char *name, std::multimap<KeyT,ValueT,CmpT>& var) : cStdVectorWatcherBase(name), m(var) {
263  itPos=-1;
264  classname = std::string("std::multimap<")+opp_typename(typeid(KeyT))+","+opp_typename(typeid(ValueT))+">";
265  }
266  const char *getClassName() const {return classname.c_str();}
267  virtual const char *getElemTypeName() const {return "struct pair<*,*>";}
268  virtual int size() const {return m.size();}
269  virtual std::string at(int i) const {
270  // std::map doesn't support random access iterator and iteration is slow,
271  // so we have to use a trick, knowing that Tkenv will call this function with
272  // i=0, i=1, etc...
273  if (i==0) {
274  it=m.begin(); itPos=0;
275  } else if (i==itPos+1 && it!=m.end()) {
276  ++it; ++itPos;
277  } else {
278  it=m.begin();
279  for (int k=0; k<i && it!=m.end(); k++) ++it;
280  itPos=i;
281  }
282  if (it==m.end()) {
283  return std::string("out of bounds");
284  }
285  return atIt();
286  }
287  virtual std::string atIt() const {
288  std::stringstream out;
289  out << it->first << " ==> " << it->second;
290  return out.str();
291  }
292 };
293 
294 template <class KeyT, class ValueT, class CmpT>
295 void createStdMultiMapWatcher(const char *varname, std::multimap<KeyT,ValueT,CmpT>& m)
296 {
298 };
299 
300 
306 #define WATCH_UNORDERED_SET(variable) createHashSetWatcher(#variable,(variable))
307 
313 #define WATCH_DEQUE(variable) createDequeWatcher(#variable,(variable))
314 
320 #define WATCH_UNORDERED_MAP(m) createHashMapWatcher(#m,(m))
321 
327 #define WATCH_POINTER_MAP(m) createPointerMapWatcher(#m,(m))
328 
334 #define WATCH_MULTIMAP(m) createStdMultiMapWatcher(#m,(m))
335 
336 #endif