diff --git a/src/base/statistics.cc b/src/base/statistics.cc index 032cbf689..c77816f23 100644 --- a/src/base/statistics.cc +++ b/src/base/statistics.cc @@ -158,7 +158,7 @@ Info::less(Info *stat1, Info *stat2) bool Info::baseCheck() const { - if (!(flags & init)) { + if (!(flags & Stats::init)) { #ifdef DEBUG cprintf("this is stat number %d\n", id); #endif @@ -175,55 +175,6 @@ Info::baseCheck() const } -void -FormulaBase::result(VResult &vec) const -{ - if (root) - vec = root->result(); -} - -Result -FormulaBase::total() const -{ - return root ? root->total() : 0.0; -} - -size_type -FormulaBase::size() const -{ - if (!root) - return 0; - else - return root->size(); -} - -void -FormulaBase::reset() -{ -} - -bool -FormulaBase::zero() const -{ - VResult vec; - result(vec); - for (off_t i = 0; i < vec.size(); ++i) - if (vec[i] != 0.0) - return false; - return true; -} - -void -FormulaBase::update(Info *) -{ -} - -string -FormulaBase::str() const -{ - return root ? root->str() : ""; -} - Formula::Formula() { setInit(); @@ -255,6 +206,55 @@ Formula::operator+=(Temp r) return *this; } +void +Formula::result(VResult &vec) const +{ + if (root) + vec = root->result(); +} + +Result +Formula::total() const +{ + return root ? root->total() : 0.0; +} + +size_type +Formula::size() const +{ + if (!root) + return 0; + else + return root->size(); +} + +void +Formula::reset() +{ +} + +bool +Formula::zero() const +{ + VResult vec; + result(vec); + for (off_t i = 0; i < vec.size(); ++i) + if (vec[i] != 0.0) + return false; + return true; +} + +void +Formula::update() +{ +} + +string +Formula::str() const +{ + return root ? root->str() : ""; +} + void check() { diff --git a/src/base/statistics.hh b/src/base/statistics.hh index 7b69184e9..ef22ebe24 100644 --- a/src/base/statistics.hh +++ b/src/base/statistics.hh @@ -114,6 +114,14 @@ class Info Info(); virtual ~Info(); + /** + * Check that this stat has been set up properly and is ready for + * use + * @return true for success + */ + virtual bool check() const = 0; + bool baseCheck() const; + /** * Reset the stat to the default state. */ @@ -125,14 +133,6 @@ class Info */ virtual bool zero() const = 0; - /** - * Check that this stat has been set up properly and is ready for - * use - * @return true for success - */ - virtual bool check() const = 0; - bool baseCheck() const; - /** * Visitor entry for outputing statistics data */ @@ -187,8 +187,8 @@ class VectorInfoBase : public Info { public: /** Names and descriptions of subfields. */ - mutable std::vector subnames; - mutable std::vector subdescs; + std::vector subnames; + std::vector subdescs; public: virtual size_type size() const = 0; @@ -242,7 +242,7 @@ class VectorInfo : public InfoWrap visit(Visit &visitor) { this->update(); - this->s.update(this); + this->s.update(); visitor.visit(*this); } }; @@ -275,7 +275,7 @@ class DistInfo : public InfoWrap void visit(Visit &visitor) { - this->s.update(this); + this->s.update(); visitor.visit(*this); } }; @@ -285,9 +285,9 @@ class VectorDistInfoBase : public Info public: std::vector data; - /** Names and descriptions of subfields. */ - mutable std::vector subnames; - mutable std::vector subdescs; + /** Names and descriptions of subfields. */ + std::vector subnames; + std::vector subdescs; protected: /** Local storage for the entry values, used for printing. */ @@ -320,7 +320,7 @@ class VectorDistInfo : public InfoWrap visit(Visit &visitor) { this->update(); - this->s.update(this); + this->s.update(); visitor.visit(*this); } }; @@ -333,10 +333,11 @@ class Vector2dInfoBase : public Info std::vector subdescs; std::vector y_subnames; + size_type x; + size_type y; + /** Local storage for the entry values, used for printing. */ mutable VCounter cvec; - mutable size_type x; - mutable size_type y; public: void @@ -357,7 +358,7 @@ class Vector2dInfo : public InfoWrap visit(Visit &visitor) { this->update(); - this->s.update(this); + this->s.update(); visitor.visit(*this); } }; @@ -397,29 +398,27 @@ class InfoAccess bool check() const { return true; } }; -template class Info> -class DataWrap : public Base +template class InfoType> +class DataWrap : public InfoAccess { public: - typedef Derived DerivedType; - typedef Base BaseType; - typedef Info InfoType; + typedef InfoType Info; protected: - Derived &self() { return *reinterpret_cast(this); } + Derived &self() { return *static_cast(this); } protected: - InfoType * + Info * info() { - return safe_cast(InfoAccess::info()); + return safe_cast(InfoAccess::info()); } public: - const InfoType * + const Info * info() const { - return safe_cast(InfoAccess::info()); + return safe_cast(InfoAccess::info()); } protected: @@ -436,7 +435,7 @@ class DataWrap : public Base public: DataWrap() { - this->setInfo(new InfoType(*this)); + this->setInfo(new Info(self())); } /** @@ -447,11 +446,12 @@ class DataWrap : public Base Derived & name(const std::string &_name) { - InfoType *info = this->info(); + Info *info = this->info(); info->name = _name; info->flags |= print; return this->self(); } + const std::string &name() const { return this->info()->name; } /** * Set the description and marks this stat to print at the end of @@ -505,15 +505,12 @@ class DataWrap : public Base } }; -template class Info> -class DataWrapVec : public DataWrap +template class InfoType> +class DataWrapVec : public DataWrap { public: - typedef Derived DerivedType; - typedef Base BaseType; - typedef Info InfoType; + typedef InfoType Info; - public: // The following functions are specific to vectors. If you use them // in a non vector context, you will get a nice compiler error! @@ -527,13 +524,20 @@ class DataWrapVec : public DataWrap Derived & subname(off_type index, const std::string &name) { - std::vector &subn = this->info()->subnames; + Derived &self = this->self(); + Info *info = this->info(); + + std::vector &subn = info->subnames; if (subn.size() <= index) subn.resize(index + 1); subn[index] = name; - return this->self(); + return self; } + // The following functions are specific to 2d vectors. If you use + // them in a non vector context, you will get a nice compiler + // error because info doesn't have the right variables. + /** * Set the subfield description for the given index and marks this stat to * print at the end of simulation. @@ -544,7 +548,9 @@ class DataWrapVec : public DataWrap Derived & subdesc(off_type index, const std::string &desc) { - std::vector &subd = this->info()->subdescs; + Info *info = this->info(); + + std::vector &subd = info->subdescs; if (subd.size() <= index) subd.resize(index + 1); subd[index] = desc; @@ -552,17 +558,24 @@ class DataWrapVec : public DataWrap return this->self(); } + void + reset() + { + Derived &self = this->self(); + Info *info = this->info(); + + size_t size = self.size(); + for (off_type i = 0; i < size; ++i) + self.data(i)->reset(info); + } }; -template class Info> -class DataWrapVec2d : public DataWrapVec +template class InfoType> +class DataWrapVec2d : public DataWrapVec { public: - typedef Derived DerivedType; - typedef Base BaseType; - typedef Info InfoType; + typedef InfoType Info; - public: /** * @warning This makes the assumption that if you're gonna subnames a 2d * vector, you're subnaming across all y @@ -570,21 +583,25 @@ class DataWrapVec2d : public DataWrapVec Derived & ysubnames(const char **names) { - InfoType *info = this->info(); - info->y_subnames.resize(this->y); - for (off_type i = 0; i < this->y; ++i) + Derived &self = this->self(); + Info *info = this->info(); + + info->y_subnames.resize(self.y); + for (off_type i = 0; i < self.y; ++i) info->y_subnames[i] = names[i]; - return this->self(); + return self; } Derived & ysubname(off_type index, const std::string subname) { - InfoType *info = this->info(); - assert(index < this->y); - info->y_subnames.resize(this->y); + Derived &self = this->self(); + Info *info = this->info(); + + assert(index < self.y); + info->y_subnames.resize(self.y); info->y_subnames[index] = subname.c_str(); - return this->self(); + return self; } }; @@ -722,6 +739,11 @@ class AvgStor return (Result)(total + current) / (Result)(curTick + 1); } + /** + * @return true if zero value + */ + bool zero() const { return total == 0.0; } + /** * Reset stat value to default */ @@ -732,18 +754,14 @@ class AvgStor last = curTick; } - /** - * @return true if zero value - */ - bool zero() const { return total == 0.0; } }; /** * Implementation of a scalar stat. The type of stat is determined by the * Storage template. */ -template -class ScalarBase : public InfoAccess +template +class ScalarBase : public DataWrap { public: typedef Stor Storage; @@ -780,8 +798,8 @@ class ScalarBase : public InfoAccess void doInit() { - new (storage) Storage(info()); - setInit(); + new (storage) Storage(this->info()); + this->setInit(); } public: @@ -792,7 +810,10 @@ class ScalarBase : public InfoAccess Counter value() const { return data()->value(); } public: - ScalarBase() { } + ScalarBase() + { + this->doInit(); + } public: // Common operators for stats @@ -845,7 +866,7 @@ class ScalarBase : public InfoAccess /** * Reset stat value to default */ - void reset() { data()->reset(info()); } + void reset() { data()->reset(this->info()); } Counter value() { return data()->value(); } @@ -893,7 +914,8 @@ class FunctorProxy : public ProxyInfo Result total() const { return (*functor)(); } }; -class ValueBase : public InfoAccess +template +class ValueBase : public DataWrap { private: ProxyInfo *proxy; @@ -903,19 +925,21 @@ class ValueBase : public InfoAccess ~ValueBase() { if (proxy) delete proxy; } template - void + Derived & scalar(T &value) { proxy = new ValueProxy(value); - setInit(); + this->setInit(); + return this->self(); } template - void + Derived & functor(T &func) { proxy = new FunctorProxy(func); - setInit(); + this->setInit(); + return this->self(); } Counter value() { return proxy->value(); } @@ -944,7 +968,7 @@ class ScalarProxy { private: /** Pointer to the parent Vector. */ - Stat *stat; + Stat &stat; /** The index to access in the parent VectorBase. */ off_type index; @@ -967,10 +991,9 @@ class ScalarProxy * Create and initialize this proxy, do not register it with the database. * @param i The index to access. */ - ScalarProxy(Stat *s, off_type i) + ScalarProxy(Stat &s, off_type i) : stat(s), index(i) { - assert(stat); } /** @@ -1000,12 +1023,12 @@ class ScalarProxy * Increment the stat by 1. This calls the associated storage object inc * function. */ - void operator++() { stat->data(index)->inc(1); } + void operator++() { stat.data(index)->inc(1); } /** * Decrement the stat by 1. This calls the associated storage object dec * function. */ - void operator--() { stat->data(index)->dec(1); } + void operator--() { stat.data(index)->dec(1); } /** Increment the stat by 1. */ void operator++(int) { ++*this; } @@ -1021,7 +1044,7 @@ class ScalarProxy void operator=(const U &v) { - stat->data(index)->set(v); + stat.data(index)->set(v); } /** @@ -1033,7 +1056,7 @@ class ScalarProxy void operator+=(const U &v) { - stat->data(index)->inc(v); + stat.data(index)->inc(v); } /** @@ -1045,7 +1068,7 @@ class ScalarProxy void operator-=(const U &v) { - stat->data(index)->dec(v); + stat.data(index)->dec(v); } /** @@ -1058,7 +1081,7 @@ class ScalarProxy std::string str() const { - return csprintf("%s[%d]", stat->info()->name, index); + return csprintf("%s[%d]", stat.info()->name, index); } }; @@ -1066,17 +1089,17 @@ class ScalarProxy * Implementation of a vector of stats. The type of stat is determined by the * Storage class. @sa ScalarBase */ -template -class VectorBase : public InfoAccess +template +class VectorBase : public DataWrapVec { public: typedef Stor Storage; typedef typename Stor::Params Params; /** Proxy type */ - typedef ScalarProxy > Proxy; - - friend class ScalarProxy >; + typedef ScalarProxy Proxy; + friend class ScalarProxy; + friend class DataWrapVec; protected: /** The storage of this stat. */ @@ -1109,9 +1132,9 @@ class VectorBase : public InfoAccess storage = reinterpret_cast(ptr); for (off_type i = 0; i < _size; ++i) - new (&storage[i]) Storage(info()); + new (&storage[i]) Storage(this->info()); - setInit(); + this->setInit(); } public: @@ -1168,13 +1191,6 @@ class VectorBase : public InfoAccess return storage != NULL; } - void - reset() - { - for (off_type i = 0; i < size(); ++i) - data(i)->reset(info()); - } - public: VectorBase() : storage(NULL) @@ -1190,6 +1206,19 @@ class VectorBase : public InfoAccess delete [] reinterpret_cast(storage); } + /** + * Set this vector to have the given size. + * @param size The new size. + * @return A reference to this stat. + */ + Derived & + init(size_type size) + { + Derived &self = this->self(); + self.doInit(size); + return self; + } + /** * Return a reference (ScalarProxy) to the stat at the given index. * @param index The vector index to access. @@ -1199,17 +1228,17 @@ class VectorBase : public InfoAccess operator[](off_type index) { assert (index >= 0 && index < size()); - return Proxy(this, index); + return Proxy(this->self(), index); } - void update(Info *data) {} + void update() {} }; template class VectorProxy { private: - Stat *stat; + Stat &stat; off_type offset; size_type len; @@ -1220,14 +1249,14 @@ class VectorProxy data(off_type index) { assert(index < len); - return stat->data(offset + index); + return stat.data(offset + index); } const typename Stat::Storage * data(off_type index) const { assert(index < len); - return const_cast(stat)->data(offset + index); + return stat.data(offset + index); } public: @@ -1252,7 +1281,7 @@ class VectorProxy } public: - VectorProxy(Stat *s, off_type o, size_type l) + VectorProxy(Stat &s, off_type o, size_type l) : stat(s), offset(o), len(l) { } @@ -1281,15 +1310,18 @@ class VectorProxy size_type size() const { return len; } }; -template -class Vector2dBase : public InfoAccess +template +class Vector2dBase : public DataWrapVec2d { public: + typedef Vector2dInfo Info; typedef Stor Storage; typedef typename Stor::Params Params; - typedef VectorProxy > Proxy; - friend class ScalarProxy >; - friend class VectorProxy >; + typedef VectorProxy Proxy; + friend class ScalarProxy; + friend class VectorProxy; + friend class DataWrapVec; + friend class DataWrapVec2d; protected: size_type x; @@ -1301,29 +1333,6 @@ class Vector2dBase : public InfoAccess Storage *data(off_type index) { return &storage[index]; } const Storage *data(off_type index) const { return &storage[index]; } - void - doInit(size_type _x, size_type _y) - { - assert(_x > 0 && _y > 0 && "sizes must be positive!"); - assert(!storage && "already initialized"); - - Vector2dInfoBase *info = safe_cast(this->info()); - - x = _x; - y = _y; - info->x = _x; - info->y = _y; - _size = x * y; - - char *ptr = new char[_size * sizeof(Storage)]; - storage = reinterpret_cast(ptr); - - for (off_type i = 0; i < _size; ++i) - new (&storage[i]) Storage(info); - - setInit(); - } - public: Vector2dBase() : storage(NULL) @@ -1340,12 +1349,39 @@ class Vector2dBase : public InfoAccess } void - update(Vector2dInfoBase *newinfo) + update() { + Info *info = this->info(); size_type size = this->size(); - newinfo->cvec.resize(size); + info->cvec.resize(size); for (off_type i = 0; i < size; ++i) - newinfo->cvec[i] = data(i)->value(); + info->cvec[i] = data(i)->value(); + } + + Derived & + init(size_type _x, size_type _y) + { + assert(_x > 0 && _y > 0 && "sizes must be positive!"); + assert(!storage && "already initialized"); + + Derived &self = this->self(); + Info *info = this->info(); + + x = _x; + y = _y; + info->x = _x; + info->y = _y; + _size = x * y; + + char *ptr = new char[_size * sizeof(Storage)]; + storage = reinterpret_cast(ptr); + + for (off_type i = 0; i < _size; ++i) + new (&storage[i]) Storage(info); + + this->setInit(); + + return self; } std::string ysubname(off_type i) const { return (*this->y_subnames)[i]; } @@ -1355,7 +1391,7 @@ class Vector2dBase : public InfoAccess { off_type offset = index * y; assert (index >= 0 && offset + index < size()); - return Proxy(this, offset, y); + return Proxy(this->self(), offset, y); } @@ -1383,8 +1419,10 @@ class Vector2dBase : public InfoAccess void reset() { - for (off_type i = 0; i < size(); ++i) - data(i)->reset(info()); + Info *info = this->info(); + size_type size = this->size(); + for (off_type i = 0; i < size; ++i) + data(i)->reset(info); } bool @@ -1699,10 +1737,11 @@ class AvgFancy * Implementation of a distribution stat. The type of distribution is * determined by the Storage template. @sa ScalarBase */ -template -class DistBase : public InfoAccess +template +class DistBase : public DataWrap { public: + typedef DistInfo Info; typedef Stor Storage; typedef typename Stor::Params Params; @@ -1734,8 +1773,8 @@ class DistBase : public InfoAccess void doInit() { - new (storage) Storage(info()); - setInit(); + new (storage) Storage(this->info()); + this->setInit(); } public: @@ -1762,9 +1801,10 @@ class DistBase : public InfoAccess bool zero() const { return data()->zero(); } void - update(DistInfoBase *base) + update() { - data()->update(info(), base->data); + Info *info = this->info(); + data()->update(info, info->data); } /** @@ -1773,21 +1813,23 @@ class DistBase : public InfoAccess void reset() { - data()->reset(info()); + data()->reset(this->info()); } }; template class DistProxy; -template -class VectorDistBase : public InfoAccess +template +class VectorDistBase : public DataWrapVec { public: + typedef VectorDistInfo Info; typedef Stor Storage; typedef typename Stor::Params Params; - typedef DistProxy > Proxy; - friend class DistProxy >; + typedef DistProxy Proxy; + friend class DistProxy; + friend class DataWrapVec; protected: Storage *storage; @@ -1816,10 +1858,11 @@ class VectorDistBase : public InfoAccess char *ptr = new char[_size * sizeof(Storage)]; storage = reinterpret_cast(ptr); + Info *info = this->info(); for (off_type i = 0; i < _size; ++i) - new (&storage[i]) Storage(info()); + new (&storage[i]) Storage(info); - setInit(); + this->setInit(); } public: @@ -1857,16 +1900,6 @@ class VectorDistBase : public InfoAccess #endif } - /** - * Reset stat value to default - */ - void - reset() - { - for (off_type i = 0; i < size(); ++i) - data(i)->reset(info()); - } - bool check() const { @@ -1874,12 +1907,15 @@ class VectorDistBase : public InfoAccess } void - update(VectorDistInfoBase *base) + update() { - size_type size = this->size(); - base->data.resize(size); + Derived &self = this->self(); + Info *info = this->info(); + + size_type size = self.size(); + info.data.resize(size); for (off_type i = 0; i < size; ++i) { - data(i)->update(info(), base->data[i]); + data(i)->update(info, info.data[i]); } } }; @@ -1938,12 +1974,13 @@ class DistProxy void reset() { } }; -template -inline typename VectorDistBase::Proxy -VectorDistBase::operator[](off_type index) +template +inline typename VectorDistBase::Proxy +VectorDistBase::operator[](off_type index) { assert (index >= 0 && index < size()); - return typename VectorDistBase::Proxy(this, index); + typedef typename VectorDistBase::Proxy Proxy; + return Proxy(this, index); } #if 0 @@ -2350,148 +2387,56 @@ class SumNode : public Node * This is a simple scalar statistic, like a counter. * @sa Stat, ScalarBase, StatStor */ -class Scalar : public DataWrap, ScalarInfo> +class Scalar : public ScalarBase { public: - /** The base implementation. */ - typedef ScalarBase Base; - - Scalar() - { - this->doInit(); - } - - /** - * Sets the stat equal to the given value. Calls the base implementation - * of operator= - * @param v The new value. - */ - template - void operator=(const U &v) { Base::operator=(v); } -}; - -class Value : public DataWrap -{ - public: - /** The base implementation. */ - typedef ValueBase Base; - - template - Value & - scalar(T &value) - { - Base::scalar(value); - return *this; - } - - template - Value & - functor(T &func) - { - Base::functor(func); - return *this; - } + using ScalarBase::operator=; }; /** * A stat that calculates the per tick average of a value. * @sa Stat, ScalarBase, AvgStor */ -class Average : public DataWrap, ScalarInfo> +class Average : public ScalarBase { public: - /** The base implementation. */ - typedef ScalarBase Base; + using ScalarBase::operator=; +}; - Average() - { - this->doInit(); - } - - /** - * Sets the stat equal to the given value. Calls the base implementation - * of operator= - * @param v The new value. - */ - template - void - operator=(const U &v) - { - Base::operator=(v); - } +class Value : public ValueBase +{ }; /** * A vector of scalar stats. * @sa Stat, VectorBase, StatStor */ -class Vector : public DataWrapVec, VectorInfo> +class Vector : public VectorBase { - public: - /** The base implementation. */ - typedef ScalarBase Base; - - /** - * Set this vector to have the given size. - * @param size The new size. - * @return A reference to this stat. - */ - Vector & - init(size_type size) - { - this->doInit(size); - return *this; - } }; /** * A vector of Average stats. * @sa Stat, VectorBase, AvgStor */ -class AverageVector - : public DataWrapVec, VectorInfo> +class AverageVector : public VectorBase { - public: - /** - * Set this vector to have the given size. - * @param size The new size. - * @return A reference to this stat. - */ - AverageVector & - init(size_type size) - { - this->doInit(size); - return *this; - } }; /** * A 2-Dimensional vecto of scalar stats. * @sa Stat, Vector2dBase, StatStor */ -class Vector2d - : public DataWrapVec2d, Vector2dInfo> +class Vector2d : public Vector2dBase { - public: - Vector2d & - init(size_type x, size_type y) - { - this->doInit(x, y); - return *this; - } }; /** * A simple distribution stat. * @sa Stat, DistBase, DistStor */ -class Distribution - : public DataWrap, DistInfo> +class Distribution : public DistBase { - public: - /** Base implementation. */ - typedef DistBase Base; - public: /** * Set the parameters of this distribution. @sa DistStor::Params @@ -2510,7 +2455,7 @@ class Distribution params->buckets = (size_type)rint((max - min) / bkt + 1.0); this->setParams(params); this->doInit(); - return *this; + return this->self(); } }; @@ -2518,13 +2463,8 @@ class Distribution * Calculates the mean and variance of all the samples. * @sa Stat, DistBase, FancyStor */ -class StandardDeviation - : public DataWrap, DistInfo> +class StandardDeviation : public DistBase { - public: - /** The base implementation */ - typedef DistBase Base; - public: /** * Construct and initialize this distribution. @@ -2539,13 +2479,8 @@ class StandardDeviation * Calculates the per tick mean and variance of the samples. * @sa Stat, DistBase, AvgFancy */ -class AverageDeviation - : public DataWrap, DistInfo> +class AverageDeviation : public DistBase { - public: - /** The base implementation */ - typedef DistBase Base; - public: /** * Construct and initialize this distribution. @@ -2560,15 +2495,8 @@ class AverageDeviation * A vector of distributions. * @sa Stat, VectorDistBase, DistStor */ -class VectorDistribution - : public DataWrapVec, - VectorDistInfo> +class VectorDistribution : public VectorDistBase { - public: - /** The base implementation */ - typedef VectorDistBase Base; - public: /** * Initialize storage and parameters for this distribution. @@ -2588,7 +2516,7 @@ class VectorDistribution params->buckets = rint((max - min) / bkt + 1.0); this->setParams(params); this->doInit(size); - return *this; + return this->self(); } }; @@ -2597,14 +2525,8 @@ class VectorDistribution * @sa Stat, VectorDistBase, FancyStor */ class VectorStandardDeviation - : public DataWrapVec, - VectorDistInfo> + : public VectorDistBase { - public: - /** The base implementation */ - typedef VectorDistBase Base; - public: /** * Initialize storage for this distribution. @@ -2615,7 +2537,7 @@ class VectorStandardDeviation init(size_type size) { this->doInit(size); - return *this; + return this->self(); } }; @@ -2624,14 +2546,8 @@ class VectorStandardDeviation * @sa Stat, VectorDistBase, AvgFancy */ class VectorAverageDeviation - : public DataWrapVec, - VectorDistInfo> + : public VectorDistBase { - public: - /** The base implementation */ - typedef VectorDistBase Base; - public: /** * Initialize storage for this distribution. @@ -2642,67 +2558,10 @@ class VectorAverageDeviation init(size_type size) { this->doInit(size); - return *this; + return this->self(); } }; -/** - * A formula for statistics that is calculated when printed. A formula is - * stored as a tree of Nodes that represent the equation to calculate. - * @sa Stat, ScalarStat, VectorStat, Node, Temp - */ -class FormulaBase : public InfoAccess -{ - protected: - /** The root of the tree which represents the Formula */ - NodePtr root; - friend class Temp; - - public: - /** - * Return the result of the Fomula in a vector. If there were no Vector - * components to the Formula, then the vector is size 1. If there were, - * like x/y with x being a vector of size 3, then the result returned will - * be x[0]/y, x[1]/y, x[2]/y, respectively. - * @return The result vector. - */ - void result(VResult &vec) const; - - /** - * Return the total Formula result. If there is a Vector - * component to this Formula, then this is the result of the - * Formula if the formula is applied after summing all the - * components of the Vector. For example, if Formula is x/y where - * x is size 3, then total() will return (x[1]+x[2]+x[3])/y. If - * there is no Vector component, total() returns the same value as - * the first entry in the VResult val() returns. - * @return The total of the result vector. - */ - Result total() const; - - /** - * Return the number of elements in the tree. - */ - size_type size() const; - - /** - * Formulas don't need to be reset - */ - void reset(); - - /** - * - */ - bool zero() const; - - /** - * - */ - void update(Info *); - - std::string str() const; -}; - class FormulaInfoBase : public VectorInfoBase { public: @@ -2734,7 +2593,7 @@ class FormulaInfo : public InfoWrap visit(Visit &visitor) { this->update(); - this->s.update(this); + this->s.update(); visitor.visit(*this); } @@ -2742,8 +2601,18 @@ class FormulaInfo : public InfoWrap }; class Temp; -class Formula : public DataWrapVec +/** + * A formula for statistics that is calculated when printed. A formula is + * stored as a tree of Nodes that represent the equation to calculate. + * @sa Stat, ScalarStat, VectorStat, Node, Temp + */ +class Formula : public DataWrapVec { + protected: + /** The root of the tree which represents the Formula */ + NodePtr root; + friend class Temp; + public: /** * Create and initialize thie formula, and register it with the database. @@ -2770,6 +2639,50 @@ class Formula : public DataWrapVec * @return a reference to this formula. */ const Formula &operator+=(Temp r); + /** + * Return the result of the Fomula in a vector. If there were no Vector + * components to the Formula, then the vector is size 1. If there were, + * like x/y with x being a vector of size 3, then the result returned will + * be x[0]/y, x[1]/y, x[2]/y, respectively. + * @return The result vector. + */ + void result(VResult &vec) const; + + /** + * Return the total Formula result. If there is a Vector + * component to this Formula, then this is the result of the + * Formula if the formula is applied after summing all the + * components of the Vector. For example, if Formula is x/y where + * x is size 3, then total() will return (x[1]+x[2]+x[3])/y. If + * there is no Vector component, total() returns the same value as + * the first entry in the VResult val() returns. + * @return The total of the result vector. + */ + Result total() const; + + /** + * Return the number of elements in the tree. + */ + size_type size() const; + + void prepare() { } + + /** + * Formulas don't need to be reset + */ + void reset(); + + /** + * + */ + bool zero() const; + + /** + * + */ + void update(); + + std::string str() const; }; class FormulaNode : public Node