Boost Reflect Library 0.1.0
vtable.hpp
Go to the documentation of this file.
00001 /**
00002  *  @file reflect.hpp
00003  *
00004  *  This class defines the macros and types used to implement
00005  *  an REFLECT interface.
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    *  @brief Contains functors defined by InterfaceDelegate for each reflected member of InterfaceType
00032    *
00033    *  Use the @ref BOOST_REFLECT_ANY(NAME,MEMBERS) or BOOST_REFLECT_ANY_DERIVED(NAME,BASES,MEMBERS) to define the vtable for your
00034    *  type.
00035    */
00036   template<typename InterfaceType = void, typename InterfaceDelegate = boost::reflect::mirror_interface>
00037   class vtable {};
00038   
00039   /**
00040    *  @brief Enables specialization of visit for InterfaceType
00041    *
00042    *  This class is specialized by BOOST_REFLECT_ANY and BOOST_REFLECT_ANY_DERIVED
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 } } // 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

© Daniel Larimer 2010-2011 - Licensed under Boost Software License, Version 1.0 Boost Reflect Library