MACE  1.0.0
 All Classes Namespaces Files Functions Variables Enumerations Defines
libs/stub/include/mace/stub/mirror_interface.hpp
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