Line data Source code
1 : /* 2 : 3 : MIT License 4 : 5 : Copyright (c) 2017 André L. Maravilha 6 : 7 : Permission is hereby granted, free of charge, to any person obtaining a copy 8 : of this software and associated documentation files (the "Software"), to deal 9 : in the Software without restriction, including without limitation the rights 10 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 : copies 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 included in all 15 : copies or substantial portions of the Software. 16 : 17 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 : SOFTWARE. 24 : 25 : */ 26 : 27 : #ifndef CXX_TIMER_HPP 28 : #define CXX_TIMER_HPP 29 : 30 : #include <chrono> 31 : 32 : 33 : namespace cxxtimer { 34 : 35 : /** 36 : * This class works as a stopwatch. 37 : */ 38 : class Timer { 39 : 40 : public: 41 : 42 : /** 43 : * Constructor. 44 : * 45 : * @param start 46 : * If true, the timer is started just after construction. 47 : * Otherwise, it will not be automatically started. 48 : */ 49 : explicit Timer(bool start = false); 50 : 51 : /** 52 : * Copy constructor. 53 : * 54 : * @param other 55 : * The object to be copied. 56 : */ 57 108 : Timer(const Timer& other) = default; 58 : 59 : /** 60 : * Transfer constructor. 61 : * 62 : * @param other 63 : * The object to be transfered. 64 : */ 65 108 : Timer(Timer&& other) = default; 66 : 67 : /** 68 : * Destructor. 69 : */ 70 216 : virtual ~Timer() = default; 71 : 72 : /** 73 : * Assignment operator by copy. 74 : * 75 : * @param other 76 : * The object to be copied. 77 : * 78 : * @return A reference to this object. 79 : */ 80 : Timer& operator=(const Timer& other) = default; 81 : 82 : /** 83 : * Assignment operator by transfer. 84 : * 85 : * @param other 86 : * The object to be transferred. 87 : * 88 : * @return A reference to this object. 89 : */ 90 : Timer& operator=(Timer&& other) = default; 91 : 92 : /** 93 : * Start/resume the timer. 94 : */ 95 : void start(); 96 : 97 : /** 98 : * Stop/pause the timer. 99 : */ 100 : void stop(); 101 : 102 : /** 103 : * Reset the timer. 104 : */ 105 : void reset(); 106 : 107 : /** 108 : * Return the elapsed time. 109 : * 110 : * @tparam duration_t 111 : * The duration type used to return the time elapsed. If not 112 : * specified, it returns the time as represented by 113 : * std::chrono::milliseconds. 114 : * 115 : * @return The elapsed time. 116 : */ 117 : template <class duration_t = std::chrono::milliseconds> 118 : typename duration_t::rep count() const; 119 : 120 : private: 121 133752 : bool started_{false}; 122 133752 : bool paused_{false}; 123 133752 : std::chrono::steady_clock::time_point reference_{std::chrono::steady_clock::now()}; 124 133752 : std::chrono::duration<long double> accumulated_{std::chrono::duration<long double>(0)}; 125 : }; 126 : 127 : } 128 : 129 : 130 267476 : inline cxxtimer::Timer::Timer(bool start) 131 267476 : { 132 133752 : if (start) { 133 133732 : this->start(); 134 133732 : } 135 267476 : } 136 : 137 133770 : inline void cxxtimer::Timer::start() { 138 133770 : if (!started_) { 139 133770 : started_ = true; 140 133770 : paused_ = false; 141 133770 : accumulated_ = std::chrono::duration<long double>(0); 142 133770 : reference_ = std::chrono::steady_clock::now(); 143 133770 : } else if (paused_) { 144 0 : reference_ = std::chrono::steady_clock::now(); 145 0 : paused_ = false; 146 0 : } 147 133770 : } 148 : 149 75815 : inline void cxxtimer::Timer::stop() { 150 75815 : if (started_ && !paused_) { 151 75815 : std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); 152 75815 : accumulated_ = accumulated_ + std::chrono::duration_cast< std::chrono::duration<long double> >(now - reference_); 153 75815 : paused_ = true; 154 75815 : } 155 75815 : } 156 : 157 : inline void cxxtimer::Timer::reset() { 158 : if (started_) { 159 : started_ = false; 160 : paused_ = false; 161 : reference_ = std::chrono::steady_clock::now(); 162 : accumulated_ = std::chrono::duration<long double>(0); 163 : } 164 : } 165 : 166 : template <class duration_t> 167 133745 : typename duration_t::rep cxxtimer::Timer::count() const { 168 133745 : if (started_) { 169 133745 : if (paused_) { 170 75815 : return std::chrono::duration_cast<duration_t>(accumulated_).count(); 171 : } else { 172 115860 : return std::chrono::duration_cast<duration_t>( 173 115860 : accumulated_ + (std::chrono::steady_clock::now() - reference_)).count(); 174 : } 175 : } else { 176 0 : return duration_t(0).count(); 177 : } 178 133745 : } 179 : 180 : 181 : #endif