metaSMT git
|
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 00200 template<typename Vec, template<class T> class Algo> 00201 typename eval_visitor<Vec, Algo>::result_type run_algorithm ( unsigned wanted ) 00202 { 00203 eval_visitor_0<Vec, Algo> visitor ( wanted ); 00204 mpl::for_each<Vec, boost::add_pointer<mpl::_> > (visitor); 00205 00206 return visitor.get_result (); 00207 } 00208 00209 template<typename Vec, template<class T> class Algo, typename ARG0> 00210 typename eval_visitor<Vec, Algo>::result_type run_algorithm ( unsigned wanted, ARG0 arg0 ) 00211 { 00212 eval_visitor_1<Vec, Algo, ARG0> visitor ( wanted, arg0 ); 00213 mpl::for_each<Vec, boost::add_pointer<mpl::_> > (visitor); 00214 00215 return visitor.get_result (); 00216 } 00217 00218 template<typename Vec, template<class T> class Algo, typename ARG0, typename ARG1> 00219 typename eval_visitor<Vec, Algo>::result_type run_algorithm ( unsigned wanted, ARG0 arg0, ARG1 arg1 ) 00220 { 00221 eval_visitor_2<Vec, Algo, ARG0, ARG1> visitor ( wanted, arg0, arg1 ); 00222 mpl::for_each<Vec, boost::add_pointer<mpl::_> > (visitor); 00223 00224 return visitor.get_result (); 00225 } 00226 00227 template<typename Vec, template<class T> class Algo, typename ARG0, typename ARG1, typename ARG2> 00228 typename eval_visitor<Vec, Algo>::result_type run_algorithm ( unsigned wanted, ARG0 arg0, ARG1 arg1, ARG2 arg2 ) 00229 { 00230 eval_visitor_3<Vec, Algo, ARG0, ARG1, ARG2> visitor ( wanted, arg0, arg1, arg2 ); 00231 mpl::for_each<Vec, boost::add_pointer<mpl::_> > (visitor); 00232 00233 return visitor.get_result (); 00234 } 00235 00236 template<typename Vec, template<class T> class Algo, typename ARG0, typename ARG1, typename ARG2, typename ARG3 > 00237 typename eval_visitor<Vec, Algo>::result_type run_algorithm ( unsigned wanted, ARG0 arg0, ARG1 arg1, ARG2 arg2, ARG3 arg3 ) 00238 { 00239 eval_visitor_4<Vec, Algo, ARG0, ARG1, ARG2, ARG3> visitor ( wanted, arg0, arg1, arg2, arg3 ); 00240 mpl::for_each<Vec, boost::add_pointer<mpl::_> > (visitor); 00241 00242 return visitor.get_result (); 00243 } 00244 00245 template<typename Vec, template<class T> class Algo, typename ARG0, typename ARG1, typename ARG2, typename ARG3, typename ARG4 > 00246 typename eval_visitor<Vec, Algo>::result_type run_algorithm ( unsigned wanted, ARG0 arg0, ARG1 arg1, ARG2 arg2, ARG3 arg3, ARG4 arg4 ) 00247 { 00248 eval_visitor_5<Vec, Algo, ARG0, ARG1, ARG2, ARG3, ARG4> visitor ( wanted, arg0, arg1, arg2, arg3, arg4 ); 00249 mpl::for_each<Vec, boost::add_pointer<mpl::_> > (visitor); 00250 00251 return visitor.get_result (); 00252 } 00253 00254 00255 00256 00257 00258 } 00259 00260