Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:33:27

0001 #ifndef PhysicsTools_Utilities_FunctClone_h
0002 #define PhysicsTools_Utilities_FunctClone_h
0003 
0004 #include <vector>
0005 #include <algorithm>
0006 #include <memory>
0007 #include <cassert>
0008 
0009 namespace funct {
0010 
0011   template <typename F>
0012   struct Master {
0013     Master(const F& f) : f_(new F(f)), toBeUpdated_(1, true) {}
0014     double operator()() const { return get(0); }
0015     double operator()(double x) const { return get(0, x); }
0016     void add() const { toBeUpdated_.resize(size() + 1, true); }
0017     size_t size() const { return toBeUpdated_.size(); }
0018     double get(size_t i) const {
0019       if (toBeUpdated_[i])
0020         update();
0021       toBeUpdated_[i] = true;
0022       return value_;
0023     }
0024     double get(size_t i, double x) const {
0025       if (toBeUpdated_[i])
0026         update(x);
0027       toBeUpdated_[i] = true;
0028       return value_;
0029     }
0030 
0031   private:
0032     void reset() const { std::fill(toBeUpdated_.begin(), toBeUpdated_.end(), true); }
0033     void clear() const { std::fill(toBeUpdated_.begin(), toBeUpdated_.end(), false); }
0034     void update() const {
0035       clear();
0036       value_ = (*f_)();
0037     }
0038     void update(double x) const {
0039       clear();
0040       value_ = (*f_)(x);
0041     }
0042     const std::shared_ptr<F> f_;
0043     mutable double value_;
0044     mutable std::vector<bool> toBeUpdated_;
0045   };
0046 
0047   template <typename F>
0048   struct Slave {
0049     Slave(const Master<F>& master) : master_(master), id_(master.size()) {
0050       assert(id_ > 0);
0051       master_.add();
0052     }
0053     double operator()() const { return master_.get(id_); }
0054     double operator()(double x) const { return master_.get(id_, x); }
0055     void setId(size_t i) { id_ = i; }
0056 
0057   private:
0058     const Master<F>& master_;
0059     size_t id_;
0060   };
0061 
0062   template <typename F>
0063   Master<F> master(const F& f) {
0064     return Master<F>(f);
0065   }
0066 
0067   template <typename F>
0068   Slave<F> slave(const Master<F>& m) {
0069     return Slave<F>(m);
0070   }
0071 }  // namespace funct
0072 
0073 #endif