00001 #ifndef CPPTL_VALUE_H_INCLUDED
00002 # define CPPTL_VALUE_H_INCLUDED
00003 # include "forwards.h"
00004 # include "typetraits.h"
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
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 namespace CppTL {
00047
00048 class Value;
00049 class ValueType;
00050 class ValueTypeRegistry;
00051
00052
00053
00054
00055
00056
00057
00058 class ValueType
00059 {
00060 public:
00061 static ValueType typeInt;
00062 static ValueType typeUInt;
00063 static ValueType typeDouble;
00064 static ValueType typeString;
00065 static ValueType typeCString;
00066
00067 void clear()
00068 {
00069 memset( this, 0, sizeof(ValueType) );
00070 }
00071
00072
00073 void (*initialize_)( const void *data, Value &target );
00076 void (*clone_)( const Value &source, Value &target );
00077 void (*destroy_)( Value &target );
00078 ConstCharView (*typeToString_)();
00079 ConstCharView (*valueToString_)();
00080 void (*convertTo_)( const Value &source, Value &target );
00081
00085 int (*compare_)( const Value &a, const Value &b, bool &canCompare );
00086
00090 bool (*less_)( const Value &a, const Value &b, bool &canCompare );
00091
00095 bool (*equal_)( const Value &a, const Value &b, bool &canCompare );
00096
00097
00098 void (*rawData_)( Value &value );
00099 };
00100
00101
00102
00103
00104
00105
00106
00107
00108 typedef LargestInt ValueInt;
00109 typedef LargestUnsignedInt ValueUInt;
00110
00111 typedef char ValueDataBuffer[24];
00112
00113 union ValueData
00114 {
00115
00116
00117
00118 ValueDataBuffer string_;
00119 void *other_;
00120 };
00121
00122 struct NoneValueTypeTag
00123 {
00124 };
00125
00126 class ValueException : public std::runtime_error
00127 {
00128 public:
00129 enum Cause
00130 {
00131 notSameType = 1
00132 };
00133 ValueException( Cause cause, const char *message,
00134 const ValueType *lhs, const ValueType *rhs )
00135 : std::runtime_error( "Can not proceed. ValueType are not compatible" )
00136 , lhs_( lhs )
00137 , rhs_( rhs )
00138 {
00139 }
00140
00141 const ValueType * const lhs_;
00142 const ValueType * const rhs_;
00143 };
00144
00147 class Value
00148 {
00149 public:
00150 typedef ValueInt Int;
00151 typedef ValueUInt UInt;
00152
00153 Value();
00154
00155 Value( const ValueType &type, const void *data );
00156
00157 Value( const Value &other )
00158 {
00159 type_ = other.type_;
00160 type_->clone_( other, *this );
00161 }
00162
00163 ~Value()
00164 {
00165 if ( type_->destroy_ )
00166 type_->destroy_( *this );
00167 }
00168
00169 Value &operator =( const Value &other )
00170 {
00171 if( &other != this )
00172 {
00173 if ( type_->destroy_ )
00174 type_->destroy_( *this );
00175 type_ = other.type_;
00176 type_->clone_( other, *this );
00177 }
00178 return *this;
00179 }
00180
00181 bool isNone() const;
00182 bool isInt() const;
00183 bool isUInt() const;
00184 bool isDouble() const;
00185 bool isString() const;
00186
00187 Int asInt() const;
00188 UInt asUInt() const;
00189 double asDouble() const;
00190 ConstCharView asString() const;
00191
00192 bool convertTo( const ValueType &targetType, Value &other ) const
00193 {
00194 return false;
00195 }
00196
00218 int compare( const Value &other, bool &canCompare, bool allowAutoConvert = true ) const
00219 {
00220 if ( type_ != other.type_ )
00221 {
00222 Value otherSameType;
00223 if ( other.convertTo( *type_, otherSameType ) )
00224 return compare( otherSameType, canCompare );
00225 }
00226 else if ( type_->compare_ )
00227 {
00228 canCompare = true;
00229 return type_->compare_( *this, other, canCompare );
00230 }
00231 else if ( type_->less_ )
00232 {
00233 canCompare = true;
00234 bool lhsLessThanRhs = type_->less_( *this, other, canCompare );
00235 if ( lhsLessThanRhs )
00236 return -1;
00237 if ( canCompare && type_->equal_ )
00238 return type_->equal_( *this, other, canCompare ) ? 0 : 1;
00239 if ( canCompare )
00240 return type_->less_( other, *this, canCompare ) ? 1 : 0;
00241 return 0;
00242 }
00243 canCompare = false;
00244 return 0;
00245 }
00246
00248 bool operator <( const Value &other ) const;
00250 bool operator <=( const Value &other ) const;
00252 bool operator ==( const Value &other ) const;
00254 bool operator !=( const Value &other ) const;
00256 bool operator >=( const Value &other ) const;
00258 bool operator >( const Value &other ) const;
00259
00260 public:
00262 ValueData data_;
00263
00264 private:
00265 const ValueType *type_;
00266 };
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 #ifdef CPPTL_NO_FUNCTION_TEMPLATE_ORDERING
00281 struct HasDefaultValueTypeHelper
00282 {
00283 };
00284
00285 inline HasDefaultValueTypeHelper getValueType( ... )
00286 {
00287 return HasDefaultValueTypeHelper();
00288 }
00289
00290 template<class T>
00291 inline const ValueType &getValueTypeHelper( const ValueType &valueType,
00292 const Type<T> &type )
00293 {
00294 return valueType;
00295 }
00296
00297 template<class T>
00298 inline const ValueType &getValueTypeSelector( const Type<T> &type )
00299 {
00300 return getValueTypeHelper( getValueType(type), type );
00301 }
00302
00303 # define CPPTL_GET_VALUE_TYPE( AType ) ::CppTL::getValueTypeSelector( ::CppTL::Type<AType>() )
00304
00305 # else
00306
00307 # define CPPTL_GET_VALUE_TYPE( AType ) ::CppTL::getValueType( ::CppTL::Type<AType>() )
00308
00309 # endif
00310
00311
00312 template<typename TargetValueType>
00313 void initialize( Value &value, Type<TargetValueType> )
00314 {
00315 }
00316
00317 template<typename TargetValueType>
00318 Value initialize( Type<TargetValueType> )
00319 {
00320 }
00321
00322
00323 template<typename TargetValueType>
00324 Value makeValue( const TargetValueType &value )
00325 {
00326 const ValueType &type = CPPTL_GET_VALUE_TYPE( TargetValueType );
00327 return Value( type, &value );
00328 }
00329
00330 template<typename TargetValueType>
00331 void makeValue( Value &value, const TargetValueType &initialValue )
00332 {
00333 }
00334
00335
00336 template<typename TargetValueType>
00337 const TargetValueType &any_cast( const Value &value, Type<TargetValueType> )
00338 {
00339 }
00340
00341 template<typename TargetValueType>
00342 TargetValueType &any_cast( Value &value, Type<TargetValueType> )
00343 {
00344 }
00345
00346 template<typename TargetValueType>
00347 const TargetValueType *any_cast( const Value *value, Type<TargetValueType> )
00348 {
00349 }
00350
00351 template<typename TargetValueType>
00352 TargetValueType *any_cast( Value *value, Type<TargetValueType> )
00353 {
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363 namespace ValueTypeHelper {
00364
00365
00367 template<typename DataType>
00368 class LargeTypeStorageHelper
00369 {
00370 public:
00371 static DataType &data( Value &value )
00372 {
00373 return *static_cast<DataType *>( value.data_.other_ );
00374 }
00375
00376 static const DataType &data( const Value &value )
00377 {
00378 return *static_cast<const DataType *>( value.data_.other_ );
00379 }
00380
00381 static void initialize( const void *data, Value &target )
00382 {
00383 target.data_.other_ = new DataType( *static_cast<const DataType *>( data ) );
00384 }
00385
00386 static void clone( const Value &source, Value &target )
00387 {
00388 target.data_.other_ = new DataType( data(source) );
00389 }
00390
00391 static void destroy( Value &target )
00392 {
00393 delete target.data_.other_;
00394 }
00395 };
00396
00397
00399 template<typename DataType>
00400 class SmallTypeStorageHelper
00401 {
00402 public:
00403 static DataType &data( Value &value )
00404 {
00405 return *(DataType *)( value.data_.string_ );
00406 }
00407
00408 static const DataType &data( const Value &value )
00409 {
00410 return *(const DataType *)( value.data_.string_ );
00411 }
00412
00413 static void initialize( const void *sourceData, Value &target )
00414 {
00415 DataType *targetData = &data(target);
00416 new (targetData) DataType( *static_cast<const DataType *>( sourceData ) );
00417 }
00418
00419 static void clone( const Value &source, Value &target )
00420 {
00421 DataType *targetData = &data(target);
00422 new (targetData) DataType( data(source) );
00423 }
00424
00425 static void destroy( Value &target )
00426 {
00427 data(target).~DataType();
00428 }
00429 };
00430
00431
00433 template<typename DataType>
00434 class StoragePolicySelector
00435 {
00436 public:
00437 typedef CPPTL_TYPENAME IfType<LargeTypeStorageHelper<DataType>
00438 ,SmallTypeStorageHelper<DataType>
00439 ,(sizeof(DataType) > sizeof(ValueDataBuffer))
00440 >::type type;
00441 };
00442
00443
00444 template<typename DataType>
00445 class CommonLifeCycle
00446 {
00447 public:
00448 typedef CommonLifeCycle<DataType> SelfType;
00449 typedef CPPTL_TYPENAME StoragePolicySelector<DataType>::type StoragePolicy;
00450
00451 static void registerFunctions( ValueType &type )
00452 {
00453 type.initialize_ = &StoragePolicy::initialize;
00454 type.clone_ = &StoragePolicy::clone;
00455 type.destroy_ = &StoragePolicy::destroy;
00456 }
00457 };
00458
00459
00460
00463 template<typename DataType>
00464 class Compare
00465 {
00466 public:
00467 typedef Compare<DataType> SelfType;
00468 typedef CPPTL_TYPENAME StoragePolicySelector<DataType>::type StoragePolicy;
00469
00470 static void registerFunctions( ValueType &type )
00471 {
00472 type.compare_ = &SelfType::compare;
00473 type.less_ = &SelfType::less;
00474 type.equal_ = &SelfType::equal;
00475 }
00476
00477 static int compare( const Value &aData, const Value &bData, bool &canCompare )
00478 {
00479 const DataType &a = StoragePolicy::data(aData);
00480 const DataType &b = StoragePolicy::data(bData);
00481 if ( a < b )
00482 return -1;
00483 if ( a == b )
00484 return 0;
00485 return 1;
00486 }
00487
00488 static bool less( const Value &aData, const Value &bData, bool &canCompare )
00489 {
00490 const DataType &a = StoragePolicy::data(aData);
00491 const DataType &b = StoragePolicy::data(bData);
00492 return a < b;
00493 }
00494
00495 static bool equal( const Value &aData, const Value &bData, bool &canCompare )
00496 {
00497 const DataType &a = StoragePolicy::data(aData);
00498 const DataType &b = StoragePolicy::data(bData);
00499 return a == b;
00500 }
00501 };
00502
00503
00506 template<typename DataType>
00507 class LessCompare
00508 {
00509 public:
00510 typedef Compare<DataType> SelfType;
00511 typedef CPPTL_TYPENAME StoragePolicySelector<DataType>::type StoragePolicy;
00512
00513 static void registerFunctions( ValueType &type )
00514 {
00515 type.compare_ = &SelfType::compare;
00516 type.less_ = &SelfType::less;
00517 type.equal_ = &SelfType::equal;
00518 }
00519
00520 static int compare( const Value &aData, const Value &bData, bool &canCompare )
00521 {
00522 const DataType &a = StoragePolicy::data(aData);
00523 const DataType &b = StoragePolicy::data(bData);
00524 if ( a < b )
00525 return -1;
00526 if ( b < a )
00527 return 1;
00528 return 0;
00529 }
00530
00531 static bool less( const Value &aData, const Value &bData, bool &canCompare )
00532 {
00533 const DataType &a = StoragePolicy::data(aData);
00534 const DataType &b = StoragePolicy::data(bData);
00535 return a < b;
00536 }
00537
00538 static bool equal( const Value &aData, const Value &bData, bool &canCompare )
00539 {
00540 const DataType &a = StoragePolicy::data(aData);
00541 const DataType &b = StoragePolicy::data(bData);
00542 return (a < b) && !(b < a);
00543 }
00544 };
00545
00546
00547 template<class DataType>
00548 class CommonValueType : public ValueType
00549 {
00550 public:
00551 CommonValueType()
00552 {
00553 clear();
00554 CommonLifeCycle<DataType>::registerFunctions( *this );
00555 }
00556 };
00557
00558
00559 template<class DataType>
00560 class ComparableValueType : public ValueType
00561 {
00562 public:
00563 ComparableValueType()
00564 {
00565 clear();
00566 CommonLifeCycle<DataType>::registerFunctions( *this );
00567 Compare<DataType>::registerFunctions( *this );
00568 }
00569 };
00570
00571
00572 }
00573
00574
00575
00576
00577 # ifdef CPPTL_NO_FUNCTION_TEMPLATE_ORDERING
00578 template<class DataType>
00579 inline const ValueType &getValueTypeSelector( const HasDefaultValueTypeHelper &,
00580 const Type<DataType> & )
00581 {
00582 # else
00583 template<class DataType>
00584 inline const ValueType &getValueType( const Type<DataType> & )
00585 {
00586 # endif
00587
00588
00589 static ValueTypeHelper::CommonValueType<DataType> type;
00590 return type;
00591 }
00592
00593
00594 struct NoneValueType : public ValueType
00595 {
00596 NoneValueType()
00597 {
00598 clear();
00599 clone_ = &NoneValueType::clone;
00600 compare_ = &NoneValueType::compare;
00601 }
00602
00603 static void clone( const Value &, Value & )
00604 {
00605 }
00606
00607 static int compare( const Value &aData, const Value &bData, bool &canCompare )
00608 {
00609 return 0;
00610 }
00611 };
00612
00613
00614 inline const ValueType &getValueType( Type<NoneValueTypeTag> )
00615 {
00616 static NoneValueType type;
00617 return type;
00618 }
00619
00620
00621 inline const ValueType &getValueType( Type<int> )
00622 {
00623 static ValueTypeHelper::ComparableValueType<int> type;
00624 return type;
00625 }
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 inline
00639 Value::Value()
00640 {
00641 type_ = &CPPTL_GET_VALUE_TYPE( NoneValueTypeTag );
00642 }
00643
00644
00645 inline
00646 Value::Value( const ValueType &type, const void *data )
00647 : type_( &type )
00648 {
00649 type.initialize_( data, *this );
00650 }
00651
00652
00653 inline bool
00654 Value::isNone() const
00655 {
00656 return type_ == &CPPTL_GET_VALUE_TYPE( NoneValueTypeTag );
00657 }
00658
00659
00660 inline bool
00661 Value::operator <( const Value &other ) const
00662 {
00663 bool canCompare;
00664 bool result = compare( other, canCompare ) < 0;
00665 if ( !canCompare )
00666 throw ValueException( ValueException::notSameType, "Value::operator <", type_, other.type_ );
00667 return result;
00668 }
00669
00670
00671 inline bool
00672 Value::operator <=( const Value &other ) const
00673 {
00674 bool canCompare;
00675 bool result = compare( other, canCompare ) <= 0;
00676 if ( !canCompare )
00677 throw ValueException( ValueException::notSameType, "Value::operator <=", type_, other.type_ );
00678 return result;
00679 }
00680
00681
00682 inline bool
00683 Value::operator ==( const Value &other ) const
00684 {
00685 bool canCompare;
00686 bool result = compare( other, canCompare ) == 0;
00687 if ( !canCompare )
00688 throw ValueException( ValueException::notSameType, "Value::operator ==", type_, other.type_ );
00689 return result;
00690 }
00691
00692
00693 inline bool
00694 Value::operator !=( const Value &other ) const
00695 {
00696 bool canCompare;
00697 bool result = compare( other, canCompare ) != 0;
00698 if ( !canCompare )
00699 throw ValueException( ValueException::notSameType, "Value::operator !=", type_, other.type_ );
00700 return result;
00701 }
00702
00703
00704 inline bool
00705 Value::operator >=( const Value &other ) const
00706 {
00707 bool canCompare;
00708 bool result = compare( other, canCompare ) >= 0;
00709 if ( !canCompare )
00710 throw ValueException( ValueException::notSameType, "Value::operator >=", type_, other.type_ );
00711 return result;
00712 }
00713
00714
00715 inline bool
00716 Value::operator >( const Value &other ) const
00717 {
00718 bool canCompare;
00719 bool result = compare( other, canCompare ) > 0;
00720 if ( !canCompare )
00721 throw ValueException( ValueException::notSameType, "Value::operator >", type_, other.type_ );
00722 return result;
00723 }
00724
00725
00726
00727
00728
00729 }
00730
00731 #endif // CPPTL_VALUE_H_INCLUDED