1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright (C) 2015-2023 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef STOPWATCH_IMPL_H
#define STOPWATCH_IMPL_H

#include <boost/date_time/posix_time/posix_time.hpp><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <boost/scoped_ptr.hpp><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

namespace isc {
namespace util {

/// @brief @c Stopwatch class implementation.
///
/// The @c Stopwatch class uses the plimpl idiom to make it easier to unit
/// test behavior of the @c Stopwatch class without a need to rely on the system
/// clock. The @c StopwatchImpl API allows for overriding the @c getCurrentTime
/// method to return the arbitrary time value as current time to various
/// methods. By setting the current time to arbitrary values the test can expect
/// arbitrary values being returned by the class methods.
///
/// Also, by using the pimpl idiom the @c Stopwatch class hides its implementation
/// details and leaves the header with only the pointer to the @c StopwatchImpl
/// class.
class StopwatchImpl {
public:

    /// @brief Constructor.
    ///
    /// Initializes the internally used timestamps. It also sets the state of
    /// the stopwatch to "stopped".
    StopwatchImpl();

    /// @brief Virtual destructor.
    ///
    /// This destructor is virtual because the @c StopwatchImpl::getCurrentTime
    /// is virtual.
    virtual ~StopwatchImpl();

    /// @brief Starts the stopwatch.
    ///
    /// Sets the stopwatch to the "started" state. It also records the time when
    /// the stopwatch is started. This method is no-op if the stopwatch is
    /// already in the "started" state.
    ///
    /// Also see the @c Stopwatch::start for details.
    void start();

    /// @brief Stop the stopwatch.
    ///
    /// Sets the stopwatch to the "stopped" state. The stop time is recorded and
    /// the cumulative time is updated to include the duration between the most
    /// recent start and stop. This method is no-op if the stopwatch is already
    /// in the "stopped" state.
    ///
    /// Also see the @c Stopwatch::stop for details.
    void stop();

    /// @brief Reset the stopwatch.
    ///
    /// Also see the @c Stopwatch::reset for details.
    void reset();

    /// @brief Retrieves the measured duration.
    ///
    /// Also see the @c Stopwatch::getLastDuration for details.
    boost::posix_time::time_duration getLastDuration() const;

    /// @brief Retrieves the total measured duration.
    ///
    /// Also see the @c Stopwatch::getTotalDuration for details.
    boost::posix_time::time_duration getTotalDuration() const;

    /// @brief Returns the duration in the textual format which can be
    /// directly used in log messages.
    ///
    /// @param duration Duration to be converted to the textual format.
    ///
    /// @return Converted value which can be used to log duration.
    static std::string
    logFormat(const boost::posix_time::time_duration& duration);

protected:

    /// @brief Returns the current time.
    ///
    /// This method is used internally by the @c StopwatchImpl class and
    /// its derivations. This class simply returns the value of
    /// @c boost::posix_time::microsec_clock::univeral_time(), which is
    /// a current timestamp. The derivations may replace it with the
    /// custom implementations. The typical use case is for the unit tests
    /// to customize the behavior of this function to return well known
    /// (deterministic) values. As a result, it is possible to influence
    /// the "measured" values returned by accessors of this class, which
    /// can be compared against some exact values.
    virtual boost::posix_time::ptime getCurrentTime() const;

private:

    /// @brief Holds the state of the stopwatch.
    bool started_;

    /// @brief Holds the timestamp when the stopwatch has been last started.
    boost::posix_time::ptime last_start_;

    /// @brief Holds the timestamp when the stopwatch has been last stopped.
    boost::posix_time::ptime last_stop_;

    /// @brief Holds the total measured time since the stopwatch has been
    /// first started after creation or reset.
    boost::posix_time::time_duration cumulative_time_;

};

}
}

#endif // STOPWATCH_H