MACE
1.0.0
|
00001 #ifndef BOOST_PP_IS_ITERATING 00002 #ifndef BOOST_STUB_MIRROR_INTERFACE_HPP 00003 #define BOOST_STUB_MIRROR_INTERFACE_HPP 00004 #include <boost/bind.hpp> 00005 #include <boost/preprocessor/repetition.hpp> 00006 #include <boost/preprocessor/seq/for_each.hpp> 00007 00008 #include <boost/fusion/container/vector.hpp> 00009 #include <boost/fusion/container/generation/make_vector.hpp> 00010 #include <boost/fusion/functional/generation/make_fused_function_object.hpp> 00011 #include <boost/fusion/functional/generation/make_unfused.hpp> 00012 #include <mace/stub/void.hpp> 00013 #include <mace/stub/vtable.hpp> 00014 #include <boost/type_traits/function_traits.hpp> 00015 #include <boost/type_traits/remove_pointer.hpp> 00016 #include <boost/type_traits/remove_reference.hpp> 00017 #include <boost/function_types/result_type.hpp> 00018 #include <boost/function.hpp> 00019 00020 namespace mace { namespace stub { 00025 template<typename MemberPtr> 00026 struct mirror_member; 00027 00028 namespace detail { 00029 namespace mirror_interface { 00030 #ifndef DOXYGEN 00031 00034 template<typename T, typename VTableType> 00035 class set_visitor { 00036 public: 00037 set_visitor( VTableType& vt, T& self ) 00038 :m_self(self),vtbl(vt){} 00039 00040 template<typename MemberPtr, MemberPtr m> 00041 void operator()( const char* name )const { 00042 typedef typename boost::function_types::result_type<MemberPtr>::type member_ref; 00043 typedef typename boost::remove_reference<member_ref>::type member; 00044 (vtbl.*m).set_delegate( &m_self, member::template get_member_ptr<T>() ); 00045 } 00046 private: 00047 T& m_self; 00048 VTableType& vtbl; 00049 }; 00050 00055 template<typename Interface, typename Delegate, typename VTableType> 00056 class set_visitor<vtable<Interface,Delegate>, VTableType> { 00057 public: 00058 typedef mace::stub::vtable<Interface,Delegate> T; 00059 00060 set_visitor( VTableType& vt, T& self ) 00061 :m_self(self),vtbl(vt){} 00062 00063 template<typename MemberPtr, MemberPtr m> 00064 void operator()( const char* name )const { 00065 typedef typename boost::function_types::result_type<MemberPtr>::type member_ref; 00066 typedef typename boost::remove_reference<member_ref>::type member; 00067 (vtbl.*m) = boost::bind( boost::ref( m_self.* member::template get_member_ptr<T>()), _1 ); 00068 } 00069 private: 00070 T& m_self; 00071 VTableType& vtbl; 00072 }; 00073 00074 #endif // DOXYGEN 00075 } 00076 } 00077 00090 struct mirror_interface 00091 { 00097 template<typename MemberPointer> 00098 struct calculate_type { 00099 typedef mirror_member<MemberPointer> type; 00100 }; 00101 00102 template<typename T, typename VTableType> 00103 static void set_vtable( VTableType& vtable, T& value ) { 00104 vtable_reflector<typename VTableType::interface_type,mirror_interface>::visit( detail::mirror_interface::set_visitor<T,VTableType>(vtable,value) ); 00105 } 00106 template<typename T, typename VTableType> 00107 static void set_vtable( VTableType& vtable, const T& value ) { 00108 vtable_reflector<typename VTableType::interface_type,mirror_interface>::visit( detail::mirror_interface::set_visitor<T,VTableType>(vtable,value) ); 00109 } 00110 }; 00111 00112 00113 00114 #define PARAM_NAME(z,n,type) BOOST_PP_CAT(a,n) 00115 #define PARAM_PLACE_HOLDER(z,n,type) BOOST_PP_CAT(_,BOOST_PP_ADD(n,1) ) 00116 #define PARAM_TYPE_NAME(z,n,type) BOOST_PP_CAT(typename A,n) 00117 #define PARAM_TYPE(z,n,type) BOOST_PP_CAT(A,n) 00118 #define PARAM_ARG(z,n,type) PARAM_TYPE(z,n,type) PARAM_NAME(z,n,type) 00119 #define DEDUCE_PARAM_TYPE(z,in,Type) typename boost::remove_const<typename boost::remove_reference<BOOST_PP_CAT(A,in)>::type >::type 00120 00121 # ifndef BOOST_STUB_MIRROR_IMPL_SIZE 00122 # define BOOST_STUB_MIRROR_IMPL_SIZE 8 00123 # endif 00124 00125 # include <boost/preprocessor/iteration/iterate.hpp> 00126 # define BOOST_PP_ITERATION_LIMITS (0, BOOST_STUB_MIRROR_IMPL_SIZE -1 ) 00127 # define BOOST_PP_FILENAME_1 <mace/stub/mirror_interface.hpp> 00128 # include BOOST_PP_ITERATE() 00129 00130 #undef PARAM_NAME 00131 #undef PARAM_TYPE 00132 #undef PARAM_ARG 00133 #undef DEDUCE_PARAM_TYPE 00134 00135 } } // namespace mace::stub 00136 #endif // BOOST_STUB_MIRROR_INTERFACE_HPP 00137 00138 #else // BOOST_PP_IS_ITERATING 00139 00140 #define n BOOST_PP_ITERATION() 00141 #define PARAM_NAMES BOOST_PP_ENUM(n,PARAM_NAME,A) // name_N 00142 #define PARAM_PLACE_HOLDERS BOOST_PP_ENUM_TRAILING(n,PARAM_PLACE_HOLDER,A) // _(N+1) 00143 #define PARAM_ARGS BOOST_PP_ENUM(n,PARAM_ARG,A) // TYPE_N name_N 00144 #define PARAM_TYPE_NAMES BOOST_PP_ENUM(n,PARAM_TYPE_NAME,A) // typename TYPE_N 00145 #define PARAM_TYPES BOOST_PP_ENUM(n,PARAM_TYPE,A) // TYPE_N 00146 #define DEDUCED_PARAM_TYPES BOOST_PP_ENUM(n,DEDUCE_PARAM_TYPE,A) // TYPE_N 00147 00148 template<typename R, typename Class BOOST_PP_COMMA_IF(n) PARAM_TYPE_NAMES> 00149 struct mirror_member<R(Class::*)(PARAM_TYPES)const> { 00150 // boost::result_of 00151 typedef typename adapt_void<R>::result_type result_type; 00152 typedef mirror_member self_type; 00153 typedef boost::fusion::vector<PARAM_TYPES> fused_params; 00154 typedef boost::fusion::vector<DEDUCED_PARAM_TYPES> deduced_params; 00155 typedef boost::function_traits<result_type(PARAM_TYPES)> traits; 00156 static const bool is_const = true; 00157 static const bool is_signal = false; 00158 00159 typedef typename boost::remove_pointer<result_type(*)(PARAM_TYPES)>::type signature; 00160 00161 result_type operator()( PARAM_ARGS )const { 00162 return m_delegate( boost::fusion::make_vector(PARAM_NAMES) ); 00163 } 00164 result_type operator() ( const fused_params& fp )const { 00165 return m_delegate( fp ); 00166 } 00167 mirror_member& operator=( const mirror_member& d ) { 00168 m_delegate = d.m_delegate; 00169 return *this; 00170 } 00171 template<typename T> 00172 mirror_member& operator=( const T& d ) { 00173 m_delegate = adapt_void<R,T>(d); 00174 return *this; 00175 } 00176 template<typename C, typename M> 00177 void set_delegate( C* s, M m ) { 00178 m_delegate = adapt_void<R, boost::function<R(const fused_params&)> >( 00179 boost::fusion::make_fused_function_object( 00180 boost::bind(m,s PARAM_PLACE_HOLDERS ) )); 00181 } 00182 private: 00183 boost::function<result_type(const fused_params&)> m_delegate; 00184 }; 00185 00186 template<typename R, typename Class BOOST_PP_COMMA_IF(n) PARAM_TYPE_NAMES> 00187 struct mirror_member<R(Class::*)(PARAM_TYPES)> 00188 { 00189 typedef typename adapt_void<R>::result_type result_type; 00190 00191 typedef mirror_member self_type; 00192 typedef boost::fusion::vector<PARAM_TYPES> fused_params; 00193 typedef boost::fusion::vector<DEDUCED_PARAM_TYPES> deduced_params; 00194 typedef boost::function_traits<result_type(PARAM_TYPES)> traits; 00195 typedef boost::function<result_type(const fused_params&)> delegate_type; 00196 static const bool is_const = false; 00197 static const bool is_signal = false; 00198 00199 // boost::result_of 00200 typedef typename boost::remove_pointer<result_type(*)(PARAM_TYPES)>::type signature; 00201 00202 result_type operator()( PARAM_ARGS ) { 00203 return m_delegate( boost::fusion::make_vector(PARAM_NAMES) ); 00204 } 00205 result_type operator() ( const fused_params& fp ) { 00206 return m_delegate( fp ); 00207 } 00208 template<typename T> 00209 mirror_member& operator=( const T& d ) { 00210 m_delegate = adapt_void<R,T>(d); 00211 return *this; 00212 } 00213 template<typename C, typename M> 00214 void set_delegate( C* s, M m ) { 00215 m_delegate = adapt_void<R, boost::function<R(const fused_params&)> >( 00216 boost::fusion::make_fused_function_object( 00217 boost::bind(m,s PARAM_PLACE_HOLDERS ) )); 00218 } 00219 private: 00220 delegate_type m_delegate; 00221 }; 00222 00223 #undef n 00224 #undef PARAM_NAMES 00225 #undef PARAM_PLACE_HOLDERS 00226 #undef PARAM_ARGS 00227 #undef PARAM_TYPE_NAMES 00228 #undef PARAM_TYPES 00229 00230 #endif // BOOST_PP_IS_ITERATING