00001 #ifndef EDG_WORKLOAD_COMMON_UTILITIES_MIXED_H
00002 #define EDG_WORKLOAD_COMMON_UTILITIES_MIXED_H
00003
00004 #include <cstdlib>
00005 #include <cstdio>
00006 #include <cstring>
00007
00008 #include <iostream>
00009 #include <vector>
00010 #include <string>
00011
00012 #include "edg/workload/common/common_namespace.h"
00013
00014 COMMON_NAMESPACE_BEGIN {
00015
00016 namespace utilities {
00017
00018 class Mixed {
00019 friend std::ostream &operator<<( std::ostream &os, const Mixed &val );
00020 friend bool operator==( const Mixed &a, const Mixed &b );
00021 inline friend bool operator!=( const Mixed &a, const Mixed &b )
00022 { return( !operator==(a, b) ); }
00023
00024 public:
00025 enum mixed_type_t { unk = -1, log, intg, real, chr, vgen, vlog, vint, vreal, vchr };
00026
00027
00028 Mixed( void );
00029 Mixed( bool b );
00030 Mixed( int i );
00031 Mixed( double d );
00032 Mixed( const char *c );
00033 Mixed( const char *begin, const char *end );
00034 Mixed( const std::string &s );
00035 Mixed( const Mixed &m );
00036
00037 template<class type_t>
00038 inline Mixed( int n, const type_t *t ) : pbuf( NULL ) { this->setVector( n, t ); }
00039 template<class type_t>
00040 inline Mixed( const std::vector<type_t> &v ) : pbuf( NULL ) { this->setVector( v ); }
00041
00042
00043 ~Mixed( void );
00044
00045
00046 inline char *getStringType( void ) { return( stringTypes[(int)this->type + 1] ); }
00047 inline char *getStringValue( void ) { return( this->castString() ); }
00048 inline std::vector<Mixed> &getVectorValue( void ) { return( this->castVector() ); }
00049
00050
00051 inline mixed_type_t getType( void ) const { return( this->type ); }
00052 inline bool getLogicalValue( void ) const { return( ((Mixed *)this)->castBool() ); }
00053 inline int getIntegerValue( void ) const { return( ((Mixed *)this)->castInteger() ); }
00054 inline double getDoubleValue( void ) const { return( ((Mixed *)this)->castReal() ); }
00055
00056 inline const char *getStringValue( void ) const { return( (const char *) ((Mixed *)this)->castString() ); }
00057 inline const char *getStringType( void ) const { return( (const char *) stringTypes[(int)this->type + 1] ); }
00058
00059 inline const std::vector<Mixed> &getVectorValue( void ) const { return( (const std::vector<Mixed> &) ((Mixed *)this)->castVector() ); }
00060
00061 inline bool defined( void ) const { return( this->type != unk ); }
00062 inline bool isVector( void ) const { return( ((int)this->type >= (int)vgen) && ((int)this->type <= (int)vchr) ); }
00063
00064
00065 inline Mixed &setLogicalValue( bool b )
00066 {
00067 this->deletePointer(); this->type = log; this->bval = b;
00068 return( *this );
00069 }
00070 inline Mixed &setIntegerValue( int i )
00071 {
00072 this->deletePointer(); this->type = intg; this->ival = i;
00073 return( *this );
00074 }
00075 inline Mixed &setDoubleValue( double d )
00076 {
00077 this->deletePointer(); this->type = real; this->rval = d;
00078 return( *this );
00079 }
00080 inline Mixed &setStringValue( const char *s )
00081 {
00082 this->setString( s );
00083 return( *this );
00084 }
00085 inline Mixed &setStringValue( const char *begin, const char *end )
00086 {
00087 this->setString( begin, end );
00088 return( *this );
00089 }
00090 template<class type_t>
00091 inline Mixed &setVectorValue( int n, const type_t *t )
00092 {
00093 this->deletePointer(); this->setVector( n, t );
00094 return( *this );
00095 }
00096 inline Mixed &setVectorValue( const std::vector<Mixed> &m, enum mixed_type_t t )
00097 {
00098 this->deletePointer();
00099 this->setVector( m ); this->type = t;
00100 return( *this );
00101 }
00102 template<class type_t>
00103 inline Mixed &setVectorValue( const std::vector<type_t> &v )
00104 {
00105 this->deletePointer(); this->setVector( v );
00106 return( *this );
00107 }
00108
00109 inline Mixed &undefine( void )
00110 {
00111 this->deletePointer(); this->type = unk;
00112 return( *this );
00113 }
00114
00115
00116 inline operator bool( void ) { return( this->castBool() ); }
00117 inline operator int( void ) { return( this->castInteger() ); }
00118 inline operator double( void ) { return( this->castReal() ); }
00119 inline operator char *( void ) { return( this->castString() ); }
00120 inline operator const char *( void ) { return( (const char *) this->castString() ); }
00121 inline operator std::vector<Mixed>( void ) { return( this->castVector() ); }
00122
00123 inline operator const char *( void ) const { return( (const char *) ((Mixed *)this)->castString() ); }
00124
00125 inline std::vector<Mixed> *operator->( void ) { return( this->castPointerVector() ); }
00126 inline bool operator=( bool b )
00127 {
00128 this->deletePointer(); this->type = log; this->bval = b;
00129 return( b );
00130 }
00131 inline int operator=( int i )
00132 {
00133 this->deletePointer(); this->type = intg; this->ival = i;
00134 return( i );
00135 }
00136 inline double operator=( double d )
00137 {
00138 this->deletePointer(); this->type = real; this->rval = d;
00139 return( d );
00140 }
00141 inline char *operator=( char *s )
00142 {
00143 this->setString( s );
00144 return( s );
00145 }
00146 template<class type_t>
00147 inline std::vector<type_t> &operator=( std::vector<type_t> &v )
00148 {
00149 this->deletePointer(); this->setVector( v );
00150 return( v );
00151 }
00152 inline Mixed &operator=( const Mixed &m )
00153 { this->copyValue( m ); return( *this ); }
00154
00155
00156 inline static char *getType( enum mixed_type_t type ) { return( stringTypes[(int) type + 1] ); }
00157 inline static void setVerbose( bool v = true ) { verbose = v; }
00158 inline static Mixed &zero( void ) { return( __zero ); }
00159 inline static bool getVerbose( void ) { return( verbose ); }
00160
00161 private:
00162 inline void deletePointer( void )
00163 {
00164 if( this->pbuf ) {
00165 delete [] this->pbuf;
00166 this->pbuf = NULL;
00167 }
00168
00169 if( this->type == chr ) delete [] this->sval.value;
00170 else if( this->isVector() ) delete this->vval;
00171 }
00172 inline void setString( const char *begin, const char *end = NULL )
00173 {
00174 size_t len = (size_t) -1;
00175
00176 if( end == NULL ) len = strlen( begin );
00177 else if( end > begin ) len = end - begin;
00178
00179 if( len != (size_t) -1 ) {
00180 this->deletePointer();
00181
00182 this->sval.value = new char[len + 1];
00183 this->sval.length = len;
00184 memcpy( this->sval.value, begin, len ); this->sval.value[len] = '\0';
00185
00186 this->type = chr;
00187 }
00188 }
00189 inline void setVector( int max, const bool *b )
00190 {
00191 int n;
00192
00193 this->vval = new std::vector<Mixed>;
00194 for( n = 0; n < max; n++ ) this->vval->push_back( b[n] );
00195 this->type = vlog;
00196 }
00197 inline void setVector( int max, const int *i )
00198 {
00199 int n;
00200
00201 this->vval = new std::vector<Mixed>;
00202 for( n = 0; n < max; n++ ) this->vval->push_back( i[n] );
00203 this->type = vint;
00204 }
00205 inline void setVector( int max, const double *d )
00206 {
00207 int n;
00208
00209 this->vval = new std::vector<Mixed>;
00210 for( n = 0; n < max; n++ ) this->vval->push_back( d[n] );
00211 this->type = vreal;
00212 }
00213 inline void setVector( int max, const char **c )
00214 {
00215 int n;
00216
00217 this->vval = new std::vector<Mixed>;
00218 for( n = 0; n < max; n++ ) this->vval->push_back( c[n] );
00219 this->type = vchr;
00220 }
00221 inline void setVector( int max, const std::string *s )
00222 {
00223 int n;
00224
00225 this->vval = new std::vector<Mixed>;
00226 for( n = 0; n < max; n++ ) this->vval->push_back( s[n].c_str() );
00227 this->type = vchr;
00228 }
00229 inline void setVector( int max, const Mixed *m )
00230 {
00231 int n;
00232
00233 this->vval = new std::vector<Mixed>;
00234 for( n = 0; n < max; n++ ) this->vval->push_back( m[n] );
00235 this->type = vgen;
00236 }
00237 inline void setVector( const std::vector<bool> &b )
00238 {
00239 size_t n, max = b.size();
00240
00241 this->vval = new std::vector<Mixed>;
00242 for( n = 0; n < max; n++ ) this->vval->push_back( b[n] );
00243 this->type = vlog;
00244 }
00245 inline void setVector( const std::vector<int> &i )
00246 {
00247 size_t n, max = i.size();
00248
00249 this->vval = new std::vector<Mixed>;
00250 for( n = 0; n < max; n++ ) this->vval->push_back( i[n] );
00251 this->type = vint;
00252 }
00253 inline void setVector( const std::vector<double> &r )
00254 {
00255 size_t n, max = r.size();
00256
00257 this->vval = new std::vector<Mixed>;
00258 for( n = 0; n < max; n++ ) this->vval->push_back( r[n] );
00259 this->type = vreal;
00260 }
00261 inline void setVector( const std::vector<char *> &c )
00262 {
00263 size_t n, max = c.size();
00264
00265 this->vval = new std::vector<Mixed>;
00266 for( n = 0; n < max; n++ ) this->vval->push_back( c[n] );
00267 this->type = vchr;
00268 }
00269 inline void setVector( const std::vector<std::string> &s )
00270 {
00271 size_t n, max = s.size();
00272
00273 this->vval = new std::vector<Mixed>;
00274 for( n = 0; n < max; n++ ) this->vval->push_back( s[n].c_str() );
00275 this->type = vchr;
00276 }
00277 inline void setVector( const std::vector<Mixed> &b )
00278 {
00279 this->vval = new std::vector<Mixed>( b );
00280 this->type = vgen;
00281 }
00282
00283 inline void copyValue( const Mixed &m )
00284 {
00285 if( m.type == chr ) this->setString( m.sval.value, m.sval.value + m.sval.length );
00286 else if( m.type == log ) this->setLogicalValue( m.bval );
00287 else if( m.type == intg ) this->setIntegerValue( m.ival );
00288 else if( m.type == real ) this->setDoubleValue( m.rval );
00289 else if( m.isVector() ) this->setVectorValue( *m.vval, m.type );
00290 else if( m.type == unk ) this->undefine();
00291 }
00292 inline bool castBool( void )
00293 {
00294 switch( this->type ) {
00295 case log:
00296 return( bval );
00297 break;
00298 case intg:
00299 return( (bool) ival );
00300 break;
00301 case real:
00302 return( (bool) rval );
00303 break;
00304 case chr:
00305 if( this->sval.value ) {
00306 if( !memcmp(this->sval.value, "true", 4) || !memcmp(this->sval.value, "TRUE", 4) ||
00307 !memcmp(this->sval.value, "yes", 3) || !memcmp(this->sval.value, "YES", 3) )
00308 return( true );
00309 else {
00310 int i = atoi( this->sval.value );
00311 return( (bool) i );
00312 }
00313 }
00314 else return( false );
00315 break;
00316 case unk:
00317 case vgen:
00318 case vlog:
00319 case vint:
00320 case vreal:
00321 case vchr:
00322 default:
00323 return( false );
00324 break;
00325 }
00326 }
00327 inline int castInteger( void )
00328 {
00329 switch( this->type ) {
00330 case log:
00331 return( (int) bval );
00332 break;
00333 case intg:
00334 return( ival );
00335 break;
00336 case real:
00337 return( (int) rval );
00338 break;
00339 case chr:
00340 if( this->sval.value ) {
00341 int val = atoi( this->sval.value );
00342 return( val );
00343 }
00344 else return( 0 );
00345 break;
00346 case unk:
00347 case vgen:
00348 case vlog:
00349 case vint:
00350 case vreal:
00351 case vchr:
00352 default:
00353 return( 0 );
00354 break;
00355 }
00356 }
00357 inline double castReal( void )
00358 {
00359 switch( this->type ) {
00360 case log:
00361 return( (double) bval );
00362 break;
00363 case intg:
00364 return( (int) ival );
00365 break;
00366 case real:
00367 return( rval );
00368 break;
00369 case chr:
00370 if( this->sval.value ) {
00371 double val = atof( this->sval.value );
00372 return( val );
00373 }
00374 else return( 0.0 );
00375 break;
00376 case unk:
00377 case vgen:
00378 case vlog:
00379 case vint:
00380 case vreal:
00381 case vchr:
00382 default:
00383 return( 0.0 );
00384 break;
00385 }
00386 }
00387 inline char *castString( void )
00388 {
00389 if( this->pbuf == NULL ) this->pbuf = new char[30];
00390
00391 switch( this->type ) {
00392 case log:
00393 strcpy( this->pbuf, (this->bval ? "true" : "false") );
00394 return( this->pbuf );
00395 break;
00396 case intg:
00397 sprintf( this->pbuf, "%d", ival );
00398 return( this->pbuf );
00399 break;
00400 case real:
00401 sprintf( this->pbuf, "%f", rval );
00402 return( this->pbuf );
00403 break;
00404 case chr:
00405 return( this->sval.value );
00406 break;
00407 case unk:
00408 case vgen:
00409 case vlog:
00410 case vint:
00411 case vreal:
00412 case vchr:
00413 default:
00414 return( NULL );
00415 break;
00416 }
00417 }
00418 inline std::vector<Mixed> &castVector( void )
00419 {
00420 switch( this->type ) {
00421 case vgen:
00422 case vlog:
00423 case vint:
00424 case vreal:
00425 case vchr:
00426 return( *vval );
00427 break;
00428 case unk:
00429 case log:
00430 case intg:
00431 case real:
00432 case chr:
00433 default:
00434 return( *empty );
00435 break;
00436 }
00437 }
00438 inline std::vector<Mixed> *castPointerVector( void )
00439 {
00440 switch( this->type ) {
00441 case vgen:
00442 case vlog:
00443 case vint:
00444 case vreal:
00445 case vchr:
00446 return( vval );
00447 break;
00448 case unk:
00449 case log:
00450 case intg:
00451 case real:
00452 case chr:
00453 default:
00454 return( empty );
00455 break;
00456 }
00457 }
00458
00459
00460 enum mixed_type_t type;
00461 union {
00462 bool bval;
00463 int ival;
00464 double rval;
00465 struct {
00466 char *value;
00467 size_t length;
00468 } sval;
00469 std::vector<Mixed> *vval;
00470 };
00471 char *pbuf;
00472
00473
00474 static bool verbose;
00475 static char *stringTypes[];
00476 static std::vector<Mixed> *empty;
00477 static Mixed __zero;
00478 };
00479
00480 typedef Mixed::mixed_type_t mixed_type_t;
00481
00482 };
00483
00484 } COMMON_NAMESPACE_END;
00485
00486 #endif
00487
00488
00489
00490