Statistics
| Branch: | Revision:

root / include / cstlwatch.h @ fbe00e73

History | View | Annotate | Download (10.3 KB)

1
//==========================================================================
2
//  CSTLWATCH.H - part of
3
//                     OMNeT++/OMNEST
4
//            Discrete System Simulation in C++
5
//
6
//
7
//  WATCH_VECTOR, WATCH_MAP etc macros
8
//
9
//==========================================================================
10

    
11
/*--------------------------------------------------------------*
12
  Copyright (C) 1992-2008 Andras Varga
13
  Copyright (C) 2006-2008 OpenSim Ltd.
14

15
  This file is distributed WITHOUT ANY WARRANTY. See the file
16
  `license' for details on this and other legal matters.
17
*--------------------------------------------------------------*/
18

    
19
#ifndef __CSTLWATCH_H
20
#define __CSTLWATCH_H
21

    
22
#include <vector>
23
#include <list>
24
#include <set>
25
#include <map>
26
#include <string>
27
#include <iostream>
28
#include <sstream>
29
#include "cownedobject.h"
30
#include "cwatch.h"
31

    
32
NAMESPACE_BEGIN
33

    
34

    
35

    
36
//
37
// Internal class
38
//
39
class SIM_API cStdVectorWatcherBase : public cWatchBase
40
{
41
  public:
42
    cStdVectorWatcherBase(const char *name) : cWatchBase(name) {}
43

    
44
    virtual std::string info() const;
45
    virtual std::string detailedInfo() const;
46
    virtual bool supportsAssignment() const {return false;}
47

    
48
    virtual const char *getElemTypeName() const = 0;
49
    virtual int size() const = 0;
50
    virtual std::string at(int i) const = 0;
51
    virtual cClassDescriptor *getDescriptor();
52
};
53

    
54

    
55
//
56
// Internal class
57
//
58
template<class T>
59
class cStdVectorWatcher : public cStdVectorWatcherBase
60
{
61
  protected:
62
    std::vector<T>& v;
63
    std::string classname;
64
  public:
65
    cStdVectorWatcher(const char *name, std::vector<T>& var) : cStdVectorWatcherBase(name), v(var) {
66
        classname = std::string("std::vector<")+opp_typename(typeid(T))+">";
67
    }
68
    const char *getClassName() const {return classname.c_str();}
69
    virtual const char *getElemTypeName() const {return opp_typename(typeid(T));}
70
    virtual int size() const {return v.size();}
71
    virtual std::string at(int i) const {std::stringstream out; out << v[i]; return out.str();}
72
};
73

    
74
template <class T>
75
void createStdVectorWatcher(const char *varname, std::vector<T>& v)
76
{
77
    new cStdVectorWatcher<T>(varname, v);
78
}
79

    
80

    
81
//
82
// Internal class
83
//
84
template<class T>
85
class cStdPointerVectorWatcher : public cStdVectorWatcher<T>
86
{
87
  public:
88
    cStdPointerVectorWatcher(const char *name, std::vector<T>& var) : cStdVectorWatcher<T>(name, var) {}
89
    virtual std::string at(int i) const {std::stringstream out; out << *(this->v[i]); return out.str();}
90
};
91

    
92
template <class T>
93
void createStdPointerVectorWatcher(const char *varname, std::vector<T>& v)
94
{
95
    new cStdPointerVectorWatcher<T>(varname, v);
96
}
97

    
98
//
99
// Internal class
100
//
101
template<class T>
102
class cStdListWatcher : public cStdVectorWatcherBase
103
{
104
  protected:
105
    std::list<T>& v;
106
    std::string classname;
107
    mutable typename std::list<T>::iterator it;
108
    mutable int itPos;
109
  public:
110
    cStdListWatcher(const char *name, std::list<T>& var) : cStdVectorWatcherBase(name), v(var) {
111
        itPos=-1;
112
        classname = std::string("std::list<")+opp_typename(typeid(T))+">";
113
    }
114
    const char *getClassName() const {return classname.c_str();}
115
    virtual const char *getElemTypeName() const {return opp_typename(typeid(T));}
116
    virtual int size() const {return v.size();}
117
    virtual std::string at(int i) const {
118
        // std::list doesn't support random access iterator and iteration is slow,
119
        // so we have to use a trick, knowing that Tkenv will call this function with
120
        // i=0, i=1, etc...
121
        if (i==0) {
122
            it=v.begin(); itPos=0;
123
        } else if (i==itPos+1 && it!=v.end()) {
124
            ++it; ++itPos;
125
        } else {
126
            it=v.begin();
127
            for (int k=0; k<i && it!=v.end(); k++) ++it;
128
            itPos=i;
129
        }
130
        if (it==v.end()) {
131
            return std::string("out of bounds");
132
        }
133
        return atIt();
134
    }
135
    virtual std::string atIt() const {
136
        std::stringstream out;
137
        out << (*it);
138
        return out.str();
139
    }
140
};
141

    
142
template <class T>
143
void createStdListWatcher(const char *varname, std::list<T>& v)
144
{
145
    new cStdListWatcher<T>(varname, v);
146
}
147

    
148

    
149
//
150
// Internal class
151
//
152
template<class T>
153
class cStdPointerListWatcher : public cStdListWatcher<T>
154
{
155
  public:
156
    cStdPointerListWatcher(const char *name, std::list<T>& var) : cStdListWatcher<T>(name, var) {}
157
    virtual std::string atIt() const {
158
        std::stringstream out;
159
        out << (**this->it);
160
        return out.str();
161
    }
162
};
163

    
164
template <class T>
165
void createStdPointerListWatcher(const char *varname, std::list<T>& v)
166
{
167
    new cStdPointerListWatcher<T>(varname, v);
168
}
169

    
170

    
171
//
172
// Internal class
173
//
174
template<class T>
175
class cStdSetWatcher : public cStdVectorWatcherBase
176
{
177
  protected:
178
    std::set<T>& v;
179
    std::string classname;
180
    mutable typename std::set<T>::iterator it;
181
    mutable int itPos;
182
  public:
183
    cStdSetWatcher(const char *name, std::set<T>& var) : cStdVectorWatcherBase(name), v(var) {
184
        itPos=-1;
185
        classname = std::string("std::set<")+opp_typename(typeid(T))+">";
186
    }
187
    const char *getClassName() const {return classname.c_str();}
188
    virtual const char *getElemTypeName() const {return opp_typename(typeid(T));}
189
    virtual int size() const {return v.size();}
190
    virtual std::string at(int i) const {
191
        // std::set doesn't support random access iterator and iteration is slow,
192
        // so we have to use a trick, knowing that Tkenv will call this function with
193
        // i=0, i=1, etc...
194
        if (i==0) {
195
            it=v.begin(); itPos=0;
196
        } else if (i==itPos+1 && it!=v.end()) {
197
            ++it; ++itPos;
198
        } else {
199
            it=v.begin();
200
            for (int k=0; k<i && it!=v.end(); k++) ++it;
201
            itPos=i;
202
        }
203
        if (it==v.end()) {
204
            return std::string("out of bounds");
205
        }
206
        return atIt();
207
    }
208
    virtual std::string atIt() const {
209
        std::stringstream out;
210
        out << (*it);
211
        return out.str();
212
    }
213
};
214

    
215
template <class T>
216
void createStdSetWatcher(const char *varname, std::set<T>& v)
217
{
218
    new cStdSetWatcher<T>(varname, v);
219
}
220

    
221

    
222
//
223
// Internal class
224
//
225
template<class T>
226
class cStdPointerSetWatcher : public cStdSetWatcher<T>
227
{
228
  public:
229
    cStdPointerSetWatcher(const char *name, std::set<T>& var) : cStdSetWatcher<T>(name, var) {}
230
    virtual std::string atIt() const {
231
        std::stringstream out;
232
        out << (**this->it);
233
        return out.str();
234
    }
235
};
236

    
237
template <class T>
238
void createStdPointerSetWatcher(const char *varname, std::set<T>& v)
239
{
240
    new cStdPointerSetWatcher<T>(varname, v);
241
}
242

    
243

    
244
//
245
// Internal class
246
//
247
template<class KeyT, class ValueT, class CmpT>
248
class cStdMapWatcher : public cStdVectorWatcherBase
249
{
250
  protected:
251
    std::map<KeyT,ValueT,CmpT>& m;
252
    mutable typename std::map<KeyT,ValueT,CmpT>::iterator it;
253
    mutable int itPos;
254
    std::string classname;
255
  public:
256
    cStdMapWatcher(const char *name, std::map<KeyT,ValueT,CmpT>& var) : cStdVectorWatcherBase(name), m(var) {
257
        itPos=-1;
258
        classname = std::string("std::map<")+opp_typename(typeid(KeyT))+","+opp_typename(typeid(ValueT))+">";
259
    }
260
    const char *getClassName() const {return classname.c_str();}
261
    virtual const char *getElemTypeName() const {return "struct pair<*,*>";}
262
    virtual int size() const {return m.size();}
263
    virtual std::string at(int i) const {
264
        // std::map doesn't support random access iterator and iteration is slow,
265
        // so we have to use a trick, knowing that Tkenv will call this function with
266
        // i=0, i=1, etc...
267
        if (i==0) {
268
            it=m.begin(); itPos=0;
269
        } else if (i==itPos+1 && it!=m.end()) {
270
            ++it; ++itPos;
271
        } else {
272
            it=m.begin();
273
            for (int k=0; k<i && it!=m.end(); k++) ++it;
274
            itPos=i;
275
        }
276
        if (it==m.end()) {
277
            return std::string("out of bounds");
278
        }
279
        return atIt();
280
    }
281
    virtual std::string atIt() const {
282
        std::stringstream out;
283
        out << it->first << " ==> " << it->second;
284
        return out.str();
285
    }
286
};
287

    
288
template <class KeyT, class ValueT, class CmpT>
289
void createStdMapWatcher(const char *varname, std::map<KeyT,ValueT,CmpT>& m)
290
{
291
    new cStdMapWatcher<KeyT,ValueT,CmpT>(varname, m);
292
}
293

    
294

    
295
//
296
// Internal class
297
//
298
template<class KeyT, class ValueT, class CmpT>
299
class cStdPointerMapWatcher : public cStdMapWatcher<KeyT,ValueT,CmpT>
300
{
301
  public:
302
    cStdPointerMapWatcher(const char *name, std::map<KeyT,ValueT,CmpT>& var) : cStdMapWatcher<KeyT,ValueT,CmpT>(name, var) {}
303
    virtual std::string atIt() const {
304
        std::stringstream out;
305
        out << this->it->first << "  ==>  " << *(this->it->second);
306
        return out.str();
307
    }
308
};
309

    
310
template<class KeyT, class ValueT, class CmpT>
311
void createStdPointerMapWatcher(const char *varname, std::map<KeyT,ValueT,CmpT>& m)
312
{
313
    new cStdPointerMapWatcher<KeyT,ValueT,CmpT>(varname, m);
314
}
315

    
316

    
317

    
318
/**
319
 * @ingroup Macros
320
 * @defgroup MacrosWatch WATCH macros
321
 */
