CVC3

statistics.h

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file statistics.h
00004  * \brief Description: Counters and flags for collecting run-time statistics.
00005  * 
00006  * Author: Sergey Berezin
00007  * 
00008  * Created: Thu Jun  5 17:38:13 2003
00009  *
00010  * <hr>
00011  *
00012  * License to use, copy, modify, sell and/or distribute this software
00013  * and its documentation for any purpose is hereby granted without
00014  * royalty, subject to the terms and conditions defined in the \ref
00015  * LICENSE file provided with this distribution.
00016  * 
00017  * <hr>
00018  * 
00019  */
00020 /*****************************************************************************/
00021 
00022 #ifndef _cvc3__statistics_h
00023 #define _cvc3__statistics_h
00024 
00025 #include <string>
00026 #include <iostream>
00027 #include <sstream>
00028 #include <map>
00029 
00030 namespace CVC3 {
00031 
00032   class Statistics; // The main class, defined below
00033 
00034   // First, wrapper classes for flags and counters.  Later, we
00035   // overload some operators like '=', '++', etc. for those classes.
00036 
00037   // Boolean flag (can only be true or false)
00038   class StatFlag {
00039   private:
00040     bool* d_flag; // We don't own the pointer
00041   public:
00042     // Constructor: takes the pointer to the actual flag, normally
00043     // stored in class Statistics below.
00044     StatFlag(bool& flag) : d_flag(&flag) { }
00045     // Destructor
00046     ~StatFlag() { }
00047     // Auto-cast to boolean
00048     operator bool() { return *d_flag; }
00049 
00050     // Setting and resetting by ++ and --
00051     // Prefix versions:
00052     bool operator--() { *d_flag = false; return false; }
00053     bool operator++() { *d_flag = true; return true; }
00054     // Postfix versions:
00055     bool operator--(int) { bool x=*d_flag; *d_flag=false; return x; }
00056     bool operator++(int) { bool x=*d_flag; *d_flag=true; return x; }
00057     // Can be assigned only a boolean value
00058     StatFlag& operator=(bool x) { *d_flag=(x!=false); return *this; }
00059     // Comparisons
00060     friend bool operator==(const StatFlag& f1, const StatFlag& f2);
00061     friend bool operator!=(const StatFlag& f1, const StatFlag& f2);
00062     // Printing
00063     friend std::ostream& operator<<(std::ostream& os, const StatFlag& f);
00064   }; // end of class StatFlag
00065 
00066   inline bool operator==(const StatFlag& f1, const StatFlag& f2) {
00067     return (*f1.d_flag) == (*f2.d_flag);
00068   }
00069   inline bool operator!=(const StatFlag& f1, const StatFlag& f2) {
00070     return (*f1.d_flag) != (*f2.d_flag);
00071   }
00072   inline std::ostream& operator<<(std::ostream& os, const StatFlag& f) {
00073     if(*f.d_flag) return(os << "true");
00074     else return(os << "false");
00075   }
00076 
00077   // Integer counter.  Intended use is to count events (e.g. number of
00078   // function calls), but can be used to store any integer value
00079   // (e.g. size of some data structure)
00080   class StatCounter {
00081   private:
00082     int* d_counter; // We don't own the pointer
00083   public:
00084     // Constructor: takes the pointer to the actual counter, normally
00085     // stored in class Statistics below.
00086     StatCounter(int& c) : d_counter(&c) { }
00087     // Destructor
00088     ~StatCounter() { }
00089     // Auto-cast to int.  In particular, arithmetic comparisons like
00090     // <, >, <=, >= will work because of this.
00091 
00092     operator int() { return *d_counter; }
00093 
00094     // Auto-increment operators
00095     // Prefix versions:
00096     int operator--() { return --(*d_counter); }
00097     int operator++() { return ++(*d_counter); }
00098     // Postfix versions:
00099     int operator--(int) { return (*d_counter)--; }
00100     int operator++(int) { return (*d_counter)++; }
00101     // Can be assigned an integer or the value of another StatCounter
00102     StatCounter& operator=(int x) { *d_counter=x; return *this; }
00103     StatCounter& operator+=(int x) { *d_counter+=x; return *this; }
00104     StatCounter& operator-=(int x) { *d_counter-=x; return *this; }
00105     StatCounter& operator=(const StatCounter& x)
00106       { *d_counter=*x.d_counter; return *this; }
00107     StatCounter& operator-=(const StatCounter& x)
00108       { *d_counter-=*x.d_counter; return *this; }
00109     StatCounter& operator+=(const StatCounter& x)
00110       { *d_counter+=*x.d_counter; return *this; }
00111     // Comparisons to integers and other StatCounters
00112     friend bool operator==(const StatCounter& c1, const StatCounter& c2);
00113     friend bool operator!=(const StatCounter& c1, const StatCounter& c2);
00114     friend bool operator==(int c1, const StatCounter& c2);
00115     friend bool operator!=(int c1, const StatCounter& c2);
00116     friend bool operator==(const StatCounter& c1, int c2);
00117     friend bool operator!=(const StatCounter& c1, int c2);
00118     // Printing
00119     friend std::ostream& operator<<(std::ostream& os, const StatCounter& f);
00120   }; // end of class StatCounter
00121 
00122   inline bool operator==(const StatCounter& c1, const StatCounter& c2) {
00123     return (*c1.d_counter) == (*c2.d_counter);
00124   }
00125   inline bool operator!=(const StatCounter& c1, const StatCounter& c2) {
00126     return (*c1.d_counter) != (*c2.d_counter);
00127   }
00128   inline bool operator==(int c1, const StatCounter& c2) {
00129     return c1 == (*c2.d_counter);
00130   }
00131   inline bool operator!=(int c1, const StatCounter& c2) {
00132     return c1 != (*c2.d_counter);
00133   }
00134   inline bool operator==(const StatCounter& c1, int c2) {
00135     return (*c1.d_counter) == c2;
00136   }
00137   inline bool operator!=(const StatCounter& c1, int c2) {
00138     return (*c1.d_counter) != c2;
00139   }
00140   inline std::ostream& operator<<(std::ostream& os, const StatCounter& c) {
00141     return (os << *c.d_counter);
00142   }
00143 
00144   // class Statistics: the storage for all flags and counters
00145 
00146   class Statistics {
00147   private:
00148     // Output control
00149     std::ostream* d_os;
00150     typedef std::map<std::string, bool> StatFlagMap;
00151     typedef std::map<std::string, int> StatCounterMap;
00152     StatFlagMap d_flags;
00153     StatCounterMap d_counters;
00154   public:
00155     // Constructor
00156     Statistics() { }
00157     // Destructor (must destroy objects it d_timers)
00158     ~Statistics() { }
00159     // Accessing flags, counters, and timers by name.  If an object
00160     // doesn't exist, it is created and initialized to false or 0.
00161     StatFlag flag(const std::string& name)
00162       { return StatFlag(d_flags[name]); }
00163     StatCounter counter(const std::string& name)
00164       { return StatCounter(d_counters[name]); }
00165 
00166     // Print all the collected data
00167     std::ostream& printAll(std::ostream& os) const;
00168     friend std::ostream& operator<<(std::ostream& os,
00169             const Statistics& stats) {
00170       return stats.printAll(os);
00171     }
00172   }; // end of class Statistics
00173 
00174 } // end of namespace CVC3
00175 
00176 #endif