Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

TypeAdapter.h

Go to the documentation of this file.
00001 /* SimData: Data Infrastructure for Simulations
00002  * Copyright (C) 2002 Mark Rose <tm2@stm.lbl.gov>
00003  * 
00004  * This file is part of SimData.
00005  * 
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  * 
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019  */
00020 
00021 
00027 #ifndef __SIMDATA_TYPEADAPTER_H__
00028 #define __SIMDATA_TYPEADAPTER_H__
00029 
00030 #if defined(_MSC_VER) && (_MSC_VER <= 1300)
00031 #pragma warning (disable : 4290)
00032 #endif
00033 
00034 #include <SimData/Export.h>
00035 #include <SimData/Exception.h>
00036 #include <SimData/Namespace.h>
00037 #include <SimData/Enum.h>
00038 #include <SimData/Path.h>
00039 
00040 #include <SimData/Types.h>
00041 #include <SimData/PTS.h>
00042 
00043 #include <string>
00044 #include <iostream>
00045 
00046 
00047 NAMESPACE_SIMDATA
00048 
00049 class BaseType;
00050 class Real;
00051 class Vector3;
00052 class Matrix3;
00053 class Curve;
00054 class Table;
00055 class LinkBase;
00056 class External;
00057 class Key;
00058 class SimDate;
00059 class ListBase;
00060 class GeoPos;
00061 class LLA;
00062 class UTM;
00063 class ECEF;
00064 class Object;
00065 
00066 #ifndef __PTS_SIM__
00067 template <int N, typename X>
00068 class LUT;
00069 
00070 typedef LUT<1,float> Table1;
00071 typedef LUT<2,float> Table2;
00072 typedef LUT<3,float> Table3;
00073 #endif // __PTS_SIM__
00074 
00075 SIMDATA_EXCEPTION(TypeMismatch)
00076 
00077         
00078 
00090 class SIMDATA_EXPORT TypeAdapter 
00091 {
00092 public:
00093         typedef enum {NONE, INT, DOUBLE, STRING, BASE} TYPE; 
00094         static const char * TypeNames[];
00095 
00096         TypeAdapter(): type(NONE) {}
00097         explicit TypeAdapter(int x): type(INT) { var.i = x; }
00098         explicit TypeAdapter(double x): type(DOUBLE) { var.d = x; }
00099         explicit TypeAdapter(std::string const &x): type(STRING) { s = x; }
00100         explicit TypeAdapter(const char *x): type(STRING) { s = x; }
00101         explicit TypeAdapter(BaseType const *x): type(BASE) { var.o = x; }
00102         explicit TypeAdapter(BaseType const &x): type(BASE) { var.o = &x; }
00103         TypeAdapter(TypeAdapter const &x): type(x.type) { 
00104                 switch(type) {
00105                         case INT:
00106                                 var.i = x.var.i;
00107                                 break;
00108                         case DOUBLE:
00109                                 var.d = x.var.d;
00110                                 break;
00111                         case STRING:
00112                                 s = x.s;
00113                                 break;
00114                         case BASE:
00115                                 var.o = x.var.o;
00116                                 break;
00117                         default:
00118                                 break;
00119                 }
00120         }
00121 
00122         // objects
00123 
00124         int getInteger() const { IntCheck(); return var.i; }
00125         double getFloatingPoint() const { DoubleCheck(); return var.d; }
00126         std::string getString() const { StringCheck(); return s; }
00127         BaseType const &getBaseType() const { BaseCheck(); return *(var.o); }
00128         
00129         template<typename T>
00130         void getBaseTypeAs(T * &t) const {
00131                 T proto;
00132                 BaseCheck();
00133                 T const *cp = dynamic_cast<T const *>(var.o);
00134                 TypeCheck(cp!=NULL, "dynamic cast of BaseType* to " + proto.typeString() +
00135                                     "failed in TypeAdapter::getBaseTypeAs");
00136                 t = const_cast<T *>(cp);
00137         }
00138 
00139         template <typename T> 
00140         void setBase(T & x) const {
00141                 BaseCheck();
00142                 T const *p = dynamic_cast<T const *>(var.o);
00143                 TypeCheck(p!=NULL, "dynamic cast of BaseType* to " + x.typeString() + 
00144                                    " failed in TypeAdapter::setBase");
00145                 T *nc = const_cast<T *>(p);
00146                 x = *nc;
00147         }
00148 
00149         template <typename T>
00150         void setCoordinate(T & x) const {
00151                 BaseCheck();
00152                 LLA const *lla = dynamic_cast<LLA const *>(var.o);
00153                 if (lla != 0) {
00154                         x = *lla;
00155                         return;
00156                 }
00157                 UTM const *utm = dynamic_cast<UTM const *>(var.o);
00158                 if (utm != 0) {
00159                         x = *utm;
00160                         return;
00161                 }
00162                 ECEF const *ecef = dynamic_cast<ECEF const *>(var.o);
00163                 TypeCheck(ecef!=NULL, "dynamic casts of BaseType* to {LLA,UTM,ECEF} failed in TypeAdapter::setCoordinate");
00164                 x = *ecef;
00165         }
00166 
00167         /*
00168         template <typename T> 
00169         void set(T & x) const { setBase(x); }
00170         */
00171 
00172         inline void set(SimDate & x) const { setBase(x); }
00173 
00174         inline void set(GeoPos & x) const { setBase(x); }
00175 
00176         inline void set(LLA & x) const { setCoordinate(x); }
00177         inline void set(UTM & x) const { setCoordinate(x); }
00178         inline void set(ECEF & x) const { setCoordinate(x); }
00179 
00180         inline void set(Vector3 & x) const { setBase(x); }
00181         inline void set(Matrix3 & x) const { setBase(x); }
00182         inline void set(Real & x) const { setBase(x); }
00183         inline void set(Curve & x) const { setBase(x); }
00184         inline void set(Table & x) const { setBase(x); }
00185 #ifndef __PTS_SIM__
00186         inline void set(Table1 & x) const { setBase(x); }
00187         inline void set(Table2 & x) const { setBase(x); }
00188         inline void set(Table3 & x) const { setBase(x); }
00189 #endif // __PTS_SIM__
00190         inline void set(External & x) const { setBase(x); }
00191         inline void set(Key & x) const { setBase(x); }
00192         inline void set(Path & x) const { setBase(x); }
00193         // list
00194 
00195         void set(short &x) const { IntCheck(); x = static_cast<short>(var.i); }
00196         void set(char &x) const { IntCheck(); x = static_cast<char>(var.i); }
00197 
00198         void set(int &x) const { IntCheck(); x = static_cast<int>(var.i); }
00199         void set(bool &x) const { IntCheck(); x = (var.i != 0); }
00200         void set(float &x) const { DoubleCheck(); x = static_cast<float>(var.d); }
00201         void set(double &x) const { DoubleCheck(); x = static_cast<double>(var.d); }
00202         void set(unsigned int &x) const { IntCheck(); x = static_cast<unsigned int>(var.i); }
00203         void set(std::string &x) const { StringCheck(); x = s; }
00204         void set(EnumLink &x) const { if (isType(STRING)) x = s; else setBase(x); }
00205         // slightly fancier handling required for path pointers
00206         void set(LinkBase &x) const {
00207                 BaseCheck();
00208                 // are we assigning to a pointerbase?
00209                 LinkBase const *p = dynamic_cast<LinkBase const *>(var.o);
00210                 if (p != 0) {
00211                         x = *(const_cast<LinkBase *>(p));
00212                 } else {
00213                         // last chance, is it a path?
00214                         Path const *path = dynamic_cast<Path const *>(var.o);
00215                         TypeCheck(path!=NULL, "dynamic cast of BaseType* to LinkBase failed");
00216                         x = LinkBase(*(const_cast<Path *>(path)), 0);
00217                 }
00218         }
00219         template <typename Q>
00220         void set(Link<Q> &x) const {
00221                 // first try to assign as an object reference
00222                 Q const *q = dynamic_cast<Q const*>(var.o);
00223                 if (q != 0) {
00224                         x = const_cast<Q*>(q);
00225                 } else {
00226                         // if not, try as a pointerbase or path
00227                         set((LinkBase &)x);
00228                 }
00229         }
00230                         
00231         bool isType(TYPE t) const { return type==t; }
00232 
00233         const std::string __repr__() const { 
00234                 std::string repr;
00235                 if (type==BASE) {
00236                         if (var.o == 0) {
00237                                 repr += "BaseType, NULL";
00238                         } else {
00239                                 repr += "BaseType, " + var.o->typeString();
00240                         }
00241                 } else {
00242                         repr += TypeNames[type];
00243                 }
00244                 return "TypeAdapter<" + repr + ">";
00245         }
00246 
00247 private:
00248         TYPE type;
00249         // can't keep std::string in the union unfortunately, since it
00250         // has a non-default constructor.
00251         std::string s;
00252         // basic types and all object pointers should go in the union.
00253         union {
00254                 int i;
00255                 double d;
00256                 BaseType const *o;
00257         } var;
00258 
00259         void TypeCheck(bool test, std::string msg) const throw(TypeMismatch) {
00260                 if (!(test)) {
00261                         msg = __repr__() + ": " + msg;
00262                         throw TypeMismatch(msg);
00263                 }
00264         }
00265         void IntCheck() const {
00266                 TypeCheck(type==INT, "integer type expected");
00267         }
00268         void StringCheck() const {
00269                 TypeCheck(type==STRING, "string type expected");
00270         }
00271         void DoubleCheck() const {
00272                 TypeCheck(type==DOUBLE, "floating point type expected");
00273         }
00274         void BaseCheck() const {
00275                 TypeCheck(type==BASE, "base type expected");
00276         }
00277 
00278 };
00279 
00280 std::ostream &operator <<(std::ostream &o, TypeAdapter const &t);
00281 
00282 
00283 NAMESPACE_SIMDATA_END
00284 
00285 
00286 #endif // __SIMDATA_TYPEADAPTER_H__
00287 

SimData version pre-0.4.0. For more information on SimData, visit the SimData Homepage.

Generated on Tue Oct 14 12:06:39 2003, using Doxygen 1.2.18.

[SF.net]