CVC3
|
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