# 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