MACE  1.0.0
 All Classes Namespaces Files Functions Variables Enumerations Defines
libs/stub/include/mace/stub/vtable.hpp
Go to the documentation of this file.
00001 
00008 #ifndef _MACE_STUB_VTABLE_HPP_
00009 #define _MACE_STUB_VTABLE_HPP_
00010 #include <boost/typeof/typeof.hpp>
00011 #include <boost/preprocessor/arithmetic/inc.hpp>
00012 #include <boost/preprocessor/seq/push_front.hpp>
00013 #include <boost/preprocessor/seq/seq.hpp>
00014 #include <boost/preprocessor/seq/enum.hpp>
00015 #include <boost/preprocessor/seq/for_each.hpp>
00016 #include <boost/preprocessor/comparison/equal.hpp>
00017 #include <boost/preprocessor/seq/transform.hpp>
00018 #include <boost/preprocessor/seq/to_tuple.hpp>
00019 #include <boost/preprocessor/tuple/to_list.hpp>
00020 #include <boost/preprocessor/list/enum.hpp>
00021 #include <boost/preprocessor/stringize.hpp>
00022 
00023 namespace mace { namespace stub {
00024 
00025   struct mirror_interface;
00026   
00033   template<typename InterfaceType = void, typename InterfaceDelegate = mace::stub::mirror_interface>
00034   class vtable {};
00035   
00042   template<typename InterfaceType,typename InterfaceDelegate = mace::stub::mirror_interface> 
00043   struct vtable_reflector {
00044     template<typename Visitor>
00045     static void visit( const Visitor& v ) {}
00046   };
00047 
00048 #ifndef DOXYGEN
00049 
00051   template<typename t>
00052   class vtable_base{};
00053 #endif
00054 
00055 } } // namespace mace::stub
00056 
00057 #ifndef DOXYGEN
00058 
00059 #define MACE_STUB_VTABLE_PUBLIC_BASE( r, data, elem )  mace::stub::vtable<elem,data>,
00060 
00061 #define MACE_STUB_VTABLE_DEFINE_MEMBER( r, data, elem ) \
00062   struct BOOST_PP_CAT( __stub__, elem) : \
00063     public InterfaceDelegate::template calculate_type<BOOST_TYPEOF(&interface_type::elem)>::type  { \
00064       typedef typename InterfaceDelegate::template calculate_type<BOOST_TYPEOF(&interface_type::elem)>::type base_type;  \
00065       using base_type::operator=;\
00066       template<typename Type>\
00067       static decltype(&Type::elem) get_member_ptr() { return &Type::elem; } \
00068   } elem;
00069 
00070 
00071 #define MACE_STUB_VTABLE_VISIT_BASE( r, visitor, name ) \
00072   vtable_reflector<name,InterfaceDelegate>::visit( visitor );
00073 
00074 #ifndef WIN32
00075   #define TEMPLATE template
00076 #else
00077   #define TEMPLATE
00078 #endif
00079 
00080 #define MACE_STUB_VTABLE_VISIT_MEMBER( r, visitor, elem ) \
00081   visitor.TEMPLATE operator()<BOOST_TYPEOF(&vtable_type::elem),&vtable_type::elem>( BOOST_PP_STRINGIZE(elem) );
00082  //visitor.template operator()<BOOST_TYPEOF(&vtable_type::elem),&vtable_type::elem>( BOOST_PP_STRINGIZE(elem) );
00083 
00084 // example of how to convert enumerate any BOOST_PP_SEQ, including BOOST_PP_SEQ_NIL
00085 #define MACE_STUB_SEQ_ENUM(X) \
00086 BOOST_PP_LIST_ENUM( \
00087   BOOST_PP_LIST_REST( \
00088     BOOST_PP_TUPLE_TO_LIST( BOOST_PP_INC(BOOST_PP_SEQ_SIZE(X)), BOOST_PP_SEQ_TO_TUPLE( \
00089     BOOST_PP_SEQ_TRANSFORM( MACE_STUB_VTABLE_PUBLIC_BASE, InterfaceDelegate, BOOST_PP_SEQ_PUSH_FRONT(X,(null)) ) ) )  \
00090   ) \
00091 )
00092 
00093 #endif  // not DOXYGEN
00094 
00104 #define MACE_STUB_DERIVED( NAME, INHERITS, MEMBERS ) \
00105 namespace mace { namespace stub { \
00106 template<typename InterfaceDelegate > \
00107 struct vtable<NAME,InterfaceDelegate> : BOOST_PP_SEQ_FOR_EACH( MACE_STUB_VTABLE_PUBLIC_BASE, InterfaceDelegate, INHERITS ) private vtable_base<NAME> { \
00108     typedef NAME interface_type; \
00109     typedef InterfaceDelegate delegate_type; \
00110     BOOST_PP_SEQ_FOR_EACH( MACE_STUB_VTABLE_DEFINE_MEMBER, NAME, MEMBERS ) \
00111 }; \
00112 template<typename InterfaceDelegate> struct vtable_reflector<NAME,InterfaceDelegate> { \
00113     typedef NAME interface_type; \
00114     template<typename Visitor> \
00115     static void visit( const Visitor& visitor ) { \
00116         typedef mace::stub::vtable<NAME,InterfaceDelegate> vtable_type; \
00117         BOOST_PP_SEQ_FOR_EACH( MACE_STUB_VTABLE_VISIT_BASE, visitor, INHERITS ) \
00118         BOOST_PP_SEQ_FOR_EACH( MACE_STUB_VTABLE_VISIT_MEMBER, visitor, MEMBERS ) \
00119     } \
00120 };\
00121 \
00122 } } 
00123 
00132 #define MACE_STUB( NAME, MEMBERS ) \
00133     MACE_STUB_DERIVED( NAME, BOOST_PP_SEQ_NIL, MEMBERS )
00134 
00135 #endif