Bytemaster's Boost Libraries
|
00001 00008 #ifndef _BOOST_REFLECT_VTABLE_HPP_ 00009 #define _BOOST_REFLECT_VTABLE_HPP_ 00010 #include <boost/preprocessor/arithmetic/inc.hpp> 00011 #include <boost/typeof/typeof.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 00022 #include <boost/preprocessor/stringize.hpp> 00023 #include <boost/reflect/reflect.hpp> 00024 00025 namespace boost { namespace reflect { 00026 00027 struct mirror_interface; 00028 00029 00036 template<typename InterfaceType = void, typename InterfaceDelegate = boost::reflect::mirror_interface> 00037 class vtable {}; 00038 00044 template<typename InterfaceType> 00045 struct vtable_reflector { 00046 template<typename Visitor, typename InterfaceDelegate> 00047 static void visit( const boost::reflect::vtable<InterfaceType,InterfaceDelegate>* vtbl, const Visitor& v ) {} 00048 }; 00049 00050 #ifndef DOXYGEN 00051 template<typename t> 00052 class vtable_base{}; 00053 #endif 00054 00055 } } // namespace boost::reflect 00056 00057 #ifndef DOXYGEN 00058 #define BOOST_REFLECT_VTABLE_PUBLIC_BASE( r, data, elem ) boost::reflect::vtable<elem,data>, 00059 00060 #define BOOST_REFLECT_VTABLE_DEFINE_MEMBER( r, data, elem ) \ 00061 struct BOOST_PP_CAT( __reflect__, elem) : \ 00062 public InterfaceDelegate::template calculate_type<BOOST_TYPEOF(&interface_type::elem)>::type \ 00063 { \ 00064 typedef typename InterfaceDelegate::template calculate_type<BOOST_TYPEOF(&interface_type::elem)>::type base_type; \ 00065 using base_type::operator=;\ 00066 static const char* name() { return BOOST_PP_STRINGIZE(data); } \ 00067 template<typename Type, typename AssignType> \ 00068 static void get_member_ptr( AssignType v ) { v = &Type::elem; } \ 00069 } elem; 00070 00071 00072 #define BOOST_REFLECT_VTABLE_VISIT_BASE( r, visitor, name ) \ 00073 vtable_reflector<name>::visit( (const boost::reflect::vtable<name,InterfaceDelegate>*)vtbl, visitor ); 00074 00075 #define BOOST_REFLECT_VTABLE_VISIT_MEMBER( r, visitor, elem ) \ 00076 visitor.template operator()<BOOST_TYPEOF(vtable_type::elem),vtable_type,&vtable_type::elem>( BOOST_PP_STRINGIZE(elem) ); 00077 00078 // example of how to convert enumerate any BOOST_PP_SEQ, including BOOST_PP_SEQ_NIL 00079 #define BOOST_REFLECT_SEQ_ENUM(X) \ 00080 BOOST_PP_LIST_ENUM( \ 00081 BOOST_PP_LIST_REST( \ 00082 BOOST_PP_TUPLE_TO_LIST( BOOST_PP_INC(BOOST_PP_SEQ_SIZE(X)), BOOST_PP_SEQ_TO_TUPLE( \ 00083 BOOST_PP_SEQ_TRANSFORM( BOOST_REFLECT_VTABLE_PUBLIC_BASE, InterfaceDelegate, BOOST_PP_SEQ_PUSH_FRONT(X,(null)) ) ) ) \ 00084 ) \ 00085 ) 00086 00087 #endif 00088 00089 #define BOOST_REFLECT_ANY_DERIVED( NAME, INHERITS, MEMBERS ) \ 00090 BOOST_REFLECT_TYPEINFO(NAME) \ 00091 namespace boost { namespace reflect { \ 00092 template<typename InterfaceDelegate > \ 00093 struct vtable<NAME,InterfaceDelegate> : BOOST_PP_SEQ_FOR_EACH( BOOST_REFLECT_VTABLE_PUBLIC_BASE, InterfaceDelegate, INHERITS ) private vtable_base<NAME> { \ 00094 typedef NAME interface_type; \ 00095 BOOST_PP_SEQ_FOR_EACH( BOOST_REFLECT_VTABLE_DEFINE_MEMBER, NAME, MEMBERS ) \ 00096 }; \ 00097 template<> struct vtable_reflector<NAME> { \ 00098 typedef NAME interface_type; \ 00099 template<typename Visitor, typename InterfaceDelegate> \ 00100 static void visit( const boost::reflect::vtable<NAME,InterfaceDelegate>* vtbl, \ 00101 const Visitor& visitor ) { \ 00102 typedef boost::reflect::vtable<NAME,InterfaceDelegate> vtable_type; \ 00103 BOOST_PP_SEQ_FOR_EACH( BOOST_REFLECT_VTABLE_VISIT_BASE, visitor, INHERITS ) \ 00104 BOOST_PP_SEQ_FOR_EACH( BOOST_REFLECT_VTABLE_VISIT_MEMBER, visitor, MEMBERS ) \ 00105 } \ 00106 };\ 00107 \ 00108 } } 00109 00110 #define BOOST_REFLECT_ANY( NAME, MEMBERS ) \ 00111 BOOST_REFLECT_ANY_DERIVED( NAME, BOOST_PP_SEQ_NIL, MEMBERS ) 00112 00113 #endif