Main Page | Modules | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

Element.h

00001 // This file may be redistributed and modified only under the terms of
00002 // the GNU Lesser General Public License (See COPYING for details).
00003 // Copyright (C) 2000-2001 Stefanus Du Toit, Karsten-O. Laux and Al Riddoch
00004 
00005 #ifndef ATLAS_MESSAGE_ELEMENT_H
00006 #define ATLAS_MESSAGE_ELEMENT_H
00007 
00008 #include <Atlas/Exception.h>
00009 
00010 #include <string>
00011 #include <map>
00012 #include <vector>
00013 
00014 namespace Atlas { namespace Message {
00015 
00017 class WrongTypeException : public Atlas::Exception
00018 {
00019   public:
00020     WrongTypeException() : Atlas::Exception("Wrong Message::Element type") { }
00021 };
00022 
00023 class Element;
00024 
00025 typedef long IntType;
00026 typedef double FloatType;
00027 typedef void * PtrType;
00028 typedef std::string StringType;
00029 typedef std::map<std::string, Element> MapType;
00030 typedef std::vector<Element> ListType;
00031 
00057 class Element
00058 {
00059 public:
00060     enum Type {
00061         TYPE_NONE,
00062         TYPE_INT,
00063         TYPE_FLOAT,
00064         TYPE_PTR,
00065         TYPE_STRING,
00066         TYPE_MAP,
00067         TYPE_LIST
00068     };
00069 
00070 private:
00071     // These are now legacy typedefs. New code should use the
00072     // Atlas::Message::*Type versions.
00073     typedef Atlas::Message::IntType IntType;
00074     typedef Atlas::Message::FloatType FloatType;
00075     typedef Atlas::Message::PtrType PtrType;
00076     typedef Atlas::Message::StringType StringType;
00077     typedef Atlas::Message::MapType MapType;
00078     typedef Atlas::Message::ListType ListType;
00079 
00081     void clear(Type new_type = TYPE_NONE);
00082 
00083 public:
00085     Element()
00086       : t(TYPE_NONE)
00087     {
00088     }
00089 
00091     ~Element()
00092     {
00093         clear();
00094     }
00095 
00097     Element(const Element& obj);
00098 
00100     Element(int v)
00101       : t(TYPE_INT), i(v)
00102     {
00103     }
00104 
00106     Element(bool v)
00107       : t(TYPE_INT), i(v)
00108     {
00109     }
00110 
00112     Element(IntType v)
00113       : t(TYPE_INT), i(v)
00114     {
00115     }
00116 
00118     Element(float v)
00119       : t(TYPE_FLOAT), f(v)
00120     {
00121     }   
00122 
00124     Element(FloatType v)
00125       : t(TYPE_FLOAT), f(v)
00126     {
00127     }
00128 
00130     Element(PtrType v)
00131       : t(TYPE_PTR), p(v)
00132     {
00133     }
00134 
00136     Element(const char* v)
00137       : t(TYPE_STRING)
00138     {
00139       if(v)
00140         s = new DataType<StringType>(v);
00141       else
00142         s = new DataType<StringType>();
00143     }
00144 
00146     Element(const StringType& v)
00147       : t(TYPE_STRING)
00148     {
00149       s = new DataType<StringType>(v);
00150     }
00152     Element(const MapType& v)
00153       : t(TYPE_MAP)
00154     {
00155       m = new DataType<MapType>(v);
00156     }
00158     Element(const ListType& v)
00159       : t(TYPE_LIST)
00160     {
00161       l = new DataType<ListType>(v);
00162     }
00163 
00165     Element& operator=(const Element& obj);
00166 
00167     Element& operator=(int v) 
00168     {
00169       if (TYPE_INT != t)
00170       {
00171         clear(TYPE_INT);
00172       }
00173       i = v;
00174       return *this;
00175     }
00176 
00177     Element& operator=(bool v) 
00178     {
00179       if (TYPE_INT != t)
00180       {
00181         clear(TYPE_INT);
00182       }
00183       i = v;
00184       return *this;
00185     }
00186 
00187     Element& operator=(IntType v) 
00188     {
00189       if (TYPE_INT != t)
00190       {
00191         clear(TYPE_INT);
00192       }
00193       i = v;
00194       return *this;
00195     }
00196 
00197     Element& operator=(float v) 
00198     {
00199       if (TYPE_FLOAT != t)
00200       {
00201         clear(TYPE_FLOAT);
00202       }
00203       f = v;
00204       return *this;
00205     }
00206 
00207     Element& operator=(FloatType v) 
00208     {
00209       if (TYPE_FLOAT != t)
00210       {
00211         clear(TYPE_FLOAT);
00212       }
00213       f = v;
00214       return *this;
00215     }
00216 
00217     Element& operator=(PtrType v) 
00218     {
00219       if (TYPE_PTR != t)
00220       {
00221         clear(TYPE_PTR);
00222       }
00223       p = v;
00224       return *this;
00225     }
00226 
00227     Element& operator=(const char * v) 
00228     {
00229       if (TYPE_STRING != t || !s->unique())
00230       {
00231         clear(TYPE_STRING);
00232         s = new DataType<StringType>(v);
00233       } else {
00234         *s = StringType(v);
00235       }
00236       return *this;
00237     }
00238 
00239     Element& operator=(const StringType & v) 
00240     {
00241       if (TYPE_STRING != t || !s->unique())
00242       {
00243         clear(TYPE_STRING);
00244         s = new DataType<StringType>(v);
00245       } else {
00246         *s = v;
00247       }
00248       return *this;
00249     }
00250 
00251     Element& operator=(const MapType & v) 
00252     {
00253       if (TYPE_MAP != t || !m->unique())
00254       {
00255         clear(TYPE_MAP);
00256         m = new DataType<MapType>(v);
00257       } else {
00258         *m = v;
00259       }
00260       return *this;
00261     }
00262 
00263     Element& operator=(const ListType & v) 
00264     {
00265       if (TYPE_LIST != t || !l->unique())
00266       {
00267         clear(TYPE_LIST);
00268         l = new DataType<ListType>(v);
00269       } else {
00270         *l = v;
00271       }
00272       return *this;
00273     }
00274 
00276     bool operator==(const Element& o) const;
00277 
00278 #if defined(__GNUC__) && __GNUC__ < 3
00279     bool operator!=(const Element& o) const
00280     {
00281         return !(*this == o);
00282     }
00283 #endif // defined(__GNUC__) && __GNUC__ < 3
00284     
00286     template<class C>
00287     bool operator!=(C c) const
00288     {
00289         return !(*this == c);
00290     }
00291 
00293     bool operator==(IntType v) const
00294     {
00295       return (t == TYPE_INT && i == v);
00296     }
00297 
00299     bool operator==(FloatType v) const
00300     {
00301       return t == TYPE_FLOAT && f == v;
00302     }
00303 
00305     bool operator==(PtrType v) const
00306     {
00307       return t == TYPE_PTR && p == v;
00308     }
00309 
00311     bool operator==(const char * v) const
00312     {
00313       if(t == TYPE_STRING)
00314         return (*s == v);
00315       return false;
00316     }
00317 
00319     bool operator==(const StringType& v) const
00320     {
00321       if(t == TYPE_STRING)
00322         return (*s == v);
00323       return false;
00324     }
00325 
00327     bool operator==(const MapType& v) const
00328     {
00329       if(t == TYPE_MAP)
00330         return (*m == v);
00331       return false;
00332     }
00333 
00335     bool operator==(const ListType& v) const
00336     {
00337       if (t == TYPE_LIST)
00338         return (*l == v);
00339       return false;
00340     }
00341 
00343     Type getType() const { return t; }
00345     bool isNone() const { return (t == TYPE_NONE); }
00347     bool isInt() const { return (t == TYPE_INT); }
00349     bool isFloat() const { return (t == TYPE_FLOAT); }
00351     bool isPtr() const { return (t == TYPE_PTR); }
00353     bool isNum() const { return ((t == TYPE_FLOAT) || (t == TYPE_INT)); }
00355     bool isString() const { return (t == TYPE_STRING); }
00357     bool isMap() const { return (t == TYPE_MAP); }
00359     bool isList() const { return (t == TYPE_LIST); }
00360 
00362     IntType asInt() const throw (WrongTypeException)
00363     {
00364         if (t == TYPE_INT) return i;
00365         throw WrongTypeException();
00366     }
00367     IntType Int() const
00368     {
00369         return i;
00370     }
00372     FloatType asFloat() const throw (WrongTypeException)
00373     {
00374         if (t == TYPE_FLOAT) return f;
00375         throw WrongTypeException();
00376     }
00377     FloatType Float() const
00378     {
00379         return f;
00380     }
00382     PtrType asPtr() const throw (WrongTypeException)
00383     {
00384         if (t == TYPE_PTR) return p;
00385         throw WrongTypeException();
00386     }
00387     PtrType Ptr() const
00388     {
00389         return p;
00390     }
00392     FloatType asNum() const throw (WrongTypeException)
00393     {
00394         if (t == TYPE_FLOAT) return f;
00395         if (t == TYPE_INT) return FloatType(i);
00396         throw WrongTypeException();
00397     }
00399     const std::string& asString() const throw (WrongTypeException)
00400     {
00401         if (t == TYPE_STRING) return *s;
00402         throw WrongTypeException();
00403     }
00405     std::string& asString() throw (WrongTypeException)
00406     {
00407         if (t == TYPE_STRING) return *(s = s->makeUnique());
00408         throw WrongTypeException();
00409     }
00410     const StringType& String() const
00411     {
00412         return *s;
00413     }
00414     StringType& String()
00415     {
00416         return *(s = s->makeUnique());
00417     }
00419     const MapType& asMap() const throw (WrongTypeException)
00420     {
00421         if (t == TYPE_MAP) return *m;
00422         throw WrongTypeException();
00423     }
00425     MapType& asMap() throw (WrongTypeException)
00426     {
00427         if (t == TYPE_MAP) return *(m = m->makeUnique());
00428         throw WrongTypeException();
00429     }
00430     const MapType& Map() const
00431     {
00432         return *m;
00433     }
00434     MapType& Map()
00435     {
00436         return *(m = m->makeUnique());
00437     }
00439     const ListType& asList() const throw (WrongTypeException)
00440     {
00441         if (t == TYPE_LIST) return *l;
00442         throw WrongTypeException();
00443     }
00445     ListType& asList() throw (WrongTypeException)
00446     {
00447         if (t == TYPE_LIST) return *(l = l->makeUnique());
00448         throw WrongTypeException();
00449     }
00450     const ListType& List() const
00451     {
00452         return *l;
00453     }
00454     ListType& List()
00455     {
00456         return *(l = l->makeUnique());
00457     }
00458 
00459     static const char * typeName(Type);
00460 
00461 protected:
00462 
00463     template<class C>
00464     class DataType
00465     {
00466     public:
00467         DataType() : _refcount(1) {}
00468         DataType(const C& c) : _refcount(1), _data(c) {}
00469 
00470         DataType& operator=(const C& c) {_data = c; return *this;}
00471 
00472         bool operator==(const C& c) const {return _data == c;}
00473 
00474         void ref() {++_refcount;}
00475         void unref() {if(--_refcount == 0) delete this;}
00476 
00477         bool unique() const {return _refcount == 1;}
00478         DataType* makeUnique()
00479         {
00480            if(unique())
00481                return this;
00482            unref(); // _refcount > 1, so this is fine
00483            return new DataType(_data);
00484         }
00485 
00486         operator C&() {return _data;}
00487 //        operator const C&() const {return _data;}
00488 
00489     private:
00490         DataType(const DataType&); // unimplemented
00491         DataType& operator=(const DataType&); // unimplemented
00492 
00493         unsigned long _refcount;
00494         C _data;
00495     };
00496 
00497     Type t;
00498     union {
00499       IntType i;
00500       FloatType f;
00501       void* p;
00502       DataType<StringType>* s;
00503       DataType<MapType>* m;
00504       DataType<ListType>* l;
00505     };
00506 };
00507 
00508 } } // namespace Atlas::Message
00509 
00510 
00511 #endif // ATLAS_MESSAGE_ELEMENT_H

Copyright 2000-2004 the respective authors.

This document can be licensed under the terms of the GNU Free Documentation License or the GNU General Public License and may be freely distributed under the terms given by one of these licenses.