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