Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
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
00030
00031
00032
00033
00034
00035
00036 template<typename InterfaceType = void, typename InterfaceDelegate = boost::reflect::mirror_interface>
00037 class vtable {};
00038
00039
00040
00041
00042
00043
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 } }
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
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