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

Generated on Thu Apr 13 16:57:33 2006 for CVC Lite by  doxygen 1.4.4