00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef __POLYMORPH_HPP
00032 #define __POLYMORPH_HPP
00033
00034 #include <boost/static_assert.hpp>
00035
00036 #include "libecs.hpp"
00037 #include "convertTo.hpp"
00038 #include "Util.hpp"
00039
00040 namespace libecs
00041 {
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 DECLARE_CLASS( PolymorphValue );
00053
00054 class PolymorphValue
00055 {
00056
00057 public:
00058
00059 ECELL_API virtual ~PolymorphValue();
00060
00061 virtual const String asString() const = 0;
00062 virtual const Real asReal() const = 0;
00063 virtual const Integer asInteger() const = 0;
00064 virtual const PolymorphVector asPolymorphVector() const = 0;
00065
00066 template< typename T >
00067 const T as() const;
00068
00069 virtual PolymorphValuePtr createClone() const = 0;
00070
00071 protected:
00072
00073 PolymorphValue( PolymorphValueCref ) {}
00074 PolymorphValue() {}
00075
00076 private:
00077
00078 PolymorphCref operator= ( PolymorphCref );
00079
00080 };
00081
00082
00083 template <>
00084 inline const String PolymorphValue::as() const
00085 {
00086 return asString();
00087 }
00088
00089 template <>
00090 inline const Real PolymorphValue::as() const
00091 {
00092 return asReal();
00093 }
00094
00095 template <>
00096 inline const Integer PolymorphValue::as() const
00097 {
00098 return asInteger();
00099 }
00100
00101 template <>
00102 inline const PolymorphVector PolymorphValue::as() const
00103 {
00104 return asPolymorphVector();
00105 }
00106
00107
00108
00109 template< typename T >
00110 class ConcretePolymorphValue
00111 :
00112 public PolymorphValue
00113 {
00114
00115 typedef typename libecs::Param<T>::type TParam;
00116
00117 public:
00118
00119 ConcretePolymorphValue( TParam aValue )
00120 :
00121 theValue( aValue )
00122 {
00123 ;
00124 }
00125
00126 ConcretePolymorphValue( PolymorphValueCref aValue )
00127 :
00128 theValue( aValue.as<T>() )
00129 {
00130 ;
00131 }
00132
00133 virtual ~ConcretePolymorphValue()
00134 {
00135 ;
00136 }
00137
00138 virtual const String asString() const
00139 {
00140 return convertTo<String>( theValue );
00141 }
00142
00143 virtual const Real asReal() const
00144 {
00145 return convertTo<Real>( theValue );
00146 }
00147
00148 virtual const Integer asInteger() const
00149 {
00150 return convertTo<Integer>( theValue );
00151 }
00152
00153 virtual const PolymorphVector asPolymorphVector() const
00154 {
00155 return convertTo<PolymorphVector>( theValue );
00156 }
00157
00158 virtual PolymorphValuePtr createClone() const
00159 {
00160 return new ConcretePolymorphValue<T>( *this );
00161 }
00162
00163 private:
00164
00165 T theValue;
00166
00167 };
00168
00169
00170
00171
00172 class PolymorphNoneValue
00173 :
00174 public PolymorphValue
00175 {
00176
00177 public:
00178
00179 PolymorphNoneValue() {}
00180
00181 ECELL_API virtual ~PolymorphNoneValue();
00182
00183 ECELL_API virtual const String asString() const;
00184 virtual const Real asReal() const { return 0.0; }
00185 virtual const Integer asInteger() const { return 0; }
00186 ECELL_API virtual const PolymorphVector asPolymorphVector() const;
00187
00188 virtual PolymorphValuePtr createClone() const
00189 {
00190 return new PolymorphNoneValue;
00191 }
00192
00193 };
00194
00195
00196
00197 class Polymorph
00198 {
00199
00200 public:
00201
00202 enum Type
00203 {
00204 NONE,
00205 REAL,
00206 INTEGER,
00207 STRING,
00208 POLYMORPH_VECTOR
00209 };
00210
00211
00212 Polymorph()
00213 :
00214 theValue( new PolymorphNoneValue )
00215 {
00216 ;
00217 }
00218
00219 Polymorph( StringCref aValue )
00220 :
00221 theValue( new ConcretePolymorphValue<String>( aValue ) )
00222 {
00223 ;
00224 }
00225
00226 Polymorph( RealParam aValue )
00227 :
00228 theValue( new ConcretePolymorphValue<Real>( aValue ) )
00229 {
00230 ;
00231 }
00232
00233 Polymorph( IntegerParam aValue )
00234 :
00235 theValue( new ConcretePolymorphValue<Integer>( aValue ) )
00236 {
00237 ;
00238 }
00239
00240 Polymorph( PolymorphVectorCref aValue )
00241 :
00242 theValue( new ConcretePolymorphValue<PolymorphVector>( aValue ) )
00243 {
00244 ;
00245 }
00246
00247 Polymorph( PolymorphCref aValue )
00248 :
00249 theValue( aValue.createValueClone() )
00250 {
00251 ;
00252 }
00253
00254 ~Polymorph()
00255 {
00256 delete theValue;
00257 }
00258
00259 PolymorphCref operator=( PolymorphCref rhs )
00260 {
00261 if( this != &rhs )
00262 {
00263 delete theValue;
00264 theValue = rhs.createValueClone();
00265 }
00266
00267 return *this;
00268 }
00269
00270 const String asString() const
00271 {
00272 return theValue->asString();
00273 }
00274
00275 const Real asReal() const
00276 {
00277 return theValue->asReal();
00278 }
00279
00280 const Integer asInteger() const
00281 {
00282 return theValue->asInteger();
00283 }
00284
00285 const PolymorphVector asPolymorphVector() const
00286 {
00287 return theValue->asPolymorphVector();
00288 }
00289
00290 template< typename T >
00291 const T as() const;
00292
00293
00294
00295
00296 ECELL_API const Type getType() const;
00297
00298 void changeType( const Type aType );
00299
00300
00301 operator String() const
00302 {
00303 return asString();
00304 }
00305
00306 operator Real() const
00307 {
00308 return asReal();
00309 }
00310
00311 operator Integer() const
00312 {
00313 return asInteger();
00314 }
00315
00316 operator PolymorphVector() const
00317 {
00318 return asPolymorphVector();
00319 }
00320
00321 protected:
00322
00323 PolymorphValuePtr createValueClone() const
00324 {
00325 return theValue->createClone();
00326 }
00327
00328 protected:
00329
00330 PolymorphValuePtr theValue;
00331
00332 };
00333
00334
00335
00336
00337 template <>
00338 inline const String Polymorph::as() const
00339 {
00340 return asString();
00341 }
00342
00343 template <>
00344 inline const Real Polymorph::as() const
00345 {
00346 return asReal();
00347 }
00348
00349 template <>
00350 inline const Integer Polymorph::as() const
00351 {
00352 return asInteger();
00353 }
00354
00355 template <>
00356 inline const PolymorphVector Polymorph::as() const
00357 {
00358 return asPolymorphVector();
00359 }
00360
00361
00362
00363
00364
00365
00366
00367 template<>
00368 inline const Polymorph nullValue()
00369 {
00370 return Polymorph();
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 template<>
00382 class ConvertTo< PolymorphVector, PolymorphVector >
00383 {
00384 public:
00385 const PolymorphVector operator()( const PolymorphVector& aValue )
00386 {
00387 return aValue;
00388 }
00389 };
00390
00391
00392
00393 template< typename FromType >
00394 class ConvertTo< PolymorphVector, FromType >
00395 {
00396 public:
00397 const PolymorphVector operator()( const FromType& aValue )
00398 {
00399 return PolymorphVector( 1, aValue );
00400 }
00401 };
00402
00403
00404 template<>
00405 class ConvertTo< PolymorphVector, String >
00406 {
00407 public:
00408 const PolymorphVector operator()( const String& aValue )
00409 {
00410 return PolymorphVector( 1, aValue );
00411 }
00412 };
00413
00414
00415
00416 template< typename ToType >
00417 class ConvertTo< ToType, PolymorphVector >
00418 {
00419 public:
00420 const ToType operator()( PolymorphVectorCref aValue )
00421 {
00422 checkSequenceSize( aValue, 1 );
00423 return static_cast<Polymorph>(aValue[0]).as<ToType>();
00424 }
00425 };
00426
00427
00428 template<>
00429 class ConvertTo< String, PolymorphVector >
00430 {
00431 public:
00432 const String operator()( PolymorphVectorCref aValue )
00433 {
00434 checkSequenceSize( aValue, 1 );
00435 return static_cast<Polymorph>(aValue[0]).as<String>();
00436 }
00437 };
00438
00439
00440
00441
00442 }
00443
00444
00445 #endif