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

Popular posts from this blog

python - pip install -U PySide error -

arrays - C++ error: a brace-enclosed initializer is not allowed here before ‘{’ token -

cytoscape.js - How to add nodes to Dagre layout with Cytoscape -