#pragma once #include "comdefs.h" using michlib::real; class BaseData { protected: static constexpr real fillval = 1.0e10; std::vector data; BaseData() = default; BaseData(size_t n): data(n) {} public: const real& V(size_t i) const { return data[i]; } real& V(size_t i) { return data[i]; } const real& operator()(size_t i) const { return data[i]; } real& operator()(size_t i) { return data[i]; } size_t N() const { return data.size(); } static real Fillval() { return fillval; } explicit operator bool() const { return N() != 0; } }; template class Averager: public Data { std::vector count; public: void Add(const Data& d) { if(!d) return; if(!*this) { *static_cast(this) = d; count.resize(Data::N()); for(size_t i = 0; i < Data::N(); i++) count[i] = (Data::V(i) == Data::Fillval()) ? 0 : 1; return; } if(Data::N() != d.N()) return; for(size_t i = 0; i < Data::N(); i++) if(d(i) != Data::Fillval()) { if(Data::V(i) == Data::Fillval()) { Data::V(i) = d(i); count[i] = 1; } else { Data::V(i) += d(i); count[i]++; } } } Averager& Div() { if(!*this) return *this; for(size_t i = 0; i < Data::N(); i++) if(count[i] != 0) Data::V(i) /= count[i]; return *this; } };