metaSMT 2
|
00001 #pragma once 00002 00003 #include <boost/mpl/for_each.hpp> 00004 #include <boost/mpl/at.hpp> 00005 #include <boost/mpl/empty.hpp> 00006 #include <boost/static_assert.hpp> 00007 #include <boost/type_traits/add_pointer.hpp> 00008 #include <boost/shared_ptr.hpp> 00009 00010 namespace metaSMT 00011 { 00012 namespace mpl = boost::mpl; 00013 00014 template<typename Vec, template<class T> class Algo> 00015 class eval_visitor 00016 { 00017 public: 00018 typedef typename Algo<typename mpl::at_c <Vec, 0>::type>::result_type result_type; 00019 00020 eval_visitor (unsigned wanted) : 00021 wanted_ (wanted) 00022 , result_ ( new result_type ) 00023 { 00024 // BOOST_STATIC_ASSERT ( !typename mpl::empty < Vec >::value ); 00025 } 00026 result_type get_result() const 00027 { 00028 return *result_; 00029 } 00030 00031 protected: 00032 unsigned wanted_; 00033 boost::shared_ptr < result_type > result_; 00034 }; 00035 00036 template<typename Vec, template<class T> class Algo> 00037 struct eval_visitor_0 : public eval_visitor < Vec, Algo > 00038 { 00039 eval_visitor_0 ( unsigned wanted ) 00040 : eval_visitor<Vec, Algo> ( wanted ) 00041 {} 00042 00043 template<typename U> 00044 void operator() (U const &) 00045 { 00046 typedef typename mpl::find < Vec,U>::type iter; 00047 unsigned pos = iter::pos::value; 00048 00049 if (pos == eval_visitor<Vec,Algo>::wanted_) 00050 { 00051 Algo< U > algo; 00052 *eval_visitor<Vec,Algo>::result_ = algo (); 00053 } 00054 } 00055 }; 00056 00057 00058 template<typename Vec, template<class T> class Algo, typename ARG0> 00059 struct eval_visitor_1 : public eval_visitor < Vec, Algo > 00060 { 00061 eval_visitor_1 (unsigned wanted, ARG0 arg0) : 00062 eval_visitor < Vec, Algo > ( wanted ) 00063 , arg0_ (arg0) {} 00064 00065 template<typename U> 00066 void operator() (U*) 00067 { 00068 typedef typename mpl::find < Vec,U>::type iter; 00069 unsigned pos = iter::pos::value; 00070 00071 if (pos == eval_visitor<Vec,Algo>::wanted_) 00072 { 00073 Algo< U > algo ( arg0_ ); 00074 *eval_visitor<Vec,Algo>::result_ = algo (); 00075 } 00076 } 00077 00078 private: 00079 ARG0 arg0_; 00080 }; 00081 00082 template<typename Vec, template<class T> class Algo, typename ARG0, typename ARG1> 00083 struct eval_visitor_2 : public eval_visitor < Vec, Algo > 00084 { 00085 eval_visitor_2 (unsigned wanted, ARG0 arg0, ARG1 arg1) : 00086 eval_visitor < Vec, Algo > ( wanted ) 00087 , arg0_ (arg0) 00088 , arg1_ (arg1) {} 00089 00090 template<typename U> 00091 void operator() (U *) 00092 { 00093 typedef typename mpl::find < Vec,U>::type iter; 00094 unsigned pos = iter::pos::value; 00095 00096 if (pos == eval_visitor<Vec,Algo>::wanted_) 00097 { 00098 Algo< U > algo ( arg0_ , arg1_ ); 00099 *eval_visitor<Vec,Algo>::result_ = algo (); 00100 } 00101 } 00102 00103 private: 00104 ARG0 arg0_; 00105 ARG1 arg1_; 00106 }; 00107 00108 template<typename Vec, template<class T> class Algo, typename ARG0, typename ARG1, typename ARG2> 00109 struct eval_visitor_3 : public eval_visitor < Vec, Algo > 00110 { 00111 eval_visitor_3 (unsigned wanted, ARG0 arg0, ARG1 arg1, ARG2 arg2) : 00112 eval_visitor < Vec, Algo > ( wanted ) 00113 , arg0_ (arg0) 00114 , arg1_ (arg1) 00115 , arg2_ (arg2) {} 00116 00117 template<typename U> 00118 void operator() (U*) 00119 { 00120 typedef typename mpl::find < Vec,U>::type iter; 00121 unsigned pos = iter::pos::value; 00122 00123 if (pos == eval_visitor<Vec,Algo>::wanted_) 00124 { 00125 Algo< U > algo ( arg0_ , arg1_ , arg2_ ); 00126 *eval_visitor<Vec,Algo>::result_ = algo (); 00127 } 00128 } 00129 00130 private: 00131 ARG0 arg0_; 00132 ARG1 arg1_; 00133 ARG2 arg2_; 00134 }; 00135 00136 template<typename Vec, template<class T> class Algo, typename ARG0, typename ARG1, typename ARG2, typename ARG3> 00137 struct eval_visitor_4 : public eval_visitor < Vec, Algo > 00138 { 00139 eval_visitor_4 (unsigned wanted, ARG0 arg0, ARG1 arg1, ARG2 arg2, ARG3 arg3) : 00140 eval_visitor < Vec, Algo > ( wanted ) 00141 , arg0_ (arg0) 00142 , arg1_ (arg1) 00143 , arg2_ (arg2) 00144 , arg3_ (arg3) {} 00145 00146 template<typename U> 00147 void operator() (U*) 00148 { 00149 typedef typename mpl::find < Vec,U>::type iter; 00150 unsigned pos = iter::pos::value; 00151 00152 if (pos == eval_visitor<Vec,Algo>::wanted_) 00153 { 00154 Algo< U > algo ( arg0_ , arg1_ , arg2_, arg3_ ); 00155 *eval_visitor<Vec,Algo>::result_ = algo (); 00156 } 00157 } 00158 00159 private: 00160 ARG0 arg0_; 00161 ARG1 arg1_; 00162 ARG2 arg2_; 00163 ARG3 arg3_; 00164 }; 00165 00166 template<typename Vec, template<class T> class Algo, typename ARG0, typename ARG1, typename ARG2, typename ARG3, typename ARG4> 00167 struct eval_visitor_5 : public eval_visitor < Vec, Algo > 00168 00169 { 00170 eval_visitor_5 (unsigned wanted, ARG0 arg0, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4) : 00171 eval_visitor < Vec, Algo > ( wanted ) 00172 , arg0_ (arg0) 00173 , arg1_ (arg1) 00174 , arg2_ (arg2) 00175 , arg3_ (arg3) 00176 , arg4_ (arg4) {} 00177 00178 template<typename U> 00179 void operator() (U*) 00180 { 00181 typedef typename mpl::find < Vec,U>::type iter; 00182 unsigned pos = iter::pos::value; 00183 00184 if (pos == eval_visitor<Vec,Algo>::wanted_) 00185 { 00186 Algo< U > algo ( arg0_ , arg1_ , arg2_, arg3_, arg4_ ); 00187 *eval_visitor<Vec,Algo>::result_ = algo (); 00188 } 00189 } 00190 00191 private: 00192 ARG0 arg0_; 00193 ARG1 arg1_; 00194 ARG2 arg2_; 00195 ARG3 arg3_; 00196 ARG4 arg4_; 00197 }; 00198 00199 00248 template<typename Vec, template<class T> class Algo> 00249 typename eval_visitor<Vec, Algo>::result_type run_algorithm ( unsigned wanted ) 00250 { 00251 eval_visitor_0<Vec, Algo> visitor ( wanted ); 00252 mpl::for_each<Vec, boost::add_pointer<mpl::_> > (visitor); 00253 00254 return visitor.get_result (); 00255 } 00256 00257 template<typename Vec, template<class T> class Algo, typename ARG0> 00258 typename eval_visitor<Vec, Algo>::result_type run_algorithm ( unsigned wanted, ARG0 arg0 ) 00259 { 00260 eval_visitor_1<Vec, Algo, ARG0> visitor ( wanted, arg0 ); 00261 mpl::for_each<Vec, boost::add_pointer<mpl::_> > (visitor); 00262 00263 return visitor.get_result (); 00264 } 00265 00266 template<typename Vec, template<class T> class Algo, typename ARG0, typename ARG1> 00267 typename eval_visitor<Vec, Algo>::result_type run_algorithm ( unsigned wanted, ARG0 arg0, ARG1 arg1 ) 00268 { 00269 eval_visitor_2<Vec, Algo, ARG0, ARG1> visitor ( wanted, arg0, arg1 ); 00270 mpl::for_each<Vec, boost::add_pointer<mpl::_> > (visitor); 00271 00272 return visitor.get_result (); 00273 } 00274 00275 template<typename Vec, template<class T> class Algo, typename ARG0, typename ARG1, typename ARG2> 00276 typename eval_visitor<Vec, Algo>::result_type run_algorithm ( unsigned wanted, ARG0 arg0, ARG1 arg1, ARG2 arg2 ) 00277 { 00278 eval_visitor_3<Vec, Algo, ARG0, ARG1, ARG2> visitor ( wanted, arg0, arg1, arg2 ); 00279 mpl::for_each<Vec, boost::add_pointer<mpl::_> > (visitor); 00280 00281 return visitor.get_result (); 00282 } 00283 00284 template<typename Vec, template<class T> class Algo, typename ARG0, typename ARG1, typename ARG2, typename ARG3 > 00285 typename eval_visitor<Vec, Algo>::result_type run_algorithm ( unsigned wanted, ARG0 arg0, ARG1 arg1, ARG2 arg2, ARG3 arg3 ) 00286 { 00287 eval_visitor_4<Vec, Algo, ARG0, ARG1, ARG2, ARG3> visitor ( wanted, arg0, arg1, arg2, arg3 ); 00288 mpl::for_each<Vec, boost::add_pointer<mpl::_> > (visitor); 00289 00290 return visitor.get_result (); 00291 } 00292 00293 template<typename Vec, template<class T> class Algo, typename ARG0, typename ARG1, typename ARG2, typename ARG3, typename ARG4 > 00294 typename eval_visitor<Vec, Algo>::result_type run_algorithm ( unsigned wanted, ARG0 arg0, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4 ) 00295 { 00296 eval_visitor_5<Vec, Algo, ARG0, ARG1, ARG2, ARG3, ARG4> visitor ( wanted, arg0, arg1, arg2, arg3, arg4 ); 00297 mpl::for_each<Vec, boost::add_pointer<mpl::_> > (visitor); 00298 00299 return visitor.get_result (); 00300 } 00301 00303 } 00304 00305