metaprogramming - c++ compile-time for loop over integer constant -
i working on porting windows c++ code linux, involves template specialization , boost::mpl. problem (1) cannot class template partial specialization compile (due argument dependence), (2) or if template can away from, meta programming technique needed loop on sequence of compile-time constant integers.
hope code snippet clearer description.
#include <vector> #include <boost/mpl/at.hpp> #include <boost/mpl/size.hpp> #include <boost/mpl/vector.hpp> class state_idle{}; class state_waitingtoturnon{}; class state_waitingtoturnoff{}; typedef boost::mpl::vector < state_idle, state_waitingtoturnon, state_waitingtoturnoff > ::type statelistx; #ifdef __linux__ template <class statelist>class mosstatemachine; typedef std::vector<void *> statetable; #if 0 // failed attempt no.1 // of course fails, there no partial specialization of function template template <class statelist, int n> static void filltable(statetable& table) { table.at(n) = (void*)(&mosstatemachine<statelist>::template performstatetransition <typename boost::mpl::at < statelist, boost::mpl::int_<n> > ::type >); filltable<statelist, n + 1>(table); } template <class statelist> void filltable <statelist, boost::mpl::size<statelist>::value>(statetable& table){} // error: function template partial specialization ‘filltable<statelist, boost::mpl::size<sequence>::value>’ not allowed template <class statelist> static statetable generatetable() { statetable table(boost::mpl::size<statelist>::value); filltable<statelist, 0>(table); return table; } #endif #if 1 // failed attempt no.2 // leverage class template partial specialization // fails because "specialized template argument" dependent on argument // (boost::mpl::size<statelist>::value statelist) template <class statelist, int n> struct bar { void operator()(statetable& table) { table.at(n) = &mosstatemachine<statelist>::template performstatetransition < typename boost::mpl::at < statelist, boost::mpl::int_<n> > ::type > ; bar<statelist, n + 1> b; b(table); } }; // error: template argument ‘boost::mpl::size<sequence>::value’ involves template parameter(s) template <class statelist> struct bar < statelist, boost::mpl::size<statelist>::value > { void operator()(statetable& table){} }; template <class statelist> static statetable generatetable() { statetable table(boost::mpl::size<statelist>::value); bar<statelist, 0> b; b(table); return table; } #endif #endif // !__linux__ template <class statelist> class mosstatemachine { public: explicit mosstatemachine(){} ~mosstatemachine(){} template <class state> void performstatetransition(){} #ifndef __linux__ // windows version. works msvc. not conform c++ standard , g++. // specialization should out of class. had failed attempts no.1 , 2 above. struct detail { typedef std::vector<void (mosstatemachine::*)()> statetable; static const int numberofstates = boost::mpl::size<statelist>::value; template <int n> static void filltable(statetable& table) { // following line of code essential these about. // need on sequence of compile time integer constant table.at(n) = &mosstatemachine::performstatetransition < typename boost::mpl::at<statelist, boost::mpl::int_<n> >::type > ; filltable<n + 1>(table); } template <> static void filltable<detail::numberofstates>(statetable& table){} static statetable generatetable() { statetable table(numberofstates); filltable<0>(table); return table; } }; #endif // !__linux__ void performstatetransitionbyid(int stateid) { #ifndef __linux__ static typename std::vector<void (mosstatemachine::*)()> lookuptable = detail::generatetable(); #else static typename std::vector<void (mosstatemachine::*)()> lookuptable = generatetable<statelist>(); #endif // !__linux__ (this->*(lookuptable.at(stateid)))(); } }; int main(int argc, char* argv[]) { mosstatemachine<statelistx>(); return 0; }
Comments
Post a Comment