MACE
1.0.0
|
00001 #ifndef _MACE_STUB_PTR_HPP 00002 #define _MACE_STUB_PTR_HPP 00003 #include <boost/shared_ptr.hpp> 00004 #include <boost/any.hpp> 00005 #include <boost/make_shared.hpp> 00006 #include <mace/stub/vtable.hpp> 00007 #include <mace/stub/mirror_interface.hpp> 00008 00009 namespace mace { namespace stub { 00010 00020 template<typename InterfaceType, typename InterfaceDelegate = mace::stub::mirror_interface> 00021 class ptr { 00022 public: 00023 typedef mace::stub::vtable<InterfaceType,InterfaceDelegate> vtable_type; 00024 typedef InterfaceType interface_type; 00025 typedef InterfaceDelegate delegate_type; 00026 00027 ptr() 00028 :m_vtable(boost::make_shared<vtable_type>()) {} 00029 00030 ptr( ptr&& m ) 00031 :m_vtable( std::move(m.m_vtable) ),m_ptr( std::move(m.m_ptr) ){} 00032 00033 operator bool()const { return m_vtable; } 00034 bool operator!()const { return !m_vtable; } 00035 00036 template<typename T> 00037 ptr( T* v ) 00038 :m_ptr( boost::make_shared<boost::any>(v) ),m_vtable(boost::make_shared<vtable_type>()) { 00039 InterfaceDelegate::set_vtable(*m_vtable,*v); 00040 } 00041 template<typename T> 00042 ptr( const boost::shared_ptr<T>& v ) 00043 :m_ptr(boost::make_shared<boost::any>(v)),m_vtable(boost::make_shared<vtable_type>()) { 00044 InterfaceDelegate::set_vtable(*m_vtable,*v); 00045 } 00046 00050 template<typename OtherInterface,typename OtherDelegate> 00051 ptr( const ptr<OtherInterface,OtherDelegate>& p ) 00052 :m_ptr(p),m_vtable(boost::make_shared<vtable_type>()) { 00053 InterfaceDelegate::set_vtable( *m_vtable, *boost::any_cast<ptr<OtherInterface,OtherDelegate>&>(m_ptr) ); 00054 } 00055 00056 const vtable_type& operator*()const { return *m_vtable; } 00057 vtable_type& operator*() { return *m_vtable; } 00058 00059 const vtable_type* operator->()const { return m_vtable.get(); } 00060 vtable_type* operator->() { return m_vtable.get(); } 00061 00062 protected: 00063 boost::shared_ptr<boost::any> m_ptr; 00064 boost::shared_ptr<vtable_type> m_vtable; 00065 }; 00071 template<typename InterfaceType,typename InterfaceDelegate, typename Visitor> 00072 void visit( const ptr<InterfaceType,InterfaceDelegate>& aptr, Visitor v ) { 00073 mace::stub::vtable_reflector<InterfaceType,InterfaceDelegate>::visit( v ); 00074 } 00075 00076 } } 00077 00078 #endif