# cstlwatch.h

    00001 //==========================================================================
    00002 //  CSTLWATCH.H - part of
    00003 //                     OMNeT++/OMNEST
    00004 //            Discrete System Simulation in C++
    00005 //
    00006 //
    00007 //  WATCH_VECTOR, WATCH_MAP etc macros
    00008 //
    00009 //==========================================================================
    00010
    00011 /*--------------------------------------------------------------*
    00012   Copyright (C) 1992-2005 Andras Varga
    00013
    00014   This file is distributed WITHOUT ANY WARRANTY. See the file
    00015   `license' for details on this and other legal matters.
    00016 *--------------------------------------------------------------*/
    00017
    00018 #ifndef _CSTLWATCH_H__
    00019 #define _CSTLWATCH_H__
    00020
    00021 #include <vector>
    00022 #include <list>
    00023 #include <set>
    00024 #include <map>
    00025 #include <string>
    00026 #include <iostream>
    00027 #include <sstream>
    00028 #include "cobject.h"
    00029 #include "cwatch.h"
    00030
    00031
    00032
    00033 //
    00034 // Internal class
    00035 //
    00036 class SIM_API cStdVectorWatcherBase : public cWatchBase
    00037 {
    00038   public:
    00039     cStdVectorWatcherBase(const char *name) : cWatchBase(name) {}
    00040
    00041     virtual std::string info() const;
    00042     virtual std::string detailedInfo() const;
    00043     virtual bool supportsAssignment() const {return false;}
    00044
    00045     virtual const char *elemTypeName() const = 0;
    00046     virtual int size() const = 0;
    00047     virtual std::string at(int i) const = 0;
    00048     virtual cStructDescriptor *createDescriptor();
    00049 };
    00050
    00051
    00052 //
    00053 // Internal class
    00054 //
    00055 template<class T>
    00056 class SIM_API cStdVectorWatcher : public cStdVectorWatcherBase
    00057 {
    00058   protected:
    00059     std::vector<T>& v;
    00060     std::string classname;
    00061   public:
    00062     cStdVectorWatcher(const char *name, std::vector<T>& var) : cStdVectorWatcherBase(name), v(var) {
    00063         classname = std::string("std::vector<")+opp_typename(typeid(T))+">";
    00064     }
    00065     const char *className() const {return classname.c_str();}
    00066     virtual const char *elemTypeName() const {return opp_typename(typeid(T));}
    00067     virtual int size() const {return v.size();}
    00068     virtual std::string at(int i) const {std::stringstream out; out << v[i]; return out.str();}
    00069 };
    00070
    00071 template <class T>
    00072 void createStdVectorWatcher(const char *varname, std::vector<T>& v)
    00073 {
    00074     new cStdVectorWatcher<T>(varname, v);
    00075 }
    00076
    00077
    00078 //
    00079 // Internal class
    00080 //
    00081 template<class T>
    00082 class SIM_API cStdPointerVectorWatcher : public cStdVectorWatcher<T>
    00083 {
    00084   public:
    00085     cStdPointerVectorWatcher(const char *name, std::vector<T>& var) : cStdVectorWatcher<T>(name, var) {}
    00086     virtual std::string at(int i) const {std::stringstream out; out << *(this->v[i]); return out.str();}
    00087 };
    00088
    00089 template <class T>
    00090 void createStdPointerVectorWatcher(const char *varname, std::vector<T>& v)
    00091 {
    00092     new cStdPointerVectorWatcher<T>(varname, v);
    00093 }
    00094
    00095 //
    00096 // Internal class
    00097 //
    00098 template<class T>
    00099 class SIM_API cStdListWatcher : public cStdVectorWatcherBase
    00100 {
    00101   protected:
    00102     std::list<T>& v;
    00103     std::string classname;
    00104     mutable typename std::list<T>::iterator it;
    00105     mutable int itPos;
    00106   public:
    00107     cStdListWatcher(const char *name, std::list<T>& var) : cStdVectorWatcherBase(name), v(var) {
    00108         itPos=-1;
    00109         classname = std::string("std::list<")+opp_typename(typeid(T))+">";
    00110     }
    00111     const char *className() const {return classname.c_str();}
    00112     virtual const char *elemTypeName() const {return opp_typename(typeid(T));}
    00113     virtual int size() const {return v.size();}
    00114     virtual std::string at(int i) const {
    00115         // std::list doesn't support random access iterator and iteration is slow,
    00116         // so we have to use a trick, knowing that Tkenv will call this function with
    00117         // i=0, i=1, etc...
    00118         if (i==0) {
    00119             it=v.begin(); itPos=0;
    00120         } else if (i==itPos+1 && it!=v.end()) {
    00121             ++it; ++itPos;
    00122         } else {
    00123             it=v.begin();
    00124             for (int k=0; k<i && it!=v.end(); k++) ++it;
    00125             itPos=i;
    00126         }
    00127         if (it==v.end()) {
    00128             return std::string("out of bounds");
    00129         }
    00130         return atIt();
    00131     }
    00132     virtual std::string atIt() const {
    00133         std::stringstream out;
    00134         out << (*it);
    00135         return out.str();
    00136     }
    00137 };
    00138
    00139 template <class T>
    00140 void createStdListWatcher(const char *varname, std::list<T>& v)
    00141 {
    00142     new cStdListWatcher<T>(varname, v);
    00143 }
    00144
    00145
    00146 //
    00147 // Internal class
    00148 //
    00149 template<class T>
    00150 class SIM_API cStdPointerListWatcher : public cStdListWatcher<T>
    00151 {
    00152   public:
    00153     cStdPointerListWatcher(const char *name, std::list<T>& var) : cStdListWatcher<T>(name, var) {}
    00154     virtual std::string atIt() const {
    00155         std::stringstream out;
    00156         out << (**this->it);
    00157         return out.str();
    00158     }
    00159 };
    00160
    00161 template <class T>
    00162 void createStdPointerListWatcher(const char *varname, std::list<T>& v)
    00163 {
    00164     new cStdPointerListWatcher<T>(varname, v);
    00165 }
    00166
    00167
    00168 //
    00169 // Internal class
    00170 //
    00171 template<class T>
    00172 class SIM_API cStdSetWatcher : public cStdVectorWatcherBase
    00173 {
    00174   protected:
    00175     std::set<T>& v;
    00176     std::string classname;
    00177     mutable typename std::set<T>::iterator it;
    00178     mutable int itPos;
    00179   public:
    00180     cStdSetWatcher(const char *name, std::set<T>& var) : cStdVectorWatcherBase(name), v(var) {
    00181         itPos=-1;
    00182         classname = std::string("std::set<")+opp_typename(typeid(T))+">";
    00183     }
    00184     const char *className() const {return classname.c_str();}
    00185     virtual const char *elemTypeName() const {return opp_typename(typeid(T));}
    00186     virtual int size() const {return v.size();}
    00187     virtual std::string at(int i) const {
    00188         // std::set doesn't support random access iterator and iteration is slow,
    00189         // so we have to use a trick, knowing that Tkenv will call this function with
    00190         // i=0, i=1, etc...
    00191         if (i==0) {
    00192             it=v.begin(); itPos=0;
    00193         } else if (i==itPos+1 && it!=v.end()) {
    00194             ++it; ++itPos;
    00195         } else {
    00196             it=v.begin();
    00197             for (int k=0; k<i && it!=v.end(); k++) ++it;
    00198             itPos=i;
    00199         }
    00200         if (it==v.end()) {
    00201             return std::string("out of bounds");
    00202         }
    00203         return atIt();
    00204     }
    00205     virtual std::string atIt() const {
    00206         std::stringstream out;
    00207         out << (*it);
    00208         return out.str();
    00209     }
    00210 };
    00211
    00212 template <class T>
    00213 void createStdSetWatcher(const char *varname, std::set<T>& v)
    00214 {
    00215     new cStdSetWatcher<T>(varname, v);
    00216 }
    00217
    00218
    00219 //
    00220 // Internal class
    00221 //
    00222 template<class T>
    00223 class SIM_API cStdPointerSetWatcher : public cStdSetWatcher<T>
    00224 {
    00225   public:
    00226     cStdPointerSetWatcher(const char *name, std::set<T>& var) : cStdSetWatcher<T>(name, var) {}
    00227     virtual std::string atIt() const {
    00228         std::stringstream out;
    00229         out << (**this->it);
    00230         return out.str();
    00231     }
    00232 };
    00233
    00234 template <class T>
    00235 void createStdPointerSetWatcher(const char *varname, std::set<T>& v)
    00236 {
    00237     new cStdPointerSetWatcher<T>(varname, v);
    00238 }
    00239
    00240
    00241 //
    00242 // Internal class
    00243 //
    00244 template<class KeyT, class ValueT, class CmpT>
    00245 class SIM_API cStdMapWatcher : public cStdVectorWatcherBase
    00246 {
    00247   protected:
    00248     std::map<KeyT,ValueT,CmpT>& m;
    00249     mutable typename std::map<KeyT,ValueT,CmpT>::iterator it;
    00250     mutable int itPos;
    00251     std::string classname;
    00252   public:
    00253     cStdMapWatcher(const char *name, std::map<KeyT,ValueT,CmpT>& var) : cStdVectorWatcherBase(name), m(var) {
    00254         itPos=-1;
    00255         classname = std::string("std::map<")+opp_typename(typeid(KeyT))+","+opp_typename(typeid(ValueT))+">";
    00256     }
    00257     const char *className() const {return classname.c_str();}
    00258     virtual const char *elemTypeName() const {return "struct pair<*,*>";}
    00259     virtual int size() const {return m.size();}
    00260     virtual std::string at(int i) const {
    00261         // std::map doesn't support random access iterator and iteration is slow,
    00262         // so we have to use a trick, knowing that Tkenv will call this function with
    00263         // i=0, i=1, etc...
    00264         if (i==0) {
    00265             it=m.begin(); itPos=0;
    00266         } else if (i==itPos+1 && it!=m.end()) {
    00267             ++it; ++itPos;
    00268         } else {
    00269             it=m.begin();
    00270             for (int k=0; k<i && it!=m.end(); k++) ++it;
    00271             itPos=i;
    00272         }
    00273         if (it==m.end()) {
    00274             return std::string("out of bounds");
    00275         }
    00276         return atIt();
    00277     }
    00278     virtual std::string atIt() const {
    00279         std::stringstream out;
    00280         out << it->first << " ==> " << it->second;
    00281         return out.str();
    00282     }
    00283 };
    00284
    00285 template <class KeyT, class ValueT, class CmpT>
    00286 void createStdMapWatcher(const char *varname, std::map<KeyT,ValueT,CmpT>& m)
    00287 {
    00288     new cStdMapWatcher<KeyT,ValueT,CmpT>(varname, m);
    00289 }
    00290
    00291
    00292 //
    00293 // Internal class
    00294 //
    00295 template<class KeyT, class ValueT, class CmpT>
    00296 class SIM_API cStdPointerMapWatcher : public cStdMapWatcher<KeyT,ValueT,CmpT>
    00297 {
    00298   public:
    00299     cStdPointerMapWatcher(const char *name, std::map<KeyT,ValueT,CmpT>& var) : cStdMapWatcher<KeyT,ValueT,CmpT>(name, var) {}
    00300     virtual std::string atIt() const {
    00301         std::stringstream out;
    00302         out << this->it->first << "  ==>  " << *(this->it->second);
    00303         return out.str();
    00304     }
    00305 };
    00306
    00307 template<class KeyT, class ValueT, class CmpT>
    00308 void createStdPointerMapWatcher(const char *varname, std::map<KeyT,ValueT,CmpT>& m)
    00309 {
    00310     new cStdPointerMapWatcher<KeyT,ValueT,CmpT>(varname, m);
    00311 }
    00312
    00313
    00314
    00320
    00326 #define WATCH_VECTOR(variable)      createStdVectorWatcher(#variable,(variable))
    00327
    00333 #define WATCH_PTRVECTOR(variable)   createStdPointerVectorWatcher(#variable,(variable))
    00334
    00340 #define WATCH_LIST(variable)        createStdListWatcher(#variable,(variable))
    00341
    00347 #define WATCH_PTRLIST(variable)     createStdPointerListWatcher(#variable,(variable))
    00348
    00354 #define WATCH_SET(variable)        createStdSetWatcher(#variable,(variable))
    00355
    00361 #define WATCH_PTRSET(variable)     createStdPointerSetWatcher(#variable,(variable))
    00362
    00368 #define WATCH_MAP(m)         createStdMapWatcher(#m,(m))
    00369
    00375 #define WATCH_PTRMAP(m)      createStdPointerMapWatcher(#m,(m))
    00376
    00377
    00378 #endif
    00379