//////////////////////////////////////////////////////////////////////////////////////////////////// // TailoredAny.h #pragma once #include #include #include struct RttiTypeInfoStrategy { typedef Loki::TypeInfo TypeInfo; template static TypeInfo Identify() { return typeid(T); } template static TypeInfo Identify(const T& t) { return typeid(t); } }; template class TailoredAny { public: typedef TypeInfoStrategy_ TypeInfoStrategy; typedef typename TypeInfoStrategy_::TypeInfo TypeInfo; TailoredAny() : content_(0) {} template TailoredAny(const ValueType_& value) : content_(new Holder_(value)) {} TailoredAny(const TailoredAny& other) : content_(other.content_ ? other.content_->Clone() : 0) {} ~TailoredAny() { delete content_; } template TailoredAny& operator=(const ValueType_& value) { TailoredAny(value).Swap(*this); return *this; } TailoredAny& operator=(const TailoredAny& other) { TailoredAny(other).Swap(*this); return *this; } void Swap(TailoredAny& other) { std::swap(content_, other.content_); } bool Empty() const { return !content_; } TypeInfo Type() const { return content_ ? content->Type() : TypeInfoStrategy_::Identify(); } private: struct PlaceHolder_ : NewStrategy_ { virtual TypeInfo Type() const = 0; virtual PlaceHolder_* Clone() const = 0; virtual ~PlaceHolder_() {} }; template struct Holder_ : PlaceHolder_ { Holder_(const ValueType_& value) : held_(value) {} TypeInfo Type() const { return TypeInfoStrategy_::Identify(held_);; } PlaceHolder_* Clone() const { return new Holder_(held_); } ValueType_ held_; }; template friend ValueType_* TailoredAnyCast(TailoredAny*); PlaceHolder_* content_; }; //////////////////////////////////////////////////////////////////////////////////////////////////// template ValueType_* TailoredAnyCast(TailoredAny* operand) { typedef TailoredAny::TypeInfoStrategy TypeInfoStrategy; return operand && operand->Type() == TypeInfoStrategy::Identify() ? &static_cast::Holder_*>(operand->content_)->held_ : 0; } template const ValueType_* TailoredAnyCast(const TailoredAny* operand) { return TailoredAnyCast(const_cast*>(operand)); } template ValueType_ TailoredAnyCast(const TailoredAny& operand) { const ValueType_* result = TailoredAnyCast(&operand); if(!result) throw std::bad_cast(); return *result; } ////////////////////////////////////////////////////////////////////////////////////////////////////