-----Original Message----- From: Vladimir Prus [mailto:[EMAIL PROTECTED] Sent: Monday, March 24, 2003 10:25 AM To: Boost mailing list Subject: Re: [boost] boost::any feature request
[] P.S. And, BTW, it would be great to see the complete code that you propose (or a diff to CVS HEAD). Here are the sources I played with. It's far from perfect, but I think the basic idea is clear. The TailoredAny<> class has the prototype: <code> template<class NewStrategy_ = Loki::EmptyType, class TypeInfoStrategy_ = RttiTypeInfoStrategy> class TailoredAny; </code> So, it can be parametrized with the type identification strategy, not the memory allocation strategy only. And here are the Intel VTune results (see the sources for details): Creation Assignment struct 13383 27358 boost::any 3846 331870 TailoredAny<> 9151 310717 TailoredAny<Loki::SmallObject> 3855 110022 If we throw away the type identification strategy and leave it hardcoded as in the original boost::any the result of the TailoredAny<> will be better.
//////////////////////////////////////////////////////////////////////////////////////////////////// // TailoredAny.h #pragma once #include <algorithm> #include <Loki/EmptyType.h> #include <Loki/TypeInfo.h> struct RttiTypeInfoStrategy { typedef Loki::TypeInfo TypeInfo; template<typename T> static TypeInfo Identify() { return typeid(T); } template<typename T> static TypeInfo Identify(const T& t) { return typeid(t); } }; template<class NewStrategy_ = Loki::EmptyType, class TypeInfoStrategy_ = RttiTypeInfoStrategy> class TailoredAny { public: typedef TypeInfoStrategy_ TypeInfoStrategy; typedef typename TypeInfoStrategy_::TypeInfo TypeInfo; TailoredAny() : content_(0) {} template<class ValueType_> TailoredAny(const ValueType_& value) : content_(new Holder_<ValueType_>(value)) {} TailoredAny(const TailoredAny& other) : content_(other.content_ ? other.content_->Clone() : 0) {} ~TailoredAny() { delete content_; } template<class ValueType_> 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<void>(); } private: struct PlaceHolder_ : NewStrategy_ { virtual TypeInfo Type() const = 0; virtual PlaceHolder_* Clone() const = 0; virtual ~PlaceHolder_() {} }; template<class ValueType_> 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<class ValueType_, class S1_, class S2_> friend ValueType_* TailoredAnyCast(TailoredAny<S1_, S2_>*); PlaceHolder_* content_; }; //////////////////////////////////////////////////////////////////////////////////////////////////// template<class ValueType_, class S1_, class S2_> ValueType_* TailoredAnyCast(TailoredAny<S1_, S2_>* operand) { typedef TailoredAny<S1_, S2_>::TypeInfoStrategy TypeInfoStrategy; return operand && operand->Type() == TypeInfoStrategy::Identify<ValueType_>() ? &static_cast<TailoredAny<S1_, S2_>::Holder_<ValueType_>*>(operand->content_)->held_ : 0; } template<class ValueType_, class S1_, class S2_> const ValueType_* TailoredAnyCast(const TailoredAny<S1_, S2_>* operand) { return TailoredAnyCast<ValueType_, S1_>(const_cast<TailoredAny<S1_, S2_>*>(operand)); } template<class ValueType_, class S1_, class S2_> ValueType_ TailoredAnyCast(const TailoredAny<S1_, S2_>& operand) { const ValueType_* result = TailoredAnyCast<ValueType_>(&operand); if(!result) throw std::bad_cast(); return *result; } ////////////////////////////////////////////////////////////////////////////////////////////////////
// play_with_any.cpp : Defines the entry point for the console application. // #include <tchar.h> #include <vector> #include <string> #include <boost/any.hpp> #include <Loki/SmallObj.h> #include <Loki/TypeManip.h> #include "TailoredAny.h" typedef std::basic_string<TCHAR> tstring; //////////////////////////////////////////////////////////////////////////////////////////////////// // 'typical' properties structure template<class Variant_> struct Properties; template<> struct Properties<void> { bool bool1; int int1; int int2; int int3; int int4; double double1; tstring string1; }; template<class Variant_> struct Properties { Variant_ bool1; Variant_ int1; Variant_ int2; Variant_ int3; Variant_ int4; Variant_ double1; Variant_ string1; }; const tstring text(_T("Some new string property")); #define ASSIGN_PROPERTIES(p) \ p.bool1 = true;\ p.int1 = 1;\ p.int1 = 2;\ p.int3 = 3;\ p.int4 = 4;\ p.double1 = 3.14;\ p.string1 = text; //////////////////////////////////////////////////////////////////////////////////////////////////// // custom type info strategy template<typename T> struct TypeInfoTraits { enum { type = -1 }; }; template<> struct TypeInfoTraits<void> { enum { type = 0 }; }; template<> struct TypeInfoTraits<bool> { enum { type = 1 }; }; template<> struct TypeInfoTraits<int> { enum { type = 2 }; }; template<> struct TypeInfoTraits<double> { enum { type = 3 }; }; template<> struct TypeInfoTraits<tstring> { enum { type = 4 }; }; class CustomTypeInfoStrategy { static int TypeImpl(Loki::Int2Type<-1>); template<int N> static int TypeImpl(Loki::Int2Type<N>) { return N; } public: typedef int TypeInfo; template<typename T> static TypeInfo Type() { return TypeImpl(Loki::Int2Type<TypeInfoTraits<T>::type>()); } template<typename T> static TypeInfo Type(const T&) { return Type<T>(); } }; //////////////////////////////////////////////////////////////////////////////////////////////////// typedef std::vector<Properties<void> > SIMPLE_VEC; typedef std::vector<Properties<boost::any> > BOOST_ANY_VEC; // must be the same as with boost::any (1) typedef std::vector<Properties<TailoredAny<> > > TAILORED_ANY_VEC; // using with Loki::SmallObject for allocation (2) typedef std::vector<Properties<TailoredAny<Loki::SmallObject<> > > > TAILORED_ANY_VEC_M; const size_t N = 0x10000; //////////////////////////////////////////////////////////////////////////////////////////////////// // creation void CreateS(SIMPLE_VEC& v) { SIMPLE_VEC(N).swap(v); } void CreateA(BOOST_ANY_VEC& v) { BOOST_ANY_VEC(N).swap(v); } void CreateT(TAILORED_ANY_VEC& v) { TAILORED_ANY_VEC(N).swap(v); } void CreateTm(TAILORED_ANY_VEC_M& v) { TAILORED_ANY_VEC_M(N).swap(v); } //////////////////////////////////////////////////////////////////////////////////////////////////// // assignment void AssignS(SIMPLE_VEC& v) { for(size_t i = v.size(); i--;) { SIMPLE_VEC::value_type& p = v[i]; ASSIGN_PROPERTIES(p) } } void AssignA(BOOST_ANY_VEC& v) { for(size_t i = v.size(); i--;) { BOOST_ANY_VEC::value_type& p = v[i]; ASSIGN_PROPERTIES(p) } } void AssignT(TAILORED_ANY_VEC& v) { for(size_t i = v.size(); i--;) { TAILORED_ANY_VEC::value_type& p = v[i]; ASSIGN_PROPERTIES(p) } } void AssignTm(TAILORED_ANY_VEC_M& v) { for(size_t i = v.size(); i--;) { TAILORED_ANY_VEC_M::value_type& p = v[i]; ASSIGN_PROPERTIES(p) } } //////////////////////////////////////////////////////////////////////////////////////////////////// int _tmain(int argc, _TCHAR* argv[]) { SIMPLE_VEC v1(0); BOOST_ANY_VEC v2(0); TAILORED_ANY_VEC v3(0); TAILORED_ANY_VEC_M v4(0); CreateS(v1); CreateA(v2); CreateT(v3); CreateTm(v4); AssignS(v1); AssignA(v2); AssignT(v3); AssignTm(v4); return 0; } ////////////////////////////////////////////////////////////////////////////////////////////////////
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost