//Purpose: // Prototype a method for storing methods from each superclass // in a vector of most derived class. #include #include #include #include "boost/indexed_types/size_enum.hpp" enum super_numerals { s_0 , s_1 , s_2 }; namespace boost{namespace indexed_types{ template<>struct size_enum< super_numerals > { static unsigned const value=s_2+1; }; }}//exit boost::indexed_types namespace template < unsigned SuperId > struct super_types : public super_types { static unsigned const super_id= SuperId ; static void method(void) { std::cout<<"super_types<"<::method\n"; } }; template < > struct super_types < 0 > { }; #include using namespace boost; struct bottom : public super_types::value > { static unsigned const supers_size = boost::indexed_types::size_enum::value ; typedef void(* method_type )(void) ; struct methods_vec { methods_vec(void) { /* Do the following with mpl: methods[s_0]= super_types::method; methods[s_1]= super_types::method; methods[s_2]= super_types::method; */ typedef boost::mpl::range_c indices_type; put_method_at putter(*this); boost::mpl::for_each(putter); } method_type operator[](super_numerals i) { return methods[i]; } private: struct put_method_at /**@brief * Arg to mpl::for_each to fill elements * of methods_vec::methods. * @rationale * One alternative would be to define: * methods_vec::operator()(Index) * however, this would require the method to be * public. By making this structure private, * and a friend of methods_vec, the same purpose * is served without exposing the operator()(Index) * to "unauthorized" use. */ { put_method_at(methods_vec& a_vec) : my_vec(a_vec) {} template < class Index > void operator()(Index) { unsigned const i=Index::value; my_vec.methods[i]=super_types::method; } private: methods_vec& my_vec ; };//end put_method_at struct friend struct put_method_at ; method_type methods[supers_size] ; }; static methods_vec our_methods ; template < class Index > void operator()(Index)const { super_numerals const i=super_numerals(Index::value); std::cout<<"executing our_methods["< indices_type; boost::mpl::for_each(a_btm); } }; // static bottom:: methods_vec bottom:: our_methods ; void always_fail(void) { BOOST_CHECK(false); } namespace butf = boost::unit_test_framework; butf::test_suite* init_unit_test_suite(int argc, char* argv[]) { butf::test_suite* tests = BOOST_TEST_SUITE("static_dispatch tests"); tests->add(BOOST_TEST_CASE(&bottom::test)); tests->add(BOOST_TEST_CASE(&always_fail)); return tests; }