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-2005 Andras Varga
00014 
00015   This file is distributed WITHOUT ANY WARRANTY. See the file
00016   `license' for details on this and other legal matters.
00017 *--------------------------------------------------------------*/
00018 
00019 #ifndef __CWATCH_H
00020 #define __CWATCH_H
00021 
00022 #include <iostream>
00023 #include <sstream>
00024 #include "cobject.h"
00025 
00026 
00034 class SIM_API cWatchBase : public cObject
00035 {
00036   public:
00042     cWatchBase(const char *name)  : cObject(name) {}
00043 
00047     cWatchBase(const cWatchBase& v) : cObject(v.name()) {operator=(v);}
00048 
00052     cWatchBase& operator=(const cWatchBase&) {copyNotSupported();return *this;}
00053 
00057     virtual cPolymorphic *dup() const {copyNotSupported(); return NULL;}
00059 
00065     virtual bool supportsAssignment() const = 0;
00066 
00071     virtual void assign(const char *s) {}
00073 };
00074 
00075 
00080 template<typename T>
00081 class SIM_API cGenericReadonlyWatch : public cWatchBase
00082 {
00083   private:
00084     const T& r;
00085   public:
00086     cGenericReadonlyWatch(const char *name, const T& x) : cWatchBase(name), r(x) {}
00087     virtual const char *className() const {return opp_typename(typeid(T));}
00088     virtual bool supportsAssignment() const {return false;}
00089     virtual std::string info() const
00090     {
00091         std::stringstream out;
00092         out << r;
00093         return out.str();
00094     }
00095 };
00096 
00097 
00103 template<typename T>
00104 class SIM_API cGenericAssignableWatch : public cWatchBase
00105 {
00106   private:
00107     T& r;
00108   public:
00109     cGenericAssignableWatch(const char *name, T& x) : cWatchBase(name), r(x) {}
00110     virtual const char *className() const {return opp_typename(typeid(T));}
00111     virtual bool supportsAssignment() const {return true;}
00112     virtual std::string info() const
00113     {
00114         std::stringstream out;
00115         out << r;
00116         return out.str();
00117     }
00118     virtual void assign(const char *s)
00119     {
00120         std::stringstream in(s);
00121         in >> r;
00122     }
00123 };
00124 
00129 class SIM_API cWatch_bool : public cWatchBase
00130 {
00131   private:
00132     bool& r;
00133   public:
00134     cWatch_bool(const char *name, bool& x) : cWatchBase(name), r(x) {}
00135     virtual const char *className() const {return "bool";}
00136     virtual bool supportsAssignment() const {return true;}
00137     virtual std::string info() const
00138     {
00139         return r ? "true" : "false";
00140     }
00141     virtual void assign(const char *s)
00142     {
00143         r = *s!='0' && *s!='n' && *s!='N' && *s!='f' && *s!='F';
00144     }
00145 };
00146 
00151 class SIM_API cWatch_char : public cWatchBase
00152 {
00153   private:
00154     char& r;
00155   public:
00156     cWatch_char(const char *name, char& x) : cWatchBase(name), r(x) {}
00157     virtual const char *className() const {return "char";}
00158     virtual bool supportsAssignment() const {return true;}
00159     virtual std::string info() const
00160     {
00161         std::stringstream out;
00162         out << "'" << (r>=0&&r<' '?' ':r) << "' (" << int(r) << ")";
00163         return out.str();
00164     }
00165     virtual void assign(const char *s)
00166     {
00167         if (s[0]=='\'')
00168             r = s[1];
00169         else
00170             r = atoi(s);
00171     }
00172 };
00173 
00178 class SIM_API cWatch_uchar : public cWatchBase
00179 {
00180   private:
00181     unsigned char& r;
00182   public:
00183     cWatch_uchar(const char *name, unsigned char& x) : cWatchBase(name), r(x) {}
00184     virtual const char *className() const {return "unsigned char";}
00185     virtual bool supportsAssignment() const {return true;}
00186     virtual std::string info() const
00187     {
00188         std::stringstream out;
00189         out << "'" << (char)(r<' '?' ':r) << "' (" << int(r) << ")";
00190         return out.str();
00191     }
00192     virtual void assign(const char *s)
00193     {
00194         if (s[0]=='\'')
00195             r = s[1];
00196         else
00197             r = atoi(s);
00198     }
00199 };
00200 
00205 class SIM_API cWatch_stdstring : public cWatchBase
00206 {
00207   private:
00208     std::string& r;
00209   public:
00210     cWatch_stdstring(const char *name, std::string& x) : cWatchBase(name), r(x) {}
00211     virtual const char *className() const {return "std::string";}
00212     virtual bool supportsAssignment() const {return true;}
00213     virtual std::string info() const
00214     {
00215         std::stringstream out;
00216         out << "\"" << r << "\"";
00217         return out.str();
00218     }
00219     virtual void assign(const char *s)
00220     {
00221         if (s[0]=='"' && s[strlen(s)-1]=='"')
00222             r.assign(s+1, strlen(s)-2);
00223         else
00224             r = s;
00225     }
00226 };
00227 
00232 class SIM_API cWatch_cPolymorphic : public cWatchBase
00233 {
00234   private:
00235     cPolymorphic& r;
00236   public:
00237     cWatch_cPolymorphic(const char *name, cPolymorphic& ref) : cWatchBase(name), r(ref) {}
00238     virtual const char *className() const {return r.className();}
00239     virtual std::string info() const {return r.info();}
00240     virtual bool supportsAssignment() const {return false;}
00241     virtual cStructDescriptor *createDescriptor() {return r.createDescriptor();}
00242 };
00243 
00248 class SIM_API cWatch_cPolymorphicPtr : public cWatchBase
00249 {
00250   private:
00251     cPolymorphic *&rp;
00252   public:
00253     cWatch_cPolymorphicPtr(const char *name, cPolymorphic *&ptr) : cWatchBase(name), rp(ptr) {}
00254     virtual const char *className() const {return rp? rp->className() : "n/a";}
00255     virtual std::string info() const {return rp ? rp->info() : "<null>";}
00256     virtual bool supportsAssignment() const {return false;}
00257     virtual cStructDescriptor *createDescriptor() {return rp ? rp->createDescriptor() : NULL;}
00258 };
00259 
00260 
00261 inline cWatchBase *createWatch(const char *varname, short& d) {
00262     return new cGenericAssignableWatch<short>(varname, d);
00263 }
00264 
00265 inline cWatchBase *createWatch(const char *varname, unsigned short& d) {
00266     return new cGenericAssignableWatch<unsigned short>(varname, d);
00267 }
00268 
00269 inline cWatchBase *createWatch(const char *varname, int& d) {
00270     return new cGenericAssignableWatch<int>(varname, d);
00271 }
00272 
00273 inline cWatchBase *createWatch(const char *varname, unsigned int& d) {
00274     return new cGenericAssignableWatch<unsigned int>(varname, d);
00275 }
00276 
00277 inline cWatchBase *createWatch(const char *varname, long& d) {
00278     return new cGenericAssignableWatch<long>(varname, d);
00279 }
00280 
00281 inline cWatchBase *createWatch(const char *varname, unsigned long& d) {
00282     return new cGenericAssignableWatch<unsigned long>(varname, d);
00283 }
00284 
00285 inline cWatchBase *createWatch(const char *varname, float& d) {
00286     return new cGenericAssignableWatch<float>(varname, d);
00287 }
00288 
00289 inline cWatchBase *createWatch(const char *varname, double& d) {
00290     return new cGenericAssignableWatch<double>(varname, d);
00291 }
00292 
00293 inline cWatchBase *createWatch(const char *varname, bool& d) {
00294     return new cWatch_bool(varname, d);
00295 }
00296 
00297 inline cWatchBase *createWatch(const char *varname, char& d) {
00298     return new cWatch_char(varname, d);
00299 }
00300 
00301 inline cWatchBase *createWatch(const char *varname, unsigned char& d) {
00302     return new cWatch_uchar(varname, d);
00303 }
00304 
00305 inline cWatchBase *createWatch(const char *varname, signed char& d) {
00306     return new cWatch_char(varname, *(char *)&d);
00307 }
00308 
00309 inline cWatchBase *createWatch(const char *varname, std::string& v) {
00310     return new cWatch_stdstring(varname, v);
00311 }
00312 
00313 // this is the fallback, if none of the above match
00314 template<typename T>
00315 inline cWatchBase *createWatch(const char *varname, T& d) {
00316     return new cGenericReadonlyWatch<T>(varname, d);
00317 }
00318 
00319 // to be used if T also has op>> defined
00320 template<typename T>
00321 inline cWatchBase *createWatch_genericAssignable(const char *varname, T& d) {
00322     return new cGenericAssignableWatch<T>(varname, d);
00323 }
00324 
00325 // for objects
00326 inline cWatchBase *createWatch_cPolymorphic(const char *varname, cPolymorphic& obj) {
00327     return new cWatch_cPolymorphic(varname, obj);
00328 }
00329 
00330 // for pointers to objects.
00331 // NOTE: this is a bit tricky. C++ thinks that (cPolymorphic*&) and
00332 // (SomeDerivedType*&) are unrelated, so we have to force the cast
00333 // in the WATCH_PTR() macro. But to stay type-safe, we include a 3rd arg
00334 // of type cPolymorphic*: the compiler has to be able to cast that
00335 // implicitly from SomeDerivedType* -- this way we don't accept pointers
00336 // that are REALLY unrelated.
00337 inline cWatchBase *createWatch_cPolymorphicPtr(const char *varname, cPolymorphic *&refp, cPolymorphic *p) {
00338     ASSERT(refp==p);
00339     return new cWatch_cPolymorphicPtr(varname, refp);
00340 }
00341 
00342 
00348 
00356 #define WATCH(variable)    createWatch(#variable,(variable))
00357 
00364 #define WATCH_RW(variable) createWatch_genericAssignable(#variable,(variable))
00365 
00372 #define WATCH_OBJ(variable) createWatch_cPolymorphic(#variable,(variable))
00373 
00380 #define WATCH_PTR(variable) createWatch_cPolymorphicPtr(#variable,(cPolymorphic*&)(variable),(variable))
00381 
00382 
00383 #endif
00384 
00385 

Generated on Sat Oct 21 17:47:56 2006 for OMNeT++/OMNEST Simulation Library by  doxygen 1.4.6