00001 #ifndef NPSTAT_SIMPLEFUNCTORS_HH_ 00002 #define NPSTAT_SIMPLEFUNCTORS_HH_ 00003 00015 namespace npstat { 00017 template <typename Result> 00018 struct Functor0 00019 { 00020 typedef Result result_type; 00021 00022 inline virtual ~Functor0() {} 00023 virtual Result operator()() const = 0; 00024 }; 00025 00027 template <typename Result, typename Arg1> 00028 struct Functor1 00029 { 00030 typedef Result result_type; 00031 typedef Arg1 first_argument_type; 00032 00033 inline virtual ~Functor1() {} 00034 virtual Result operator()(const Arg1&) const = 0; 00035 }; 00036 00038 template <typename Result, typename Arg1, typename Arg2> 00039 struct Functor2 00040 { 00041 typedef Result result_type; 00042 typedef Arg1 first_argument_type; 00043 typedef Arg2 second_argument_type; 00044 00045 inline virtual ~Functor2() {} 00046 virtual Result operator()(const Arg1&, const Arg2&) const = 0; 00047 }; 00048 00050 template <typename Result, typename Arg1, typename Arg2, typename Arg3> 00051 struct Functor3 00052 { 00053 typedef Result result_type; 00054 typedef Arg1 first_argument_type; 00055 typedef Arg2 second_argument_type; 00056 typedef Arg3 third_argument_type; 00057 00058 inline virtual ~Functor3() {} 00059 virtual Result operator()(const Arg1&,const Arg2&,const Arg3&) const=0; 00060 }; 00061 00063 template <typename Result> 00064 struct Same : public Functor1<Result, Result> 00065 { 00066 inline Result operator()(const Result& a) const {return a;} 00067 }; 00068 00070 template <typename Result> 00071 struct SameRef : public Functor1<const Result&, Result> 00072 { 00073 inline const Result& operator()(const Result& a) const {return a;} 00074 }; 00075 00080 template <typename Result> 00081 struct DefaultConstructor0 : public Functor0<Result> 00082 { 00083 inline Result operator()() const {return Result();} 00084 }; 00085 00090 template <typename Result, typename Arg1> 00091 struct DefaultConstructor1 : public Functor1<Result, Arg1> 00092 { 00093 inline Result operator()(const Arg1&) const {return Result();} 00094 }; 00095 00100 template <typename Result, typename Arg1, typename Arg2> 00101 struct DefaultConstructor2 : public Functor2<Result, Arg1, Arg2> 00102 { 00103 inline Result operator()(const Arg1&, const Arg2&) const 00104 {return Result();} 00105 }; 00106 00111 template <typename Result, typename Arg1, typename Arg2, typename Arg3> 00112 struct DefaultConstructor3 : public Functor3<Result, Arg1, Arg2, Arg3> 00113 { 00114 inline Result operator()(const Arg1&, const Arg2&, const Arg3&) const 00115 {return Result();} 00116 }; 00117 00122 template <typename Result, typename Arg1, typename CastType> 00123 struct CastingCopyConstructor : public Functor1<Result, Arg1> 00124 { 00125 inline Result operator()(const Arg1& a) const 00126 {return Result(static_cast<CastType>(a));} 00127 }; 00128 00133 template <typename Result> 00134 struct FcnFunctor0 : public Functor0<Result> 00135 { 00136 inline explicit FcnFunctor0(Result (*fcn)()) : fcn_(fcn) {} 00137 00138 inline Result operator()() const {return fcn_();} 00139 00140 private: 00141 FcnFunctor0(); 00142 Result (*fcn_)(); 00143 }; 00144 00149 template <typename Result, typename Arg1> 00150 struct FcnFunctor1 : public Functor1<Result, Arg1> 00151 { 00152 inline explicit FcnFunctor1(Result (*fcn)(Arg1)) : fcn_(fcn) {} 00153 00154 inline Result operator()(const Arg1& a) const {return fcn_(a);} 00155 00156 private: 00157 FcnFunctor1(); 00158 Result (*fcn_)(Arg1); 00159 }; 00160 00165 template <typename Result, typename Arg1, typename Arg2> 00166 struct FcnFunctor2 : public Functor2<Result, Arg1, Arg2> 00167 { 00168 inline explicit FcnFunctor2(Result (*fcn)(Arg1, Arg2)) : fcn_(fcn) {} 00169 00170 inline Result operator()(const Arg1& x, const Arg2& y) const 00171 {return fcn_(x, y);} 00172 00173 private: 00174 FcnFunctor2(); 00175 Result (*fcn_)(Arg1, Arg2); 00176 }; 00177 00182 template <typename Result, typename Arg1, typename Arg2, typename Arg3> 00183 struct FcnFunctor3 : public Functor3<Result, Arg1, Arg2, Arg3> 00184 { 00185 inline explicit FcnFunctor3(Result (*fcn)(Arg1,Arg2,Arg3)):fcn_(fcn) {} 00186 00187 inline Result operator()(const Arg1&x,const Arg2&y,const Arg3&z) const 00188 {return fcn_(x, y, z);} 00189 00190 private: 00191 FcnFunctor3(); 00192 Result (*fcn_)(Arg1, Arg2, Arg3); 00193 }; 00194 00199 template <class Container, class Result = typename Container::value_type> 00200 struct Element1D : public Functor1<Result, Container> 00201 { 00202 inline explicit Element1D(const unsigned long index) : idx(index) {} 00203 00204 inline Result operator()(const Container& c) const {return c[idx];} 00205 00206 private: 00207 Element1D(); 00208 unsigned long idx; 00209 }; 00210 00215 template <class Container, class Result = typename Container::value_type> 00216 struct Element1DAt : public Functor1<Result, Container> 00217 { 00218 inline explicit Element1DAt(const unsigned long index) : idx(index) {} 00219 00220 inline Result operator()(const Container& c) const {return c.at(idx);} 00221 00222 private: 00223 Element1DAt(); 00224 unsigned long idx; 00225 }; 00226 00231 template <typename T1, typename T2> 00232 struct assign_left 00233 { 00234 inline T1& operator()(T1& left, const T2& right) const 00235 {return left = right;} 00236 }; 00237 00242 template <typename T1, typename T2> 00243 struct assign_right 00244 { 00245 inline T2& operator()(const T1& left, T2& right) const 00246 {return right = left;} 00247 }; 00248 00250 template <typename T1, typename T2> 00251 struct pluseq_left 00252 { 00253 inline T1& operator()(T1& left, const T2& right) const 00254 {return left += right;} 00255 }; 00256 00258 template <typename T1, typename T2> 00259 struct pluseq_right 00260 { 00261 inline T2& operator()(const T1& left, T2& right) const 00262 {return right += left;} 00263 }; 00264 00269 template <typename T1, typename T2> 00270 struct addmul_left 00271 { 00272 inline explicit addmul_left(const double weight) : w_(weight) {} 00273 00274 inline T1& operator()(T1& left, const T2& right) const 00275 {return left += w_*right;} 00276 00277 private: 00278 addmul_left(); 00279 double w_; 00280 }; 00281 00286 template <typename T1, typename T2> 00287 struct addmul_right 00288 { 00289 inline explicit addmul_right(const double weight) : w_(weight) {} 00290 00291 inline T1& operator()(T1& left, const T2& right) const 00292 {return right += w_*left;} 00293 00294 private: 00295 addmul_right(); 00296 double w_; 00297 }; 00298 00300 template <typename T1, typename T2> 00301 struct minuseq_left 00302 { 00303 inline T1& operator()(T1& left, const T2& right) const 00304 {return left -= right;} 00305 }; 00306 00308 template <typename T1, typename T2> 00309 struct minuseq_right 00310 { 00311 inline T2& operator()(const T1& left, T2& right) const 00312 {return right -= left;} 00313 }; 00314 00316 template <typename T1, typename T2> 00317 struct multeq_left 00318 { 00319 inline T1& operator()(T1& left, const T2& right) const 00320 {return left *= right;} 00321 }; 00322 00324 template <typename T1, typename T2> 00325 struct multeq_right 00326 { 00327 inline T2& operator()(const T1& left, T2& right) const 00328 {return right *= left;} 00329 }; 00330 00332 template <typename T1, typename T2> 00333 struct diveq_left 00334 { 00335 inline T1& operator()(T1& left, const T2& right) const 00336 {return left /= right;} 00337 }; 00338 00340 template <typename T1, typename T2> 00341 struct diveq_right 00342 { 00343 inline T2& operator()(const T1& left, T2& right) const 00344 {return right /= left;} 00345 }; 00346 00348 template <typename T1, typename T2> 00349 struct diveq_left_0by0isC 00350 { 00351 inline diveq_left_0by0isC() : 00352 C(T1()), leftZero(T1()), rightZero(T2()) {} 00353 inline explicit diveq_left_0by0isC(const T1& value) : 00354 C(value), leftZero(T1()), rightZero(T2()) {} 00355 00356 inline T1& operator()(T1& left, const T2& right) const 00357 { 00358 if (right == rightZero) 00359 if (left == leftZero) 00360 { 00361 left = C; 00362 return left; 00363 } 00364 return left /= right; 00365 } 00366 00367 private: 00368 T1 C; 00369 T1 leftZero; 00370 T2 rightZero; 00371 }; 00372 00374 template <typename T1, typename T2> 00375 struct diveq_right_0by0isC 00376 { 00377 inline diveq_right_0by0isC() : 00378 C(T2()), leftZero(T1()), rightZero(T2()) {} 00379 inline explicit diveq_right_0by0isC(const T2& value) : 00380 C(value), leftZero(T1()), rightZero(T2()) {} 00381 00382 inline T2& operator()(const T1& left, T2& right) const 00383 { 00384 if (left == leftZero) 00385 if (right == rightZero) 00386 { 00387 right = C; 00388 return right; 00389 } 00390 return right /= left; 00391 } 00392 00393 private: 00394 T2 C; 00395 T1 leftZero; 00396 T2 rightZero; 00397 }; 00398 00400 template <typename T1, typename T2, typename T3=T1> 00401 struct scast_assign_left 00402 { 00403 inline T1& operator()(T1& left, const T2& right) const 00404 {return left = static_cast<T3>(right);} 00405 }; 00406 00408 template <typename T1, typename T2, typename T3=T2> 00409 struct scast_assign_right 00410 { 00411 inline T2& operator()(const T1& left, T2& right) const 00412 {return right = static_cast<T3>(left);} 00413 }; 00414 00416 template <typename T1, typename T2, typename T3=T1> 00417 struct scast_pluseq_left 00418 { 00419 inline T1& operator()(T1& left, const T2& right) const 00420 {return left += static_cast<T3>(right);} 00421 }; 00422 00424 template <typename T1, typename T2, typename T3=T2> 00425 struct scast_pluseq_right 00426 { 00427 inline T2& operator()(const T1& left, T2& right) const 00428 {return right += static_cast<T3>(left);} 00429 }; 00430 00432 template <typename T1, typename T2, typename T3=T1> 00433 struct scast_minuseq_left 00434 { 00435 inline T1& operator()(T1& left, const T2& right) const 00436 {return left -= static_cast<T3>(right);} 00437 }; 00438 00440 template <typename T1, typename T2, typename T3=T2> 00441 struct scast_minuseq_right 00442 { 00443 inline T2& operator()(const T1& left, T2& right) const 00444 {return right -= static_cast<T3>(left);} 00445 }; 00446 } 00447 00448 #endif // NPSTAT_SIMPLEFUNCTORS_HH_ 00449