MACE
1.0.0
|
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