#ifndef Reflex_Any
#define Reflex_Any
#include "Reflex/Kernel.h"
#include <algorithm>
#include <typeinfo>
#include <iostream>
namespace Reflex {
class RFLX_API Any {
friend RFLX_API std::ostream& operator <<(std::ostream&,
const Any&);
public:
Any():
fContent(0) {}
template <typename ValueType> Any(const ValueType &value):
fContent(new Holder<ValueType>(value)) {}
Any(const Any &other):
fContent(other.fContent ? other.fContent->Clone() : 0) {}
~Any() {
delete fContent;
}
void
Clear() {
if (!Empty()) {
delete fContent;
fContent = 0;
}
}
operator bool() {
return !Empty();
}
Any&
Swap(Any& rhs) {
std::swap(fContent, rhs.fContent);
return *this;
}
template <typename ValueType> Any&
operator =(const ValueType& rhs) {
Any(rhs).Swap(*this);
return *this;
}
Any&
operator =(const Any& rhs) {
Any(rhs).Swap(*this);
return *this;
}
bool
Empty() const {
return !fContent;
}
const std::type_info&
TypeInfo() const {
return fContent ? fContent->TypeInfo() : typeid(void);
}
void*
Address() const {
return fContent ? fContent->Address() : 0;
}
private:
class Placeholder {
public:
Placeholder() {}
virtual ~Placeholder() {}
virtual const std::type_info& TypeInfo() const = 0;
virtual Placeholder* Clone() const = 0;
virtual void* Address() const = 0;
};
template <typename ValueType> class Holder: public Placeholder {
public:
Holder(const ValueType& value):
fHeld(value) {}
virtual const std::type_info&
TypeInfo() const {
return typeid(ValueType);
}
virtual Placeholder*
Clone() const {
return new Holder(fHeld);
}
virtual void*
Address() const {
return (void*) (&fHeld);
}
ValueType fHeld;
};
template <typename ValueType> friend ValueType* any_cast(Any*);
Placeholder* fContent;
};
class BadAnyCast: public std::bad_cast {
public:
BadAnyCast() {}
virtual const char*
what() const throw() {
return "BadAnyCast: failed conversion using any_cast";
}
};
template <class E> void
throw_exception(const E& e) {
throw e;
}
template <typename ValueType> ValueType*
any_cast(Any* operand) {
return operand && operand->TypeInfo() == typeid(ValueType)
? &static_cast<Any::Holder<ValueType>*>(operand->fContent)->fHeld : 0;
}
template <typename ValueType> const ValueType*
any_cast(const Any* operand) {
return any_cast<ValueType>(const_cast<Any*>(operand));
}
template <typename ValueType> ValueType
any_cast(const Any& operand) {
const ValueType* result = any_cast<ValueType>(&operand);
if (!result) {
throw_exception(BadAnyCast());
}
return *result;
}
RFLX_API std::ostream& operator <<(std::ostream&,
const Any&);
}
#endif // Reflex_Any