cwatch.h

00001 //==========================================================================
00002 //  CWATCH.H - part of
00003 //                     OMNeT++/OMNEST
00004 //            Discrete System Simulation in C++
00005 //
00006 //
00007 //  Declaration of the following classes:
00008 //    cWatchBase etc: make primitive types, structs etc inspectable
00009 //
00010 //==========================================================================
00011 
00012 /*--------------------------------------------------------------*
00013   Copyright (C) 1992-2008 Andras Varga
00014   Copyright (C) 2006-2008 OpenSim Ltd.
00015 
00016   This file is distributed WITHOUT ANY WARRANTY. See the file
00017   `license' for details on this and other legal matters.
00018 *--------------------------------------------------------------*/
00019 
00020 #ifndef __CWATCH_H
00021 #define __CWATCH_H
00022 
00023 #include <iostream>
00024 #include <sstream>
00025 #include "cownedobject.h"
00026 
00027 NAMESPACE_BEGIN
00028 
00029 
00037 class SIM_API cWatchBase : public cNoncopyableOwnedObject
00038 {
00039   public:
00045     cWatchBase(const char *name)  : cNoncopyableOwnedObject(name) {}
00047 
00053     virtual bool supportsAssignment() const = 0;
00054 
00059     virtual void assign(const char *s) {}
00061 };
00062 
00063 
00068 template<typename T>
00069 class cGenericReadonlyWatch : public cWatchBase
00070 {
00071   private:
00072     const T& r;
00073   public:
00074     cGenericReadonlyWatch(const char *name, const T& x) : cWatchBase(name), r(x) {}
00075     virtual const char *getClassName() const {return opp_typename(typeid(T));}
00076     virtual bool supportsAssignment() const {return false;}
00077     virtual std::string info() const
00078     {
00079         std::stringstream out;
00080         out << r;
00081         return out.str();
00082     }
00083 };
00084 
00085 
00091 template<typename T>
00092 class cGenericAssignableWatch : public cWatchBase
00093 {
00094   private:
00095     T& r;
00096   public:
00097     cGenericAssignableWatch(const char *name, T& x) : cWatchBase(name), r(x) {}
00098     virtual const char *getClassName() const {return opp_typename(typeid(T));}
00099     virtual bool supportsAssignment() const {return true;}
00100     virtual std::string info() const
00101     {
00102         std::stringstream out;
00103         out << r;
00104         return out.str();
00105     }
00106     virtual void assign(const char *s)
00107     {
00108         std::stringstream in(s);
00109         in >> r;
00110     }
00111 };
00112 
00117 class SIM_API cWatch_bool : public cWatchBase
00118 {
00119   private:
00120     bool& r;
00121   public:
00122     cWatch_bool(const char *name, bool& x) : cWatchBase(name), r(x) {}
00123     virtual const char *getClassName() const {return "bool";}
00124     virtual bool supportsAssignment() const {return true;}
00125     virtual std::string info() const
00126     {
00127         return r ? "true" : "false";
00128     }
00129     virtual void assign(const char *s)
00130     {
00131         r = *s!='0' && *s!='n' && *s!='N' && *s!='f' && *s!='F';
00132     }
00133 };
00134 
00139 class SIM_API cWatch_char : public cWatchBase
00140 {
00141   private:
00142     char& r;
00143   public:
00144     cWatch_char(const char *name, char& x) : cWatchBase(name), r(x) {}
00145     virtual const char *getClassName() const {return "char";}
00146     virtual bool supportsAssignment() const {return true;}
00147     virtual std::string info() const
00148     {
00149         std::stringstream out;
00150         out << "'" << ((unsigned char)r<32 ? ' ' : r) << "' (" << int(r) << ")";
00151         return out.str();
00152     }
00153     virtual void assign(const char *s)
00154     {
00155         if (s[0]=='\'')
00156             r = s[1];
00157         else
00158             r = atoi(s);
00159     }
00160 };
00161 
00166 class SIM_API cWatch_uchar : public cWatchBase
00167 {
00168   private:
00169     unsigned char& r;
00170   public:
00171     cWatch_uchar(const char *name, unsigned char& x) : cWatchBase(name), r(x) {}
00172     virtual const char *getClassName() const {return "unsigned char";}
00173     virtual bool supportsAssignment() const {return true;}
00174     virtual std::string info() const
00175     {
00176         std::stringstream out;
00177         out << "'" << (char)(r<' ' ? ' ' : r) << "' (" << int(r) << ")";
00178         return out.str();
00179     }
00180     virtual void assign(const char *s)
00181     {
00182         if (s[0]=='\'')
00183             r = s[1];
00184         else
00185             r = atoi(s);
00186     }
00187 };
00188 
00193 class SIM_API cWatch_stdstring : public cWatchBase
00194 {
00195   private:
00196     std::string& r;
00197   public:
00198     cWatch_stdstring(const char *name, std::string& x) : cWatchBase(name), r(x) {}
00199     virtual const char *getClassName() const {return "std::string";}
00200     virtual bool supportsAssignment() const {return true;}
00201     virtual std::string info() const;
00202     virtual void assign(const char *s);
00203 };
00204 
00209 class SIM_API cWatch_cObject : public cWatchBase
00210 {
00211   private:
00212     cObject& r;
00213   public:
00214     cWatch_cObject(const char *name, cObject& ref) : cWatchBase(name), r(ref) {}
00215     virtual const char *getClassName() const {return r.getClassName();}
00216     virtual std::string info() const {return r.info();}
00217     virtual bool supportsAssignment() const {return false;}
00218     virtual cClassDescriptor *getDescriptor() {return r.getDescriptor();}
00219 };
00220 
00225 class SIM_API cWatch_cObjectPtr : public cWatchBase
00226 {
00227   private:
00228     cObject *&rp;
00229   public:
00230     cWatch_cObjectPtr(const char *name, cObject *&ptr) : cWatchBase(name), rp(ptr) {}
00231     virtual const char *getClassName() const {return rp? rp->getClassName() : "n/a";}
00232     virtual std::string info() const {return rp ? rp->info() : "<null>";}
00233     virtual bool supportsAssignment() const {return false;}
00234     virtual cClassDescriptor *getDescriptor() {return rp ? rp->getDescriptor() : NULL;}
00235 };
00236 
00237 
00238 inline cWatchBase *createWatch(const char *varname, short& d) {
00239     return new cGenericAssignableWatch<short>(varname, d);
00240 }
00241 
00242 inline cWatchBase *createWatch(const char *varname, unsigned short& d) {
00243     return new cGenericAssignableWatch<unsigned short>(varname, d);
00244 }
00245 
00246 inline cWatchBase *createWatch(const char *varname, int& d) {
00247     return new cGenericAssignableWatch<int>(varname, d);
00248 }
00249 
00250 inline cWatchBase *createWatch(const char *varname, unsigned int& d) {
00251     return new cGenericAssignableWatch<unsigned int>(varname, d);
00252 }
00253 
00254 inline cWatchBase *createWatch(const char *varname, long& d) {
00255     return new cGenericAssignableWatch<long>(varname, d);
00256 }
00257 
00258 inline cWatchBase *createWatch(const char *varname, unsigned long& d) {
00259     return new cGenericAssignableWatch<unsigned long>(varname, d);
00260 }
00261 
00262 inline cWatchBase *createWatch(const char *varname, float& d) {
00263     return new cGenericAssignableWatch<float>(varname, d);
00264 }
00265 
00266 inline cWatchBase *createWatch(const char *varname, double& d) {
00267     return new cGenericAssignableWatch<double>(varname, d);
00268 }
00269 
00270 inline cWatchBase *createWatch(const char *varname, bool& d) {
00271     return new cWatch_bool(varname, d);
00272 }
00273 
00274 inline cWatchBase *createWatch(const char *varname, char& d) {
00275     return new cWatch_char(varname, d);
00276 }
00277 
00278 inline cWatchBase *createWatch(const char *varname, unsigned char& d) {
00279     return new cWatch_uchar(varname, d);
00280 }
00281 
00282 inline cWatchBase *createWatch(const char *varname, signed char& d) {
00283     return new cWatch_char(varname, *(char *)&d);
00284 }
00285 
00286 inline cWatchBase *createWatch(const char *varname, std::string& v) {
00287     return new cWatch_stdstring(varname, v);
00288 }
00289 
00290 // this is the fallback, if none of the above match
00291 template<typename T>
00292 inline cWatchBase *createWatch(const char *varname, T& d) {
00293     return new cGenericReadonlyWatch<T>(varname, d);
00294 }
00295 
00296 // to be used if T also has op>> defined
00297 template<typename T>
00298 inline cWatchBase *createWatch_genericAssignable(const char *varname, T& d) {
00299     return new cGenericAssignableWatch<T>(varname, d);
00300 }
00301 
00302 // for objects
00303 inline cWatchBase *createWatch_cObject(const char *varname, cObject& obj) {
00304     return new cWatch_cObject(varname, obj);
00305 }
00306 
00307 // for pointers to objects.
00308 // NOTE: this is a bit tricky. C++ thinks that (cObject*&) and
00309 // (SomeDerivedType*&) are unrelated, so we have to force the cast
00310 // in the WATCH_PTR() macro. But to stay type-safe, we include a 3rd arg
00311 // of type cObject*: the compiler has to be able to cast that
00312 // implicitly from SomeDerivedType* -- this way we do not accept pointers
00313 // that are REALLY unrelated.
00314 inline cWatchBase *createWatch_cObjectPtr(const char *varname, cObject *&refp, cObject *p) {
00315     ASSERT(refp==p);
00316     return new cWatch_cObjectPtr(varname, refp);
00317 }
00318 
00319 
00325 
00333 #define WATCH(variable)    createWatch(#variable,(variable))
00334 
00341 #define WATCH_RW(variable) createWatch_genericAssignable(#variable,(variable))
00342 
00349 #define WATCH_OBJ(variable) createWatch_cObject(#variable,(variable))
00350 
00357 #define WATCH_PTR(variable) createWatch_cObjectPtr(#variable,(cObject*&)(variable),(variable))
00358 
00359 
00360 NAMESPACE_END
00361 
00362 
00363 #endif
00364 
00365 
Generated on Tue Dec 2 11:16:27 2014 for OMNeT++ Simulation Library by  doxygen 1.6.3