Bytemaster's Boost Libraries
|
00001 #ifndef _BOOST_REFLECT_ANY_PTR_HPP 00002 #define _BOOST_REFLECT_ANY_PTR_HPP 00003 #include <boost/shared_ptr.hpp> 00004 #include <boost/any.hpp> 00005 #include <boost/reflect/vtable.hpp> 00006 #include <boost/reflect/mirror_interface.hpp> 00007 00008 namespace boost { namespace reflect { 00009 00019 template<typename InterfaceType, typename InterfaceDelegate = boost::reflect::mirror_interface> 00020 class any_ptr { 00021 public: 00022 typedef boost::reflect::vtable<InterfaceType,InterfaceDelegate> vtable_type; 00023 typedef InterfaceType interface_type; 00024 typedef InterfaceDelegate delegate_type; 00025 00026 any_ptr() 00027 :m_vtable(new vtable_type()) {} 00028 00029 operator bool()const { return m_vtable; } 00030 bool operator!()const { return !m_vtable; } 00031 00032 template<typename T> 00033 any_ptr( T* v ) 00034 :m_ptr(v),m_vtable(new vtable_type()) { 00035 InterfaceDelegate::set_vtable(*m_vtable,*v); 00036 } 00037 template<typename T> 00038 any_ptr( const boost::shared_ptr<T>& v ) 00039 :m_ptr(v),m_vtable(new vtable_type()) { 00040 InterfaceDelegate::set_vtable(*m_vtable,*v); 00041 } 00042 00046 template<typename OtherInterface,typename OtherDelegate> 00047 any_ptr( const any_ptr<OtherInterface,OtherDelegate>& p ) 00048 :m_ptr(p),m_vtable(new vtable_type()) { 00049 InterfaceDelegate::set_vtable( *m_vtable, *boost::any_cast<any_ptr<OtherInterface,OtherDelegate>&>(m_ptr) ); 00050 } 00051 00052 const vtable_type& operator*()const { return *m_vtable; } 00053 vtable_type& operator*() { return *m_vtable; } 00054 00055 const vtable_type* operator->()const { return m_vtable.get(); } 00056 vtable_type* operator->() { return m_vtable.get(); } 00057 00058 protected: 00059 00060 boost::any m_ptr; 00061 boost::shared_ptr<vtable_type> m_vtable; 00062 }; 00068 template<typename InterfaceType,typename InterfaceDelegate, typename Visitor> 00069 void visit( const any_ptr<InterfaceType,InterfaceDelegate>& aptr, Visitor v ) { 00070 boost::reflect::vtable_reflector<InterfaceType>::visit( &*aptr, v ); 00071 } 00072 00073 } } 00074 00075 #endif