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. |