File indexing completed on 2024-04-06 12:24:18
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 }
0072
0073 #endif