322
//@{
323

    
324
/**
325
 * Makes std::vectors inspectable in Tkenv. See also WATCH_PTRVECTOR().
326
 *
327
 * @hideinitializer
328
 */
329
#define WATCH_VECTOR(variable)      createStdVectorWatcher(#variable,(variable))
330

    
331
/**
332
 * Makes std::vectors storing pointers inspectable in Tkenv. See also WATCH_VECTOR().
333
 *
334
 * @hideinitializer
335
 */
336
#define WATCH_PTRVECTOR(variable)   createStdPointerVectorWatcher(#variable,(variable))
337

    
338
/**
339
 * Makes std::lists inspectable in Tkenv. See also WATCH_PTRLIST().
340
 *
341
 * @hideinitializer
342
 */
343
#define WATCH_LIST(variable)        createStdListWatcher(#variable,(variable))
344

    
345
/**
346
 * Makes std::lists storing pointers inspectable in Tkenv. See also WATCH_LIST().
347
 *
348
 * @hideinitializer
349
 */
350
#define WATCH_PTRLIST(variable)     createStdPointerListWatcher(#variable,(variable))
351

    
352
/**
353
 * Makes std::sets inspectable in Tkenv. See also WATCH_PTRSET().
354
 *
355
 * @hideinitializer
356
 */
357
#define WATCH_SET(variable)        createStdSetWatcher(#variable,(variable))
358

    
359
/**
360
 * Makes std::sets storing pointers inspectable in Tkenv. See also WATCH_SET().
361
 *
362
 * @hideinitializer
363
 */
364
#define WATCH_PTRSET(variable)     createStdPointerSetWatcher(#variable,(variable))
365

    
366
/**
367
 * Makes std::maps inspectable in Tkenv. See also WATCH_PTRMAP().
368
 *
369
 * @hideinitializer
370
 */
371
#define WATCH_MAP(m)         createStdMapWatcher(#m,(m))
372

    
373
/**
374
 * Makes std::maps storing pointers inspectable in Tkenv. See also WATCH_MAP().
375
 *
376
 * @hideinitializer
377
 */
378
#define WATCH_PTRMAP(m)      createStdPointerMapWatcher(#m,(m))
379
//@}
380

    
381
NAMESPACE_END
382

    
383

    
384
#endif
385