Atlas-C++
|
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.