1 /*! \file
2   \verbatim
3 
4     Copyright (c) 2006, Sylvain Paris and Fr�do Durand
5 
6     Permission is hereby granted, free of charge, to any person
7     obtaining a copy of this software and associated documentation
8     files (the "Software"), to deal in the Software without
9     restriction, including without limitation the rights to use, copy,
10     modify, merge, publish, distribute, sublicense, and/or sell copies
11     of the Software, and to permit persons to whom the Software is
12     furnished to do so, subject to the following conditions:
13 
14     The above copyright notice and this permission notice shall be
15     included in all copies or substantial portions of the Software.
16 
17     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24     DEALINGS IN THE SOFTWARE.
25 
26   \endverbatim
27 */
28 
29 
30 
31 #ifndef __CHRONO__
32 #define __CHRONO__
33 
34 #include <ctime>
35 
36 #include <iostream>
37 #include <sstream>
38 #include <string>
39 
40 #include "msg_stream.h"
41 
42 class Chrono{
43 
44 public:
45   inline Chrono(const std::string t=std::string());
46 
47   inline void start();
48   inline void stop();
49   inline void reset();
50 
51   inline std::string report();
52   inline std::string time_report();
53 
54   inline float time_in_seconds();
55 
56   inline ~Chrono();
57 
58 private:
59   const std::string title;
60 
61   bool         is_started;
62   bool         reported;
63   std::clock_t start_clock;
64   std::clock_t cumulative_clock;
65   unsigned int n_starts;
66 };
67 
68 
69 
70 /*
71 
72   #############################################
73   #############################################
74   #############################################
75   ######                                 ######
76   ######   I M P L E M E N T A T I O N   ######
77   ######                                 ######
78   #############################################
79   #############################################
80   #############################################
81 
82 */
83 
84 
Chrono(const std::string t)85 Chrono::Chrono(const std::string t):
86   title(t),
87   is_started(false),
88   reported(false),
89   start_clock(0),
90   cumulative_clock(0),
91   n_starts(0){
92 
93 }
94 
95 
start()96 void Chrono::start(){
97 
98   if (is_started){
99     Message::warning<<"Chrono '"<<title<<"' is already started. Nothing done."<<Message::done;
100     return;
101   }
102 
103   is_started = true;
104   n_starts++;
105   start_clock = std::clock();
106 }
107 
108 
stop()109 void Chrono::stop(){
110   if (!is_started){
111     Message::warning<<"Chrono '"<<title<<"' is not started. Nothing done."<<Message::done;
112     return;
113   }
114 
115   cumulative_clock += std::clock() - start_clock;
116   is_started = false;
117 }
118 
119 
reset()120 void Chrono::reset(){
121   if (is_started){
122     Message::warning<<"Chrono '"<<title<<"' is started during reset request.\n Only reset cumulative time."<<Message::done;
123     return;
124   }
125 
126   cumulative_clock = 0;
127 }
128 
129 
report()130 std::string Chrono::report(){
131   if (is_started){
132     Message::warning<<"Chrono '"<<title<<"' is started.\n Cannot provide a report."<<Message::done;
133     return std::string();
134   }
135 
136   std::ostringstream msg;
137   msg<<"["<<title<<"] cumulative time: "<<(static_cast<float>(cumulative_clock)/CLOCKS_PER_SEC)
138      <<"s\t#run: "<<n_starts<<"\taverage time: "
139      <<(static_cast<float>(cumulative_clock)/CLOCKS_PER_SEC/n_starts)<<"s";
140   reported = true;
141   return msg.str();
142 }
143 
144 
time_report()145 std::string Chrono::time_report(){
146   if (is_started){
147     Message::warning<<"Chrono '"<<title<<"' is started.\n Cannot provide a time report."<<Message::done;
148     return std::string();
149   }
150 
151   std::ostringstream msg;
152   msg<<(static_cast<float>(cumulative_clock)/CLOCKS_PER_SEC);
153   reported = true;
154   return msg.str();
155 }
156 
157 
time_in_seconds()158 float Chrono::time_in_seconds(){
159 
160   if (is_started){
161     Message::warning<<"Chrono '"<<title<<"' is started.\n Cannot provide a time measure."<<Message::done;
162   }
163 
164   reported = true;
165 
166   return static_cast<float>(cumulative_clock) / CLOCKS_PER_SEC;
167 }
168 
169 
~Chrono()170 Chrono::~Chrono(){
171   if (is_started){
172     Message::warning<<"Chrono '"<<title<<"' is started and is being destroyed."<<Message::done;
173     stop();
174   }
175 
176   if (!reported){
177     Message::warning<<"Chrono '"<<title<<"' is destroyed without having given its result.\n"
178 		    <<report()<<Message::done;
179 
180   }
181 }
182 
183 
184 
185 #endif
186