32 #include <Pt/TypeTraits.h>
66 friend T any_cast(
const Any&);
69 friend struct AnyCast;
77 virtual Value* clone(
char*)
const = 0;
78 virtual const std::type_info&
type()
const = 0;
79 virtual bool isRef()
const = 0;
80 virtual void*
get() = 0;
81 virtual const void*
get()
const = 0;
86 class BasicValue :
public Value
89 BasicValue(
const T& value = T())
93 const T& value()
const
99 virtual const std::type_info&
type()
const
100 {
return typeid(T); }
102 virtual Value* clone(
char* data)
const
104 return Any::cloneValue(_value, data);
107 virtual bool isRef()
const
113 virtual const void*
get()
const
121 template <
typename T>
122 class BasicRefValue :
public Value
125 BasicRefValue(T* value)
129 virtual const std::type_info&
type()
const
130 {
return typeid(T); }
132 virtual Value* clone(
char* data)
const
133 {
return new(data) BasicRefValue(_value); }
135 virtual bool isRef()
const
139 {
return (
void*) _value; }
141 virtual const void*
get()
const
149 class RefValue :
public Value
152 RefValue(
void* value,
const std::type_info& ti)
157 virtual bool isRef()
const
160 virtual const std::type_info&
type()
const
163 virtual Any::Value* clone(
char* data)
const
164 {
return new(data) RefValue(_value, *_ti); }
169 virtual const void*
get()
const
174 const std::type_info* _ti;
178 bool dataUsed()
const
179 {
return static_cast<const void*
>(_value) ==
static_cast<const void*
>(_data); }
192 template <
typename T>
196 _value = this->createValue(
type);
208 template <
typename T>
213 _value =
new(
static_cast<void*
>(_data)) BasicRefValue<T>(
type);
228 _value =
new(
static_cast<void*
>(_data)) RefValue(
type, ti);
242 Any& assign(Value* value);
310 {
return _value && _value->isRef(); }
319 const std::type_info&
type()
const
320 {
return _value ? _value->type() :
typeid(void); }
331 template <
typename T>
335 _value = this->createValue(rhs);
348 template <
typename T>
352 _value =
new(
static_cast<void*
>(_data)) BasicRefValue<T>(rhs);
369 const Any::Value* value()
const
388 return _value->get();
404 return _value->get();
411 static const unsigned sizeofData =
sizeof(RefValue);
413 template <
typename T>
414 struct IsSmallObject : BoolConstant< sizeof(BasicValue<T>) <= Any::sizeofData >
418 template <typename T>
419 static Value* cloneValue(const T& value, char* data);
421 template <typename T>
422 static Value* cloneValue(const T& value, char* data, TrueType);
424 template <typename T>
425 static Value* cloneValue(const T& value, char* data, FalseType);
427 template <typename T>
428 Value* createValue(const T& value);
430 template <typename T>
431 Value* createValue(const T& value, TrueType);
433 template <typename T>
434 Value* createValue(const T& value, FalseType);
441 alignas(Value) char _data[sizeofData];
444 template <typename T>
445 inline Any::Value* Any::cloneValue(const T& value, char* data)
447 return Any::cloneValue(value, data, IsSmallObject<T>());
450 template <typename T>
451 inline Any::Value* Any::cloneValue(const T& value, char* data, TrueType)
453 return new(data) BasicValue<T>(value);
456 template <typename T>
457 inline Any::Value* Any::cloneValue(const T& value, char*, FalseType)
459 return new BasicValue<T>(value);
462 template <typename T>
463 inline Any::Value* Any::createValue(const T& value)
465 return this->createValue(value, IsSmallObject<T>());
468 template <typename T>
469 inline Any::Value* Any::createValue(const T& value, TrueType)
471 return new(
static_cast<void*
>(_data)) BasicValue<T>(value);
474 template <
typename T>
475 inline Any::Value* Any::createValue(
const T& value, FalseType)
477 return new BasicValue<T>(value);
482 template <
typename T>
485 static T cast(
const Any& any)
494 if( any.type() ==
typeid(ValueT) )
496 void* v = any._value->get();
497 ValueT* vtp =
reinterpret_cast<ValueT*
>(v);
502 else if( 0 == std::strcmp(any.type().name(),
typeid(ValueT).name() ) )
504 void* v = any._value->get();
505 ValueT* vtp =
reinterpret_cast<ValueT*
>(v);
510 throw std::bad_cast();
516 template <
typename T>
519 static T* cast(
const Any& any)
528 if( any.type() ==
typeid(ValueT) )
530 void* v = any._value->get();
531 ValueT* vtp =
reinterpret_cast<ValueT*
>(v);
536 else if( 0 == std::strcmp(any.type().name(),
typeid(ValueT).name() ) )
538 void* v = any._value->get();
539 ValueT* vtp =
reinterpret_cast<ValueT*
>(v);
544 throw std::bad_cast();
559 template <
typename T>
562 return AnyCast<T>::cast(any);
566 inline Any& Any::assign(Value* value)
569 _value = value->clone(_data);
578 _value = val._value->clone(_data);
596 rhs._value = tmp->clone(rhs._data);
604 Value* tmp = rhs._value;
606 _value = tmp->clone(_data);
611 Value* tmp = rhs._value;
626 _value = rhs._value->clone(_data);