CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/JetMETCorrections/InterpolationTables/interface/SimpleFunctors.h

Go to the documentation of this file.
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