// Paolo Medici // University of Parma #include <typeinfo> /// A minimalistic boost::any free implementation without virtual function. /// It do not have `clone' virtual function then a `shared pointer' technique is /// used. Object destructor are not called, then this class should be used only /// for destructorless types. /// Object size produced by this implementation should be lesser then boost::any /// In this example myanycast executable is 6228 bytes, anycast 7716 bytes. class any_type { struct value_type { const std::type_info * m_type; int m_ref_count; value_type(const std::type_info *type) : m_type(type), m_ref_count(1) { } }; template<typename T> struct impl_value_type: public value_type { T m_data; impl_value_type(const T & data) : value_type(&typeid(T)), m_data(data) { } }; value_type *value; void release() { if(value) { value->m_ref_count--; if(value->m_ref_count == 0) delete value; // WW not typesafe, and object destructor are not called. } } public: any_type() : value(0) { } any_type(const any_type & src) { src.value->m_ref_count++; value = src.value; } ~any_type() { release(); } template<class T> explicit any_type(const T & data) : value(0) { assign(data); } template<class T> void operator = (const T & data) { assign(data); } void operator = (const any_type & src) { src.value->m_ref_count++; release(); value = src.value; } template<class T> operator T () const { return get<T>(); } template<class T> void assign (const T & data) { release(); value = new impl_value_type<T>(data); } template<class T> T & get() const { if( *value->m_type == typeid(T) ) return static_cast<impl_value_type<T> *>(value)->m_data; else { throw std::bad_cast(); } } }; ///////////////////////////////////////////// TEST /////////////////// #include <vector> #include <iostream> void foo(const any_type & c) { std::cout << int(c) << std::endl; } int main() { std::vector<any_type> a; a.push_back(any_type(1)); a.push_back(any_type(1.0)); foo(a[0]); // int() works foo(a[1]); // int() throw an exception return 0; }