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