Listing 3
class any_ptr { public: template <class T> struct functions; template <class T> any_ptr(T* x) : m_a(x), m_t(&functions<T>::table) {} any_ptr() : m_a(NULL), m_t(NULL) {} void Delete() { assert(m_a != NULL); m_t->Delete(m_a); m_a = NULL; } const std::type_info& GetType() const { return m_t->GetType(m_a); } any_ptr Clone() const { any_ptr o(*this); o.m_a = m_t->Clone(m_a); return o; } template<typename ValueType> ValueType* PtrCast() { if (!(typeid(ValueType) == GetType())) { throw BadObjectCast(); } return static_cast<ValueType*>(m_a); } // Function table type order is important // It must match all other lists of functions struct table { void (*Delete)(void*); const std::type_info& (*GetType)(void*); void* (*Clone)(void*); }; // For a given referenced type T, generates functions for the // function table and a static instance of the table. template<class T> struct functions { static typename any_ptr::table table; static void Delete(void* p) { delete static_cast<T*>(p); } static const std::type_info& GetType(void* p) { return typeid(T); } static void* Clone(void* p) { return new T(*static_cast<T*>(p)); } }; private: void* m_a; table* m_t; }; template<class T> typename any_ptr::table any_ptr::functions<T>::table = { &any_ptr::template functions<T>::Delete ,&any_ptr::template functions<T>::GetType ,&any_ptr::template functions<T>::Clone };