diff --git a/include/hpp/statistics/bin.hh b/include/hpp/statistics/bin.hh index 3f76157497ddd2fe584042e7ac80e6d46ef34ba9..aa40be13fbc7c122a0f4cd7f3cfe4882d791c480 100644 --- a/include/hpp/statistics/bin.hh +++ b/include/hpp/statistics/bin.hh @@ -19,31 +19,169 @@ # define HPP_STATISTICS_HH # include <ostream> +# include <set> # include <hpp/statistics/config.hh> namespace hpp { namespace statistics { class Bin; - std::ostream& operator<< (std::ostream& os, const Bin& b); + template < typename T > + class Statistics; + } // namespace statistics +} // namespace hpp + +std::ostream& operator<< (std::ostream&, const hpp::statistics::Bin&); +template < typename T > +std::ostream& operator<< (std::ostream&, const hpp::statistics::Statistics <T>&); +namespace hpp { + namespace statistics { /// Abstract class representing a bin. /// /// Bins are use for statistics. They keep the number of /// of apparition of a given value. + /// Inherited class should also implement comparison and equality + /// operators. class HPP_STATISTICS_DLLAPI Bin { public: /// Return the number of element in the bin. - virtual size_t freq () const = 0; + size_t freq () const + { + return freq_; + } + + /// Add an occurence + /// \return The frequency after increment; + size_t operator ++() + { + return ++freq_; + } + + /// Add an occurence + /// \return The frequency before increment; + size_t operator ++(int) + { + return freq_++; + } + + /// Print the bin. + std::ostream& print (std::ostream& os) const; - private: /// Print the inner value of the bin. virtual std::ostream& printValue (std::ostream& os) const = 0; - friend std::ostream& operator<< (std::ostream&, const Bin&); + protected: + /// Constructor + Bin () : freq_ (0) {} + + private: + /// The number of occurence. + size_t freq_; + }; + + /// Template class to do statistics. + /// You should derivate class Bin and construct a class + /// Statistics < YourBin >. + template < typename T > + class HPP_STATISTICS_DLLAPI Statistics + { + public: + typedef typename std::set <T>::iterator iterator; + typedef typename std::set <T>::const_iterator const_iterator; + + /// Return the number of occurence of a Bin + virtual size_t freq (const T& bin) const; + + /// Return the total number of occurence. + unsigned int numberOfOccurence () const + { + return counts_; + } + + /// Put the results in a stream. + virtual std::ostream& print (std::ostream& os) const; + + protected: + /// Constructor + Statistics(); + + /// Increment a Bin + /// \note bin is inserted in the set of bins if it was not + /// already in the set. + virtual void increment (T& bin); + + /// Return an iterator pointing at the beginning of + /// the set of bins. + const_iterator begin() const + { + return bins_.begin(); + } + + /// Return an iterator pointing at the end of + /// the set of bins. + const_iterator end() const + { + return bins_.end(); + } + + private: + std::set < T > bins_; + + unsigned int counts_; }; } // namespace statistics } // namespace hpp +/// Implementation + +namespace hpp { + namespace statistics { + template < typename T > + void Statistics <T>::increment (T& b) + { + b++; + std::pair< iterator, bool > it = bins_.insert (b); + if (!it.second) { + // The bin exists already. We must copy and reinsert it. + b = *(it.first); + b++; + bins_.erase (it.first); + bins_.insert (b); + } + counts_++; + } + + template < typename T > + size_t Statistics <T>::freq (const T& b) const + { + typename std::set< T >::iterator it = bins_.find (b); + if (it == bins_.end ()) { + return 0; + } + return it->freq (); + } + + template < typename T > + Statistics <T>::Statistics () :bins_ (), counts_(0) + {} + + template < typename T > + std::ostream& Statistics<T>::print (std::ostream& os) const + { + const_iterator it; + for (it = begin(); it != end(); it++) + os << (*it) << std::endl; + return os; + } + } // namespace statistics +} // namespace hpp + + template < typename T > +std::ostream& operator<< (std::ostream& os, const hpp::statistics::Statistics <T>& ss) +{ + return ss.print (os); +} + #endif // HPP_STATISTICS_HH diff --git a/include/hpp/statistics/success-bin.hh b/include/hpp/statistics/success-bin.hh index 376eeea89e2c7f74e334deca60094f055899a88e..57fa4f8aa81854468769d449a8575eb28f0a61dc 100644 --- a/include/hpp/statistics/success-bin.hh +++ b/include/hpp/statistics/success-bin.hh @@ -31,9 +31,6 @@ namespace hpp { namespace statistics { - class SuccessStatistics; - std::ostream& operator<< (std::ostream&, const SuccessStatistics&); - /// This class count the number of success and failure. class HPP_STATISTICS_DLLAPI SuccessBin : public Bin { @@ -56,17 +53,6 @@ namespace hpp { /// If this bin represents 'failure', returns the reason as a string. const std::string& reasonString () const; - /// Add an occurence - /// \return The frequency after increment; - size_t operator ++(); - - /// Add an occurence - /// \return The frequency before increment; - size_t operator ++(int); - - /// \return The number of element in the bin. - size_t freq () const; - /// Check for equality. /// \return True if both are 'success' or if they are both 'failure' /// with the same Reason. @@ -106,9 +92,12 @@ namespace hpp { std::ostream& printValue (std::ostream& os) const; }; - class HPP_STATISTICS_DLLAPI SuccessStatistics + class HPP_STATISTICS_DLLAPI SuccessStatistics : + public Statistics < SuccessBin > { public: + typedef Statistics <SuccessBin> Parent; + /// Constructor SuccessStatistics (); @@ -129,21 +118,13 @@ namespace hpp { /// Count the number of a particular failure. unsigned int nbFailure (const SuccessBin::Reason& r) const; - - private: - std::set <SuccessBin> bins_; - - unsigned int counts_; - - /// Increment the bin. - void increment (SuccessBin& b); - - /// Put the results in a stream. - std::ostream& print (std::ostream& os) const; - - friend std::ostream& operator<< (std::ostream&, const SuccessStatistics&); }; } // namespace statistics } // namespace hpp +std::ostream& operator<< (std::ostream& os, const hpp::statistics::SuccessStatistics& ss) +{ + return ss.print (os); +} + #endif // HPP_STATISTICS_SUCCESSBIN_HH diff --git a/src/bin.cc b/src/bin.cc index e25a377c3c2821777a5897e1300d9d03ed676c2c..b983780bcb82e4b4ac5ede1400e64216676c8a95 100644 --- a/src/bin.cc +++ b/src/bin.cc @@ -18,9 +18,13 @@ namespace hpp { namespace statistics { - std::ostream& operator<< (std::ostream& os, const Bin& b) + std::ostream& Bin::print (std::ostream& os) const { - return b.printValue (os) << " seen " << b.freq() << " time(s)." << std::endl; + return printValue (os) << " seen " << freq() << " time(s)."; } } // namespace statistics } // namespace hpp +std::ostream& operator<< (std::ostream& os, const hpp::statistics::Bin& b) +{ + return b.print (os); +} diff --git a/src/success-bin.cc b/src/success-bin.cc index b812e24e3898cecdf5672022c3dd1e33dfe793d5..1e29da983f05e21ba560d598498a6ba232c05010 100644 --- a/src/success-bin.cc +++ b/src/success-bin.cc @@ -30,7 +30,7 @@ namespace hpp { } SuccessBin::SuccessBin (const bool success, const Reason& r) : - success_ (success), freq_ (0), reason_(r) + Bin(), success_ (success), reason_(r) { if (success_) reason_ = REASON_SUCCESS; @@ -41,21 +41,6 @@ namespace hpp { return success_; } - size_t SuccessBin::freq () const - { - return freq_; - } - - size_t SuccessBin::operator ++() - { - return ++freq_; - } - - size_t SuccessBin::operator ++(int) - { - return freq_++; - } - std::ostream& SuccessBin::printValue (std::ostream& os) const { os << "Event "; @@ -79,7 +64,7 @@ namespace hpp { return reason_.id < other.reason ().id; } - SuccessStatistics::SuccessStatistics () : bins_(), counts_(0) + SuccessStatistics::SuccessStatistics () {} void SuccessStatistics::addFailure (const SuccessBin::Reason& r) @@ -94,52 +79,19 @@ namespace hpp { increment (b); } - void SuccessStatistics::increment (SuccessBin& b) - { - b++; - std::pair<std::set<SuccessBin>::iterator, bool> it = bins_.insert (b); - if (!it.second) { - // The bin exists already. We must copy and reinsert it. - SuccessBin bin = *(it.first); - bin ++; - bins_.erase (b); - bins_.insert (bin); - } - counts_++; - } - unsigned int SuccessStatistics::nbSuccess () const { - std::set<SuccessBin>::iterator it = bins_.find (SuccessBin(true)); - if (it != bins_.end()) - return it->freq(); - return 0; + return freq (SuccessBin(true)); } unsigned int SuccessStatistics::nbFailure () const { - return counts_ - nbSuccess(); + return numberOfOccurence() - nbSuccess(); } unsigned int SuccessStatistics::nbFailure (const SuccessBin::Reason& r) const { - std::set<SuccessBin>::iterator it = bins_.find (SuccessBin(false, r)); - if (it != bins_.end()) - return it->freq(); - return 0; - } - - std::ostream& SuccessStatistics::print (std::ostream& os) const - { - std::set <SuccessBin>::const_iterator it; - for (it = bins_.begin(); it != bins_.end(); it++) - os << (*it); - return os; - } - - std::ostream& operator<< (std::ostream& os, const SuccessStatistics& ss) - { - return ss.print (os); + return freq (SuccessBin (false, r)); } } // namespace statistics } // namespace hpp diff --git a/tests/test-successstatistics.cc b/tests/test-successstatistics.cc index bd3eeacf19580091bbfd70e0247e002b706cb8fe..f9dfe2ff1d43486fbf21235dde09d533c6e9d223 100644 --- a/tests/test-successstatistics.cc +++ b/tests/test-successstatistics.cc @@ -49,7 +49,7 @@ int main () if ( ss.nbSuccess () != counter[0] || ss.nbFailure (SuccessBin::REASON_UNKNOWN) != counter[1] || ss.nbFailure (REASON_TEST) != counter[2]) { - std::cout << ss; + std::cout << ss << std::endl; std::cout << "Real frequencies are: ( " << counter[0] << ", " << counter[1] << ", " << counter [2] << ")" << std::endl; return EXIT_FAILURE;