00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <clipsmm/value.h>
00020
00021 #include <stdexcept>
00022
00023 namespace DACLIPS {
00024
00025 Value::Value(Type type): m_value(NULL) {
00026 this->set_type( type );
00027 }
00028
00029 Value::Value( float x ): m_value(NULL) {
00030 this->set_type( TYPE_FLOAT );
00031 this->set(x);
00032 }
00033
00034 Value::Value( double x ): m_value(NULL) {
00035 this->set_type( TYPE_FLOAT );
00036 this->set(x);
00037 }
00038
00039 Value::Value( short int x ): m_value(NULL) {
00040 this->set_type( TYPE_INTEGER );
00041 this->set(x);
00042 }
00043
00044 Value::Value( unsigned short int x ): m_value(NULL) {
00045 this->set_type( TYPE_INTEGER );
00046 this->set(x);
00047 }
00048
00049 Value::Value( int x ): m_value(NULL) {
00050 this->set_type( TYPE_INTEGER );
00051 this->set(x);
00052 }
00053
00054 Value::Value( unsigned int x ): m_value(NULL) {
00055 this->set_type( TYPE_INTEGER );
00056 this->set(x);
00057 }
00058
00059 Value::Value( long int x ): m_value(NULL) {
00060 this->set_type( TYPE_INTEGER );
00061 this->set(x);
00062 }
00063
00064 Value::Value( char* x, Type type ): m_value(NULL) {
00065 this->set_type( type );
00066 this->set(x);
00067 }
00068
00069 Value::Value( const std::string& x, Type type ): m_value(NULL) {
00070 this->set_type( type );
00071 this->set(x);
00072 }
00073
00074 Value::Value( void* x, Type type ): m_value(NULL) {
00075 this->set_type( type );
00076 this->set(x);
00077 }
00078
00079 Value::Value( const Value& value): m_value(NULL) {
00080 this->operator=(value);
00081 }
00082
00083 Value::~Value() {
00084 deallocate_storage();
00085 }
00086
00087 double Value::as_float() const {
00088 switch ( m_clips_type ) {
00089 case TYPE_FLOAT:
00090 return *static_cast<double*>(m_value);
00091 case TYPE_INTEGER:
00092 return *static_cast<long int*>(m_value);
00093 default:
00094 throw std::logic_error("Invalid get_float() of non-float value");
00095 }
00096 }
00097
00098 long int Value::as_integer() const {
00099 switch ( m_clips_type ) {
00100 case TYPE_FLOAT:
00101 return static_cast<long int>(*static_cast<double*>(m_value));
00102 case TYPE_INTEGER:
00103 return *static_cast<long int*>(m_value);
00104 default:
00105 throw std::logic_error("Invalid get_float() of non-float value");
00106 }
00107 }
00108
00109 std::string& Value::as_string() const {
00110 switch ( m_clips_type ) {
00111 case TYPE_STRING:
00112 case TYPE_SYMBOL:
00113 case TYPE_INSTANCE_NAME:
00114 return *static_cast<std::string*>(m_value);
00115 default:
00116 throw std::logic_error("Invalid get_string() of non-string value");
00117 }
00118 }
00119
00120 void* Value::as_address() const {
00121 switch ( m_clips_type ) {
00122 case TYPE_EXTERNAL_ADDRESS:
00123 case TYPE_INSTANCE_ADDRESS:
00124 return *static_cast<int**>(m_value);
00125 default:
00126 throw std::logic_error("Invalid get_address() of non-address value");
00127 }
00128 }
00129
00130 Value& Value::set( float x, bool change_type ) {
00131 return this->set( static_cast<double>(x), change_type );
00132 }
00133
00134 Value& Value::set( double x, bool change_type ) {
00135 if (change_type)
00136 this->set_type( TYPE_FLOAT );
00137 if ( m_clips_type == TYPE_INTEGER )
00138 return this->set( static_cast<long int>(x) );
00139 if ( m_clips_type != TYPE_FLOAT )
00140 throw std::logic_error("Invalid set( double x ) on non-float value");
00141 *static_cast<double*>(m_value) = x;
00142 m_signal_changed.emit();
00143 return *this;
00144 }
00145
00146 Value& Value::set( short int x, bool change_type ) {
00147 return this->set( static_cast<long int>(x), change_type );
00148 }
00149
00150 Value& Value::set( unsigned short int x, bool change_type ) {
00151 return this->set( static_cast<long int>(x), change_type );
00152 }
00153
00154 Value& Value::set( int x, bool change_type ) {
00155 return this->set( static_cast<long int>(x), change_type );
00156 }
00157
00158 Value& Value::set( unsigned int x, bool change_type ) {
00159 return this->set( static_cast<long int>(x), change_type );
00160 }
00161
00162 Value& Value::set( long int x, bool change_type ) {
00163 if (change_type)
00164 this->set_type( TYPE_INTEGER );
00165 if ( m_clips_type == TYPE_FLOAT )
00166 return this->set( static_cast<double>(x) );
00167 if ( m_clips_type != TYPE_INTEGER )
00168 throw std::logic_error("Invalid set( long int x ) on non-integer value");
00169 *static_cast<long int*>(m_value) = x;
00170 m_signal_changed.emit();
00171 return *this;
00172 }
00173
00174 Value& Value::set( const std::string& x, bool change_type, Type type ) {
00175 if ( change_type )
00176 this->set_type( type );
00177 if ( ! ( m_clips_type == TYPE_STRING ||
00178 m_clips_type == TYPE_SYMBOL ||
00179 m_clips_type == TYPE_INSTANCE_NAME ) )
00180 throw std::logic_error("Invalid set( std::string x ) on non-string value");
00181 *static_cast<std::string*>(m_value) = x;
00182 m_signal_changed.emit();
00183 return *this;
00184 }
00185
00186 Value& Value::set( const char* x, bool change_type, Type type ) {
00187 std::string s = x;
00188 return this->set( s, change_type, type );
00189 }
00190
00191 Value& Value::set( void* x, bool change_type, Type type ) {
00192 if ( change_type )
00193 this->set_type( type );
00194 if ( ! ( m_clips_type == TYPE_EXTERNAL_ADDRESS ||
00195 m_clips_type == TYPE_INSTANCE_ADDRESS ) )
00196 throw std::logic_error("Invalid set( void* x ) on non-address value");
00197 *static_cast<int**>(m_value) = static_cast<int*>(x);
00198 m_signal_changed.emit();
00199 return *this;
00200 }
00201
00202 Value::operator float( ) const {
00203 return this->as_float();
00204 }
00205
00206 Value::operator double( ) const {
00207 return this->as_float();
00208 }
00209
00210 Value::operator short int( ) const {
00211 return this->as_integer();
00212 }
00213
00214 Value::operator unsigned short int( ) const {
00215 return this->as_integer();
00216 }
00217
00218 Value::operator int( ) const {
00219 return this->as_integer();
00220 }
00221
00222 Value::operator unsigned int( ) const {
00223 return this->as_integer();
00224 }
00225
00226 Value::operator long int( ) const {
00227 return this->as_integer();
00228 }
00229
00230 Value::operator std::string&( ) const {
00231 return this->as_string();
00232 }
00233
00234 Value::operator const char*( ) const {
00235 return this->as_string().c_str();
00236 }
00237
00238 Value::operator void*( ) const {
00239 return this->as_address();
00240 }
00241
00242 size_t Value::size() const {
00243 switch ( m_clips_type ) {
00244 case TYPE_FLOAT:
00245 return sizeof(double);
00246 case TYPE_INTEGER:
00247 return sizeof(long int);
00248 case TYPE_SYMBOL:
00249 case TYPE_STRING:
00250 case TYPE_INSTANCE_NAME:
00251 return sizeof( *static_cast<std::string*>(m_value) );
00252 case TYPE_EXTERNAL_ADDRESS:
00253 case TYPE_INSTANCE_ADDRESS:
00254 return sizeof(int*);
00255 }
00256 return 0;
00257 }
00258
00259 Value& Value::operator=( float x ) {
00260 return this->set(x);
00261 }
00262
00263 Value& Value::operator=( double x ) {
00264 return this->set(x);
00265 }
00266
00267 Value& Value::operator=( short int x ) {
00268 return this->set(x);
00269 }
00270
00271 Value& Value::operator=( unsigned short int x ) {
00272 return this->set(x);
00273 }
00274
00275 Value& Value::operator=( int x ) {
00276 return this->set(x);
00277 }
00278
00279 Value& Value::operator=( unsigned int x ) {
00280 return this->set(x);
00281 }
00282
00283 Value& Value::operator=( long int x ) {
00284 return this->set(x);
00285 }
00286
00287 Value& Value::operator=( const std::string& x ) {
00288 return this->set(x);
00289 }
00290
00291 Value& Value::operator=( const char* x ) {
00292 return this->set(x);
00293 }
00294
00295 Value& Value::operator=( void* x ) {
00296 return this->set(x);
00297 }
00298
00299 Value& Value::operator=( const Value& x ) {
00300 this->set_type( x.m_clips_type );
00301 switch ( m_clips_type ) {
00302 case TYPE_FLOAT:
00303 *static_cast<double*>(m_value) = *static_cast<double*>(x.m_value);
00304 break;
00305 case TYPE_INTEGER:
00306 *static_cast<long int*>(m_value) = *static_cast<long int*>(x.m_value);
00307 break;
00308 case TYPE_SYMBOL:
00309 case TYPE_STRING:
00310 case TYPE_INSTANCE_NAME:
00311 *static_cast<std::string*>(m_value) = *static_cast<std::string*>(x.m_value);
00312 break;
00313 case TYPE_EXTERNAL_ADDRESS:
00314 case TYPE_INSTANCE_ADDRESS:
00315 *static_cast<int**>(m_value) = *static_cast<int**>(x.m_value);
00316 break;
00317 }
00318 return *this;
00319 }
00320
00321 bool Value::operator==( float x ) const {
00322 return this->as_float() == x;
00323 }
00324
00325 bool Value::operator==( double x ) const {
00326 return this->as_float() == x;
00327 }
00328
00329 bool Value::operator==( short int x ) const {
00330 return this->as_integer() == x;
00331 }
00332
00333 bool Value::operator==( unsigned short int x ) const {
00334 return this->as_integer() == x;
00335 }
00336
00337 bool Value::operator==( int x ) const {
00338 return this->as_integer() == x;
00339 }
00340
00341 bool Value::operator==( unsigned int x ) const {
00342 return this->as_integer() == x;
00343 }
00344
00345 bool Value::operator==( long int x ) const {
00346 return this->as_integer() == x;
00347 }
00348
00349 bool Value::operator==( const std::string& x ) const {
00350 return this->as_string() == x;
00351 }
00352
00353 bool Value::operator==( const char* x ) const {
00354 return this->as_string() == x;
00355 }
00356
00357 bool Value::operator==( void* x ) const {
00358 return this->as_address() == x;
00359 }
00360
00361 bool Value::operator!=( float x ) const {
00362 return this->as_float() != x;
00363 }
00364
00365 bool Value::operator!=( double x ) const {
00366 return this->as_float() != x;
00367 }
00368
00369 bool Value::operator!=( short int x ) const {
00370 return this->as_integer() != x;
00371 }
00372
00373 bool Value::operator!=( unsigned short int x ) const {
00374 return this->as_integer() != x;
00375 }
00376
00377 bool Value::operator!=( int x ) const {
00378 return this->as_integer() != x;
00379 }
00380
00381 bool Value::operator!=( unsigned int x ) const {
00382 return this->as_integer() != x;
00383 }
00384
00385 bool Value::operator!=( long int x ) const {
00386 return this->as_integer() != x;
00387 }
00388
00389 bool Value::operator!=( const std::string& x ) const {
00390 return this->as_string() != x;
00391 }
00392
00393 bool Value::operator!=( const char* x ) const {
00394 return this->as_string() != x;
00395 }
00396
00397 bool Value::operator!=( void* x ) const {
00398 return this->as_address() != x;
00399 }
00400
00401 Type Value::type() const {
00402 return m_clips_type;
00403 }
00404
00405 Type Value::set_type(Type type) {
00406 if (m_value)
00407 deallocate_storage();
00408
00409 m_clips_type = type;
00410 switch (type) {
00411 case TYPE_FLOAT:
00412 m_value = new double;
00413 break;
00414 case TYPE_INTEGER:
00415 m_value = new long int;
00416 break;
00417 case TYPE_SYMBOL:
00418 case TYPE_STRING:
00419 case TYPE_INSTANCE_NAME:
00420 m_value = new std::string;
00421 break;
00422 case TYPE_EXTERNAL_ADDRESS:
00423 case TYPE_INSTANCE_ADDRESS:
00424 m_value = new int*;
00425 break;
00426 }
00427 return m_clips_type;
00428 }
00429
00430 sigc::signal<void> Value::signal_changed() {
00431 return m_signal_changed;
00432 }
00433
00434 void Value::deallocate_storage() {
00435 if (!m_value)
00436 return;
00437 switch (m_clips_type) {
00438 case TYPE_FLOAT:
00439 delete static_cast<double*>(m_value);
00440 break;
00441 case TYPE_INTEGER:
00442 delete static_cast<long int*>(m_value);
00443 break;
00444 case TYPE_SYMBOL:
00445 case TYPE_STRING:
00446 case TYPE_INSTANCE_NAME:
00447 delete static_cast<std::string*>(m_value);
00448 break;
00449 case TYPE_EXTERNAL_ADDRESS:
00450 case TYPE_INSTANCE_ADDRESS:
00451 delete static_cast<int**>(m_value);
00452 break;
00453 }
00454 m_value = NULL;
00455 }
00456
00457 }