00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #ifndef __WATCHABLECONTAINERS_H__
00025 #define __WATCHABLECONTAINERS_H__
00026
00027 #include <omnetpp.h>
00028
00029 #include <map>
00030 #include <deque>
00031 #include <oversim_mapset.h>
00032
00033 template<class T>
00034 class SIM_API cHashSetWatcher : public cStdVectorWatcherBase
00035 {
00036 protected:
00037 UNORDERED_SET<T>& v;
00038 std::string classname;
00039 mutable typename UNORDERED_SET<T>::iterator it;
00040 mutable int itPos;
00041 public:
00042 cHashSetWatcher(const char *name, UNORDERED_SET<T>& var) : cStdVectorWatcherBase(name), v(var) {
00043 itPos=-1;
00044 classname = std::string("unordered_set<")+opp_typename(typeid(T))+">";
00045 }
00046 const char *getClassName() const {return classname.c_str();}
00047 virtual const char *getElemTypeName() const {return opp_typename(typeid(T));}
00048 virtual int size() const {return v.size();}
00049 virtual std::string at(int i) const {
00050 if (i==0) {
00051 it=v.begin(); itPos=0;
00052 } else if (i==itPos+1 && it!=v.end()) {
00053 ++it; ++itPos;
00054 } else {
00055 it=v.begin();
00056 for (int k=0; k<i && it!=v.end(); k++) ++it;
00057 itPos=i;
00058 }
00059 if (it==v.end()) {
00060 return std::string("out of bounds");
00061 }
00062 return atIt();
00063 }
00064 virtual std::string atIt() const {
00065 std::stringstream out;
00066 out << (*it);
00067 return out.str();
00068 }
00069 };
00070
00071 template <class T>
00072 void createHashSetWatcher(const char *varname, UNORDERED_SET<T>& v)
00073 {
00074 new cHashSetWatcher<T>(varname, v);
00075 };
00076
00077 template<class T>
00078 class SIM_API cDequeWatcher : public cStdVectorWatcherBase
00079 {
00080 protected:
00081 std::deque<T>& v;
00082 std::string classname;
00083 mutable typename std::deque<T>::iterator it;
00084 mutable int itPos;
00085 public:
00086 cDequeWatcher(const char *name, std::deque<T>& var) : cStdVectorWatcherBase(name), v(var) {
00087 itPos=-1;
00088 classname = std::string("deque<")+opp_typename(typeid(T))+">";
00089 }
00090 const char *className() const {return classname.c_str();}
00091 virtual const char *getElemTypeName() const {return opp_typename(typeid(T));}
00092 virtual int size() const {return v.size();}
00093 virtual std::string at(int i) const {
00094 if (i==0) {
00095 it=v.begin(); itPos=0;
00096 } else if (i==itPos+1 && it!=v.end()) {
00097 ++it; ++itPos;
00098 } else {
00099 it=v.begin();
00100 for (int k=0; k<i && it!=v.end(); k++) ++it;
00101 itPos=i;
00102 }
00103 if (it==v.end()) {
00104 return std::string("out of bounds");
00105 }
00106 return atIt();
00107 }
00108 virtual std::string atIt() const {
00109 std::stringstream out;
00110 out << (*it);
00111 return out.str();
00112 }
00113 };
00114
00115 template <class T>
00116 void createDequeWatcher(const char *varname, std::deque<T>& v)
00117 {
00118 new cDequeWatcher<T>(varname, v);
00119 };
00120
00121 template<class KeyT, class ValueT, class CmpT>
00122 class SIM_API cHashMapWatcher : public cStdVectorWatcherBase
00123 {
00124 protected:
00125 UNORDERED_MAP<KeyT,ValueT,CmpT>& m;
00126 mutable typename UNORDERED_MAP<KeyT,ValueT,CmpT>::iterator it;
00127 mutable int itPos;
00128 std::string classname;
00129 public:
00130 cHashMapWatcher(const char *name, UNORDERED_MAP<KeyT,ValueT,CmpT>& var) : cStdVectorWatcherBase(name), m(var) {
00131 itPos=-1;
00132 classname = std::string("unordered_map<")+opp_typename(typeid(KeyT))+","+opp_typename(typeid(ValueT))+">";
00133 }
00134 const char *getClassName() const {return classname.c_str();}
00135 virtual const char *getElemTypeName() const {return "struct pair<*,*>";}
00136 virtual int size() const {return m.size();}
00137 virtual std::string at(int i) const {
00138 if (i==0) {
00139 it=m.begin(); itPos=0;
00140 } else if (i==itPos+1 && it!=m.end()) {
00141 ++it; ++itPos;
00142 } else {
00143 it=m.begin();
00144 for (int k=0; k<i && it!=m.end(); k++) ++it;
00145 itPos=i;
00146 }
00147 if (it==m.end()) {
00148 return std::string("out of bounds");
00149 }
00150 return atIt();
00151 }
00152 virtual std::string atIt() const {
00153 std::stringstream out;
00154 out << it->first << " ==> " << it->second;
00155 return out.str();
00156 }
00157 };
00158
00159 template <class KeyT, class ValueT, class CmpT>
00160 void createHashMapWatcher(const char *varname, UNORDERED_MAP<KeyT,ValueT,CmpT>& m)
00161 {
00162 new cHashMapWatcher<KeyT,ValueT,CmpT>(varname, m);
00163 };
00164
00165 template<class KeyT, class ValueT, class CmpT>
00166 class SIM_API cPointerMapWatcher : public cStdVectorWatcherBase
00167 {
00168 protected:
00169 std::map<KeyT,ValueT,CmpT>& m;
00170 mutable typename std::map<KeyT,ValueT,CmpT>::iterator it;
00171 mutable int itPos;
00172 std::string classname;
00173 public:
00174 cPointerMapWatcher(const char *name, std::map<KeyT,ValueT,CmpT>& var) : cStdVectorWatcherBase(name), m(var) {
00175 itPos=-1;
00176 classname = std::string("pointer_map<")+opp_typename(typeid(KeyT))+","+opp_typename(typeid(ValueT))+">";
00177 }
00178 const char *getClassName() const {return classname.c_str();}
00179 virtual const char *getElemTypeName() const {return "struct pair<*,*>";}
00180 virtual int size() const {return m.size();}
00181 virtual std::string at(int i) const {
00182 if (i==0) {
00183 it=m.begin(); itPos=0;
00184 } else if (i==itPos+1 && it!=m.end()) {
00185 ++it; ++itPos;
00186 } else {
00187 it=m.begin();
00188 for (int k=0; k<i && it!=m.end(); k++) ++it;
00189 itPos=i;
00190 }
00191 if (it==m.end()) {
00192 return std::string("out of bounds");
00193 }
00194 return atIt();
00195 }
00196 virtual std::string atIt() const {
00197 std::stringstream out;
00198 out << it->first << " ==> " << *(it->second);
00199 return out.str();
00200 }
00201 };
00202
00203 template <class KeyT, class ValueT, class CmpT>
00204 void createPointerMapWatcher(const char *varname, std::map<KeyT,ValueT,CmpT>& m)
00205 {
00206 new cPointerMapWatcher<KeyT,ValueT,CmpT>(varname, m);
00207 };
00208
00209 template<class KeyT, class ValueT, class CmpT>
00210 class cStdMultiMapWatcher : public cStdVectorWatcherBase
00211 {
00212 protected:
00213 std::multimap<KeyT,ValueT,CmpT>& m;
00214 mutable typename std::multimap<KeyT,ValueT,CmpT>::iterator it;
00215 mutable int itPos;
00216 std::string classname;
00217 public:
00218 cStdMultiMapWatcher(const char *name, std::multimap<KeyT,ValueT,CmpT>& var) : cStdVectorWatcherBase(name), m(var) {
00219 itPos=-1;
00220 classname = std::string("std::multimap<")+opp_typename(typeid(KeyT))+","+opp_typename(typeid(ValueT))+">";
00221 }
00222 const char *getClassName() const {return classname.c_str();}
00223 virtual const char *getElemTypeName() const {return "struct pair<*,*>";}
00224 virtual int size() const {return m.size();}
00225 virtual std::string at(int i) const {
00226
00227
00228
00229 if (i==0) {
00230 it=m.begin(); itPos=0;
00231 } else if (i==itPos+1 && it!=m.end()) {
00232 ++it; ++itPos;
00233 } else {
00234 it=m.begin();
00235 for (int k=0; k<i && it!=m.end(); k++) ++it;
00236 itPos=i;
00237 }
00238 if (it==m.end()) {
00239 return std::string("out of bounds");
00240 }
00241 return atIt();
00242 }
00243 virtual std::string atIt() const {
00244 std::stringstream out;
00245 out << it->first << " ==> " << it->second;
00246 return out.str();
00247 }
00248 };
00249
00250 template <class KeyT, class ValueT, class CmpT>
00251 void createStdMultiMapWatcher(const char *varname, std::multimap<KeyT,ValueT,CmpT>& m)
00252 {
00253 new cStdMultiMapWatcher<KeyT,ValueT,CmpT>(varname, m);
00254 };
00255
00256
00262 #define WATCH_UNORDERED_SET(variable) createHashSetWatcher(#variable,(variable))
00263
00269 #define WATCH_DEQUE(variable) createDequeWatcher(#variable,(variable))
00270
00276 #define WATCH_UNORDERED_MAP(m) createHashMapWatcher(#m,(m))
00277
00283 #define WATCH_POINTER_MAP(m) createPointerMapWatcher(#m,(m))
00284
00290 #define WATCH_MULTIMAP(m) createStdMultiMapWatcher(#m,(m))
00291
00292 #endif