OMNeT++ Simulation Library  6.0.3
cstlwatch.h
1 //==========================================================================
2 // CSTLWATCH.H - part of
3 // OMNeT++/OMNEST
4 // Discrete System Simulation in C++
5 //
6 //==========================================================================
7 
8 /*--------------------------------------------------------------*
9  Copyright (C) 1992-2017 Andras Varga
10  Copyright (C) 2006-2017 OpenSim Ltd.
11 
12  This file is distributed WITHOUT ANY WARRANTY. See the file
13  `license' for details on this and other legal matters.
14 *--------------------------------------------------------------*/
15 
16 #ifndef __OMNETPP_CSTLWATCH_H
17 #define __OMNETPP_CSTLWATCH_H
18 
19 #include <vector>
20 #include <list>
21 #include <set>
22 #include <map>
23 #include <string>
24 #include <iostream>
25 #include <sstream>
26 #include "cownedobject.h"
27 #include "cwatch.h"
28 
29 namespace omnetpp {
30 
31 //
32 // Internal class
33 //
34 class SIM_API cStdVectorWatcherBase : public cWatchBase
35 {
36  private:
37  mutable cClassDescriptor *desc;
38  public:
39  cStdVectorWatcherBase(const char *name) : cWatchBase(name) {desc = nullptr;}
40 
41  virtual std::string str() const override;
42  virtual bool supportsAssignment() const override {return false;}
43 
44  virtual const char *getElemTypeName() const = 0;
45  virtual int size() const = 0;
46  virtual std::string at(int i) const = 0;
47  virtual cClassDescriptor *getDescriptor() const override;
48 };
49 
50 
51 //
52 // Internal class
53 //
54 template<class T>
55 class cStdVectorWatcher : public cStdVectorWatcherBase
56 {
57  protected:
58  std::vector<T>& v;
59  std::string classname;
60  public:
61  cStdVectorWatcher(const char *name, std::vector<T>& var) : cStdVectorWatcherBase(name), v(var) {
62  classname = std::string("std::vector<")+opp_typename(typeid(T))+">";
63  }
64  const char *getClassName() const override {return classname.c_str();}
65  virtual const char *getElemTypeName() const override {return opp_typename(typeid(T));}
66  virtual int size() const override {return v.size();}
67  virtual std::string at(int i) const override {std::stringstream out; out << v[i]; return out.str();}
68 };
69 
70 template <class T>
71 void createStdVectorWatcher(const char *varname, std::vector<T>& v)
72 {
73  new cStdVectorWatcher<T>(varname, v);
74 }
75 
76 
77 //
78 // Internal class
79 //
80 template<class T>
81 class cStdPointerVectorWatcher : public cStdVectorWatcher<T>
82 {
83  public:
84  cStdPointerVectorWatcher(const char *name, std::vector<T>& var) : cStdVectorWatcher<T>(name, var) {}
85  virtual std::string at(int i) const {std::stringstream out; out << *(this->v[i]); return out.str();}
86 };
87 
88 template <class T>
89 void createStdPointerVectorWatcher(const char *varname, std::vector<T>& v)
90 {
91  new cStdPointerVectorWatcher<T>(varname, v);
92 }
93 
94 //
95 // Internal class
96 //
97 template<class T>
98 class cStdListWatcher : public cStdVectorWatcherBase
99 {
100  protected:
101  std::list<T>& v;
102  std::string classname;
103  mutable typename std::list<T>::iterator it;
104  mutable int itPos;
105  public:
106  cStdListWatcher(const char *name, std::list<T>& var) : cStdVectorWatcherBase(name), v(var) {
107  itPos=-1;
108  classname = std::string("std::list<")+opp_typename(typeid(T))+">";
109  }
110  const char *getClassName() const override {return classname.c_str();}
111  virtual const char *getElemTypeName() const override {return opp_typename(typeid(T));}
112  virtual int size() const override {return v.size();}
113  virtual std::string at(int i) const override {
114  // std::list doesn't support random access iterator and iteration is slow,
115  // so we have to use a trick, knowing that Qtenv will call this function with
116  // i=0, i=1, etc...
117  if (i==0) {
118  it=v.begin(); itPos=0;
119  } else if (i==itPos+1 && it!=v.end()) {
120  ++it; ++itPos;
121  } else {
122  it=v.begin();
123  for (int k=0; k<i && it!=v.end(); k++) ++it;
124  itPos=i;
125  }
126  if (it==v.end()) {
127  return std::string("out of bounds");
128  }
129  return atIt();
130  }
131  virtual std::string atIt() const {
132  std::stringstream out;
133  out << (*it);
134  return out.str();
135  }
136 };
137 
138 template <class T>
139 void createStdListWatcher(const char *varname, std::list<T>& v)
140 {
141  new cStdListWatcher<T>(varname, v);
142 }
143 
144 
145 //
146 // Internal class
147 //
148 template<class T>
149 class cStdPointerListWatcher : public cStdListWatcher<T>
150 {
151  public:
152  cStdPointerListWatcher(const char *name, std::list<T>& var) : cStdListWatcher<T>(name, var) {}
153  virtual std::string atIt() const {
154  std::stringstream out;
155  out << (**this->it);
156  return out.str();
157  }
158 };
159 
160 template <class T>
161 void createStdPointerListWatcher(const char *varname, std::list<T>& v)
162 {
163  new cStdPointerListWatcher<T>(varname, v);
164 }
165 
166 
167 //
168 // Internal class
169 //
170 template<class T>
171 class cStdSetWatcher : public cStdVectorWatcherBase
172 {
173  protected:
174  std::set<T>& v;
175  std::string classname;
176  mutable typename std::set<T>::iterator it;
177  mutable int itPos;
178  public:
179  cStdSetWatcher(const char *name, std::set<T>& var) : cStdVectorWatcherBase(name), v(var) {
180  itPos=-1;
181  classname = std::string("std::set<")+opp_typename(typeid(T))+">";
182  }
183  const char *getClassName() const override {return classname.c_str();}
184  virtual const char *getElemTypeName() const override {return opp_typename(typeid(T));}
185  virtual int size() const override {return v.size();}
186  virtual std::string at(int i) const override {
187  // std::set doesn't support random access iterator and iteration is slow,
188  // so we have to use a trick, knowing that Qtenv will call this function with
189  // i=0, i=1, etc...
190  if (i==0) {
191  it=v.begin(); itPos=0;
192  } else if (i==itPos+1 && it!=v.end()) {
193  ++it; ++itPos;
194  } else {
195  it=v.begin();
196  for (int k=0; k<i && it!=v.end(); k++) ++it;
197  itPos=i;
198  }
199  if (it==v.end()) {
200  return std::string("out of bounds");
201  }
202  return atIt();
203  }
204  virtual std::string atIt() const {
205  std::stringstream out;
206  out << (*it);
207  return out.str();
208  }
209 };
210 
211 template <class T>
212 void createStdSetWatcher(const char *varname, std::set<T>& v)
213 {
214  new cStdSetWatcher<T>(varname, v);
215 }
216 
217 
218 //
219 // Internal class
220 //
221 template<class T>
222 class cStdPointerSetWatcher : public cStdSetWatcher<T>
223 {
224  public:
225  cStdPointerSetWatcher(const char *name, std::set<T>& var) : cStdSetWatcher<T>(name, var) {}
226  virtual std::string atIt() const {
227  std::stringstream out;
228  out << (**this->it);
229  return out.str();
230  }
231 };
232 
233 template <class T>
234 void createStdPointerSetWatcher(const char *varname, std::set<T>& v)
235 {
236  new cStdPointerSetWatcher<T>(varname, v);
237 }
238 
239 
240 //
241 // Internal class
242 //
243 template<class KeyT, class ValueT, class CmpT>
244 class cStdMapWatcher : public cStdVectorWatcherBase
245 {
246  protected:
247  std::map<KeyT,ValueT,CmpT>& m;
248  mutable typename std::map<KeyT,ValueT,CmpT>::iterator it;
249  mutable int itPos;
250  std::string classname;
251  public:
252  cStdMapWatcher(const char *name, std::map<KeyT,ValueT,CmpT>& var) : cStdVectorWatcherBase(name), m(var) {
253  itPos=-1;
254  classname = std::string("std::map<")+opp_typename(typeid(KeyT))+","+opp_typename(typeid(ValueT))+">";
255  }
256  const char *getClassName() const override {return classname.c_str();}
257  virtual const char *getElemTypeName() const override {return "pair<,>";}
258  virtual int size() const override {return m.size();}
259  virtual std::string at(int i) const override {
260  // std::map doesn't support random access iterator and iteration is slow,
261  // so we have to use a trick, knowing that Qtenv will call this function with
262  // i=0, i=1, etc...
263  if (i==0) {
264  it=m.begin(); itPos=0;
265  } else if (i==itPos+1 && it!=m.end()) {
266  ++it; ++itPos;
267  } else {
268  it=m.begin();
269  for (int k=0; k<i && it!=m.end(); k++) ++it;
270  itPos=i;
271  }
272  if (it==m.end()) {
273  return std::string("out of bounds");
274  }
275  return atIt();
276  }
277  virtual std::string atIt() const {
278  std::stringstream out;
279  out << it->first << " ==> " << it->second;
280  return out.str();
281  }
282 };
283 
284 template <class KeyT, class ValueT, class CmpT>
285 void createStdMapWatcher(const char *varname, std::map<KeyT,ValueT,CmpT>& m)
286 {
287  new cStdMapWatcher<KeyT,ValueT,CmpT>(varname, m);
288 }
289 
290 
291 //
292 // Internal class
293 //
294 template<class KeyT, class ValueT, class CmpT>
295 class cStdPointerMapWatcher : public cStdMapWatcher<KeyT,ValueT,CmpT>
296 {
297  public:
298  cStdPointerMapWatcher(const char *name, std::map<KeyT,ValueT,CmpT>& var) : cStdMapWatcher<KeyT,ValueT,CmpT>(name, var) {}
299  virtual std::string atIt() const {
300  std::stringstream out;
301  out << this->it->first << " ==> " << *(this->it->second);
302  return out.str();
303  }
304 };
305 
306 template<class KeyT, class ValueT, class CmpT>
307 void createStdPointerMapWatcher(const char *varname, std::map<KeyT,ValueT,CmpT>& m)
308 {
309  new cStdPointerMapWatcher<KeyT,ValueT,CmpT>(varname, m);
310 }
311 
312 
323 #define WATCH_VECTOR(variable) omnetpp::createStdVectorWatcher(#variable,(variable))
324 
330 #define WATCH_PTRVECTOR(variable) omnetpp::createStdPointerVectorWatcher(#variable,(variable))
331 
337 #define WATCH_LIST(variable) omnetpp::createStdListWatcher(#variable,(variable))
338 
344 #define WATCH_PTRLIST(variable) omnetpp::createStdPointerListWatcher(#variable,(variable))
345 
351 #define WATCH_SET(variable) omnetpp::createStdSetWatcher(#variable,(variable))
352 
358 #define WATCH_PTRSET(variable) omnetpp::createStdPointerSetWatcher(#variable,(variable))
359 
365 #define WATCH_MAP(m) omnetpp::createStdMapWatcher(#m,(m))
366 
372 #define WATCH_PTRMAP(m) omnetpp::createStdPointerMapWatcher(#m,(m))
373 
376 } // namespace omnetpp
377 
378 
379 #endif
380 
omnetpp::opp_typename
const SIM_API char * opp_typename(const std::type_info &t)
Returns the name of a C++ type, correcting the quirks of various compilers.