CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_1/src/PhysicsTools/Utilities/interface/FunctClone.h

Go to the documentation of this file.
00001 #ifndef PhysicsTools_Utilities_FunctClone_h
00002 #define PhysicsTools_Utilities_FunctClone_h
00003 #include <boost/shared_ptr.hpp>
00004 #include <vector>
00005 #include <algorithm>
00006 
00007 namespace funct {
00008 
00009   template<typename F>
00010   struct Master {
00011     Master(const F& f) : f_(new F(f)), toBeUpdated_(1, true) { 
00012     }
00013     double operator()() const {
00014       return get(0);
00015     }
00016     double operator()(double x) const {
00017       return get(0, x);
00018     }
00019     void add() const {
00020       toBeUpdated_.resize(size() + 1, true);
00021     }
00022     size_t size() const { return toBeUpdated_.size(); }
00023     double get(size_t i) const {
00024       if(toBeUpdated_[i]) update();
00025       toBeUpdated_[i] = true;
00026       return value_;
00027     }
00028     double get(size_t i, double x) const {
00029       if(toBeUpdated_[i]) update(x);
00030       toBeUpdated_[i] = true;
00031       return value_;
00032     }
00033   private:
00034     void reset() const {
00035       std::fill(toBeUpdated_.begin(), toBeUpdated_.end(), true);
00036     }
00037     void clear() const {
00038       std::fill(toBeUpdated_.begin(), toBeUpdated_.end(), false);
00039     }
00040     void update() const {
00041       clear();
00042       value_ = (*f_)();
00043     }
00044     void update(double x) const {
00045       clear();
00046       value_ = (*f_)(x);
00047     }
00048     const boost::shared_ptr<F> f_;
00049     mutable double value_;
00050     mutable std::vector<bool> toBeUpdated_;
00051   };
00052 
00053   template<typename F>
00054   struct Slave {
00055     Slave(const Master<F>& master) : master_(master), id_(master.size()) { 
00056       assert(id_ > 0);
00057       master_.add();
00058     }
00059     double operator()() const { return master_.get(id_); }
00060     double operator()(double x) const { return master_.get(id_, x); }
00061     void setId(size_t i) { id_ = i; }
00062   private:
00063     const Master<F> & master_;
00064     size_t id_;
00065   };
00066 
00067   template<typename F>
00068   Master<F> master(const F& f) { return Master<F>(f); }
00069 
00070   template<typename F>
00071   Slave<F> slave(const Master<F>& m) { return Slave<F>(m); }
00072 }
00073 
00074 #endif