Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Reference

Header <boost/chrono/include.hpp>
Included on the C++11 Recommendation
Chrono I/O
Chrono Rounding Utilities
Other Clocks

As constexpr will not be supported by some compilers, it is replaced in the code by BOOST_CHRONO_CONSTEXPR for constexpr functions and BOOST_CHRONO_STATIC_CONSTEXPR for struct/class static fields. The same applies to noexecpt which is replaced by BOOST_CHRONO_NOEXCEPT in the code.

The documentation doesn't use these macros.

Include all the chrono header files.

#include <boost/chrono/chrono.hpp>
#include <boost/chrono/chrono_io.hpp>
#include <boost/chrono/process_cpu_clocks.hpp>
#include <boost/chrono/thread_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#include <boost/chrono/floor.hpp>
#include <boost/chrono/round.hpp>

Include only the standard files.

#include <boost/chrono/chrono.hpp>

Include only the standard files.

#include <boost/chrono/duration.hpp>
#include <boost/chrono/time_point.hpp>
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/typeof/boost/chrono/chrono.hpp>

Next follows some limitation respect to the C++0x recomendations:

The current implementation provides in addition:

When BOOST_NO_STATIC_ASSERT is defined, the user can select the way static assertions are reported. Define

  • BOOST_CHRONO_USES_STATIC_ASSERT: define it if you want to use Boost.StaticAssert.
  • BOOST_CHRONO_USES_MPL_ASSERT: define it if you want to use Boost.MPL static asertions.
  • BOOST_CHRONO_USES_ARRAY_ASSERT: define it if you want to use internal static asertions.

The default behavior is as BOOST_CHRONO_USES_ARRAY_ASSERT was defined.

When BOOST_CHRONO_USES_MPL_ASSERT is not defined the following symbols are defined as

#define BOOST_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION \
    "A duration representation can not be a duration"
#define BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO \
    "Second template parameter of duration must be a boost::ratio"
#define BOOST_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE \
    "duration period must be positive"
#define BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_TIME_POINT_MUST_BE_A_BOOST_CHRONO_DURATION \
    "Second template parameter of time_point must be a boost::chrono::duration"

Depending on the static assertion used system you will have an hint of the failing assertion either through the symbol or through the text.

When BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING is defined the lib don't provides the hybrid error handling prototypes:

Clock::time_point Clock::now(system::error_code&ec=boost::thows());

This allow to be closer to the standard and to avoid the Boost.System dependency, making possible to have Boost.Chrono as a header-only library.

When BOOST_CHRONO_HEADER_ONLY is defined the lib is header-only.

If in addition BOOST_USE_WINDOWS_H is defined <windows.h> is included, otherwise files in boost/detail/win are used to reduce the impact of including <windows.h>.

However, you will either need to define BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING or link with Boost.System.

This file contains duration specific classes and non-member functions.

namespace boost {
  namespace chrono {

    template <class Rep, class Period = ratio<1> >  class duration;

  }
  template <class Rep1, class Period1, class Rep2, class Period2>
  struct common_type<duration<Rep1, Period1>,
                     duration<Rep2, Period2> >;

  namespace chrono {

    // customization traits
    template <class Rep> struct treat_as_floating_point;
    template <class Rep> struct duration_values;

    // duration arithmetic
    template <class Rep1, class Period1, class Rep2, class Period2>
    constexpr
    typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
    operator+(
        const duration<Rep1, Period1>& lhs,
        const duration<Rep2, Period2>& rhs);

    template <class Rep1, class Period1, class Rep2, class Period2>
    constexpr
    typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
    operator-(
        const duration<Rep1, Period1>& lhs,
        const duration<Rep2, Period2>& rhs);

    template <class Rep1, class Period, class Rep2>
    constexpr
    duration<typename common_type<Rep1, Rep2>::type, Period>
    operator*(
        const duration<Rep1, Period>& d,
        const Rep2& s);

    template <class Rep1, class Period, class Rep2>
    constexpr
    duration<typename common_type<Rep1, Rep2>::type, Period>
    operator*(
        const Rep1& s,
        const duration<Rep2, Period>& d);

    template <class Rep1, class Period, class Rep2>
    constexpr
    duration<typename common_type<Rep1, Rep2>::type, Period>
    operator/(
        const duration<Rep1, Period>& d,
        const Rep2& s);

    template <class Rep1, class Period1, class Rep2, class Period2>
    constexpr
    typename common_type<Rep1, Rep2>::type
    operator/(
        const duration<Rep1, Period1>& lhs,
        const duration<Rep2, Period2>& rhs);

    #ifdef BOOST_CHRONO_EXTENSIONS
    // Used to get frecuency of events
    template <class Rep1, class Rep2, class Period>
    constexpr
    double operator/(
        const Rep1& s,
        const duration<Rep2, Period>& d);
    #endif

    // duration comparisons
    template <class Rep1, class Period1, class Rep2, class Period2>
    constexpr bool operator==(
        const duration<Rep1, Period1>& lhs,
        const duration<Rep2, Period2>& rhs);

    template <class Rep1, class Period1, class Rep2, class Period2>
    constexpr bool operator!=(
        const duration<Rep1, Period1>& lhs,
        const duration<Rep2, Period2>& rhs);

    template <class Rep1, class Period1, class Rep2, class Period2>
    constexpr bool __duration__op_le_1(
        const duration<Rep1, Period1>& lhs,
        const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Rep2, class Period2>
    constexpr bool operator<=(
        const duration<Rep1, Period1>& lhs,
        const duration<Rep2, Period2>& rhs);

    template <class Rep1, class Period1, class Rep2, class Period2>
    constexpr bool operator>(
        const duration<Rep1, Period1>& lhs,
        const duration<Rep2, Period2>& rhs);
    template <class Rep1, class Period1, class Rep2, class Period2>
    constexpr bool operator>=(
        const duration<Rep1, Period1>& lhs,
        const duration<Rep2, Period2>& rhs);

    // duration_cast

    template <class ToDuration, class Rep, class Period>
    constexpr
    ToDuration duration_cast(const duration<Rep, Period>& d);

    // convenience typedefs
    typedef duration<boost::int_least64_t, nano> nanoseconds;    // at least 64 bits needed
    typedef duration<boost::int_least64_t, micro> microseconds;  // at least 55 bits needed
    typedef duration<boost::int_least64_t, milli> milliseconds;  // at least 45 bits needed
    typedef duration<boost::int_least64_t> seconds;              // at least 35 bits needed
    typedef duration<boost::int_least32_t, ratio< 60> > minutes; // at least 29 bits needed
    typedef duration<boost::int_least32_t, ratio<3600> > hours;  // at least 23 bits needed

  }
}
template <class Rep> struct treat_as_floating_point
    : boost::is_floating_point<Rep> {};

The duration template uses the treat_as_floating_point trait to help determine if a duration with one tick period can be converted to another duration with a different tick period. If treat_as_floating_point<Rep>::value is true, then Rep is a floating-point type and implicit conversions are allowed among durations. Otherwise, the implicit convertibility depends on the tick periods of the durations. If Rep is a class type which emulates a floating-point type, the author of Rep can specialize treat_as_floating_point so that duration will treat this Rep as if it were a floating-point type. Otherwise Rep is assumed to be an integral type, or a class emulating an integral type.

template <class Rep>
struct duration_values
{
public:
    static constexpr Rep zero();
    static constexpr Rep max();
    static constexpr Rep min();
};

The duration template uses the duration_values trait to construct special values of the duration's representation (Rep). This is done because the representation might be a class type with behavior which requires some other implementation to return these special values. In that case, the author of that class type should specialize duration_values to return the indicated values.

static constexpr Rep zero();

Returns: Rep(0). Note: Rep(0) is specified instead of Rep() since Rep() may have some other meaning, such as an uninitialized value.

Remarks: The value returned corresponds to the additive identity.

static constexpr Rep max();

Returns: numeric_limits<Rep>::max().

Remarks: The value returned compares greater than zero().

static constexpr Rep min();

Returns: numeric_limits<Rep>::lowest().

Remarks: The value returned compares less than or equal to zero().

template <class Rep1, class Period1, class Rep2, class Period2>
struct common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2> >
{
    typedef chrono::duration<typename common_type<Rep1, Rep2>::type, see bellow> type;
};

The period of the duration indicated by this specialization of common_type is the greatest common divisor of Period1 and Period2. This can be computed by forming a ratio of the greatest common divisor of Period1::num and Period2::num, and the least common multiple of Period1::den and Period2::den.

Note: The typedef type is the duration with the largest tick period possible where both duration arguments will convert to it without requiring a division operation. The representation of this type is intended to be able to hold any value resulting from this conversion, with the possible exception of round-off error when floating-point durations are involved (but not truncation error).

A duration measures time between two points in time (time_point). A duration has a representation which holds a count of ticks, and a tick period. The tick period is the amount of time which occurs from one tick to another in units of a second. It is expressed as a rational constant using ratio.

namespace boost { namespace chrono {

    template <class Rep, class Period>
    class duration {
    public:
        typedef Rep rep;
        typedef Period period;
    private:
        rep rep_; // exposition only
    public:
        constexpr duration();
        template <class Rep2>
        constexpr explicit duration(const Rep2& r);

        template <class Rep2, class Period2>
        constexpr duration(const duration<Rep2, Period2>& d);

        duration& operator=(const duration&) = default;

        constexpr rep count() const;

        constexpr duration  __duration__op_plus();
        constexpr duration  __duration__op_minus();
        duration& operator++();
        duration  operator++(int);
        duration& operator--();
        duration  operator--(int);

        duration& operator+=(const duration& d);
        duration& operator-=(const duration& d);

        duration& operator*==(const rep& rhs);
        duration& operator/=(const rep& rhs);
        duration& operator%=(const rep& rhs);
        duration& operator%=(const duration& rhs);

        static constexpr duration zero();
        static constexpr duration min();
        static constexpr duration max();
    };

}}

Rep must be an arithmetic type, or a class emulating an arithmetic type, compile diagnostic otherwise. If duration is instantiated with the type of Rep being a duration, compile diagnostic is issued.

Period must be an instantiation of ratio, compile diagnostic otherwise.

Period::num must be positive, compile diagnostic otherwise.

Examples:

  • duration<long, ratio<60> > holds a count of minutes using a long.
  • duration<long long, milli> holds a count of milliseconds using a long long.
  • duration<double, ratio<1, 30> > holds a count using a double with a tick period of 1/30 second (a tick frequency of 30 Hz).

The following members of duration do not throw an exception unless the indicated operations on the representations throw an exception.

constexpr duration();

Effects: Constructs an object of type duration from duration_values<rep>::zero().

template <class Rep2>
constexpr explicit duration(const Rep2& r);

Remarks: Rep2 is implicitly convertible to rep, and

  • treat_as_floating_point<rep>::value is true, or
  • !treat_as_floating_point<rep>::value && !treat_as_floating_point<Rep2>::value is true.

If these constraints are not met, this constructor will not participate in overload resolution. Note: This requirement prevents construction of an integral-based duration with a floating-point representation. Such a construction could easily lead to confusion about the value of the duration.

Example:

duration<int, milli> d(3.5);  // do not compile
duration<int, milli> d(3);    // ok

Effects: Constructs an object of type duration.

PostConditions: count() == static_cast<rep>(r).

template <class Rep2, class Period2>
constexpr duration(const duration<Rep2, Period2>& d);

Remarks: treat_as_floating_point<rep>::value, or ratio_divide<Period2, period>::type::den == 1, else this constructor will not participate in overload resolution. note This requirement prevents implicit truncation error when converting between integral-based durations. Such a construction could easily lead to confusion about the value of the duration.

Example:

duration<int, milli> ms(3);
duration<int, micro> us = ms;  // ok
duration<int, milli> ms2 = us; // do not compile

Effects: Constructs an object of type duration, constructing rep_ from duration_cast<duration>(d).count().

constexpr rep count() const;

Returns: rep_.

constexpr duration operator+() const;

Returns: *this.

constexpr duration operator-() const;

Returns: duration(-rep_).

duration& operator++();

Effects: ++rep_.

Returns: *this.

duration operator++(int);

Returns: duration(rep_++).

duration& operator--();

Effects: --rep_.

Returns: *this.

duration operator--(int);

Returns: duration(rep_--).

duration& operator+=(const duration& d);

Effects: rep_ += d.count().

Returns: *this.

duration& operator-=(const duration& d);

Effects: rep_ -= d.count().

Returns: *this.

duration& operator%=(const duration& d);

Effects: rep_ %= d.count().

Returns: *this.

duration& operator*=(const rep& rhs);

Effects: rep_ *= rhs.

Returns: *this.

duration& operator/=(const rep& rhs);

Effects: rep_ /= rhs.

Returns: *this.

duration& operator%=(const rep& rhs);

Effects: rep_ %= rhs.

Returns: *this.

static constexpr duration zero();

Returns: duration(duration_values<rep>::zero()).

static constexpr duration min();

Returns: duration(duration_values<rep>::min()).

static constexpr duration max();

Returns: duration(duration_values<rep>::max()).

template <class Rep1, class Period1, class Rep2, class Period2>
constexpr
typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);

Returns: CD(CD(lhs).count() + CD(rhs).count()) where CD is the type of the return value.

template <class Rep1, class Period1, class Rep2, class Period2>
constexpr
typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);

Returns: CD(CD(lhs).count() - CD(rhs).count()) where CD is the type of the return value.

template <class Rep1, class Period, class Rep2>
constexpr
duration<typename common_type<Rep1, Rep2>::type, Period>
operator*(const duration<Rep1, Period>& d, const Rep2& s);

Requires: Let CR represent the common_type of Rep1 and Rep2. This function will not participate in overload resolution unless both Rep1 and Rep2 are implicitly convertible to CR.

Returns: CD(CD(d).count() * s) where CD is the type of the return value.

template <class Rep1, class Period, class Rep2>
constexpr
duration<typename common_type<Rep1, Rep2>::type, Period>
operator*(const Rep1& s, const duration<Rep2, Period>& d);

Requires: Let CR represent the common_type of Rep1 and Rep2. This function will not participate in overload resolution unless both Rep1 and Rep2 are implicitly convertible to CR.

Returns: d * s.

template <class Rep1, class Period, class Rep2>
constexpr
duration<typename common_type<Rep1, Rep2>::type, Period>
operator/(const duration<Rep1, Period>& d, const Rep2& s);

Requires: Let CR represent the common_type of Rep1 and Rep2. This function will not participate in overload resolution unless both Rep1 and Rep2 are implicitly convertible to CR, and Rep2 is not an instantiation of duration.

Returns: CD(CD(d).count() / s) where CD is the type of the return value.

template <class Rep1, class Period1, class Rep2, class Period2>
constexpr
typename common_type<Rep1, Rep2>::type
operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);

Remarks: Let CD represent the common_type of the two duration arguments. Returns: Returns CD(lhs).count() / CD(rhs).count().

Included only if BOOST_CHRONO_EXTENSIONS is defined.

This overloading could be used to get the frequency of an event counted by Rep1.

template <class Rep1, class Rep2, class Period>
constexpr
double operator/(const Rep1& s, const duration<Rep2, Period>& d);

Remarks: Let CR represent the common_type of Rep1 and Rep2. This function will not participate in overload resolution unless both Rep1 and Rep2 are implicitly convertible to CR, and Rep1 is not an instantiation of duration. Let CD represent duration<CR,Period>.

Returns: CR(s)/CD(d).count() where CD is the type of the return value.

template <class Rep1, class Period, class Rep2>
constexpr
duration<typename common_type<Rep1, Rep2>::type, Period>
operator%(const duration<Rep1, Period>& d, const Rep2& s);

Remarks: Let CR represent the common_type of Rep1 and Rep2. This function will not participate in overload resolution unless Rep2 must be implicitly convertible to CR and Rep2 must not be an instantiation of duration.

Returns: CD(CD(d).count() % s) where CD is the type of the return value.

template <class Rep1, class Period1, class Rep2, class Period2>
constexpr
typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2> >::type
operator%(const duration<Rep1, Period1>& lhs,
          const duration<Rep2, Period2>& rhs);

Remarks: This function will not participate in overload resolution unless

Returns: CD(CD(lhs).count() % CD(rhs).count()) where CD is the type of the return value.

template <class Rep1, class Period1, class Rep2, class Period2>
bool operator==(const duration<Rep1, Period1>& lhs,
                const duration<Rep2, Period2>& rhs);

Returns: Let CD represent the common_type of the two duration arguments.

Returns: Returns CD(lhs).count() == CD(rhs).count()

template <class Rep1, class Period1, class Rep2, class Period2>
bool operator!=(const duration<Rep1, Period1>& lhs,
                const duration<Rep2, Period2>& rhs);

Returns: !(lhs == rhs).

template <class Rep1, class Period1, class Rep2, class Period2>
bool operator< (const duration<Rep1, Period1>& lhs,
                const duration<Rep2, Period2>& rhs);

Returns: Let CD represent the common_type of the two duration arguments. Returns CD(lhs).count() < CD(rhs).count()

template <class Rep1, class Period1, class Rep2, class Period2>
bool operator<=(const duration<Rep1, Period1>& lhs,
                const duration<Rep2, Period2>& rhs);

Returns: !(rhs < lhs).

template <class Rep1, class Period1, class Rep2, class Period2>
bool operator> (const duration<Rep1, Period1>& lhs,
                const duration<Rep2, Period2>& rhs);

Returns: rhs < lhs.

template <class Rep1, class Period1, class Rep2, class Period2>
bool operator>=(const duration<Rep1, Period1>& lhs,
                const duration<Rep2, Period2>& rhs);

Returns: !(lhs < rhs).

template <class ToDuration, class Rep, class Period>
ToDuration duration_cast(const duration<Rep, Period>& d);

Requires: This function will not participate in overload resolution unless ToDuration is an instantiation of duration.

Returns: Forms CF which is a ratio resulting from ratio_divide<Period, typename ToDuration::period>::type. Let CR be the common_type of ToDuration::rep, Rep, and intmax_t.

  • If CF::num == 1 and CF::den == 1, then returns ToDuration(static_cast<typename ToDuration::rep>(d.count()))
  • else if CF::num != 1 and CF::den == 1, then returns ToDuration(static_cast<typename ToDuration::rep>(static_cast<CR>(d.count()) * static_cast<CR>(CF::num)))
  • else if CF::num == 1 and CF::den != 1, then returns ToDuration(static_cast<typename ToDuration::rep>(static_cast<CR>(d.count()) / static_cast<CR>(CF::den)))
  • else returns ToDuration(static_cast<typename ToDuration::rep>(static_cast<CR>(d.count()) * static_cast<CR>(CF::num) / static_cast<CR>(CF::den)))

Remarks: This function does not rely on any implicit conversions. All conversions must be accomplished through static_cast. The implementation avoids all multiplications or divisions when it is known at compile-time that it can be avoided because one or more arguments are 1. All intermediate computations are carried out in the widest possible representation and only converted to the destination representation at the final step.

// convenience typedefs
typedef duration<boost::int_least64_t, nano> nanoseconds;    // at least 64 bits needed
typedef duration<boost::int_least64_t, micro> microseconds;  // at least 55 bits needed
typedef duration<boost::int_least64_t, milli> milliseconds;  // at least 45 bits needed
typedef duration<boost::int_least64_t> seconds;              // at least 35 bits needed
typedef duration<boost::int_least32_t, ratio< 60> > minutes; // at least 29 bits needed
typedef duration<boost::int_least32_t, ratio<3600> > hours;  // at least 23 bits needed

A clock represents a bundle consisting of a duration, a time_point, and a function now() to get the current time_point. A clock must meet the requirements in the following Table.

In this table C1 and C2 denote Clock types. t1 and t2 are values returned from C1::now() where the call returning t1 happens before the call returning t2 and both of these calls occur before C1::time_point::max(). (note This means C1 did not wrap around between t1 and t2.).

Table 4.1. Clock Requirements

expression

return type

operational semantics

C1::rep

An arithmetic type or class emulating an arithmetic type.

The representation type of the duration and time_point.

C1::period

ratio

The tick period of the clock in seconds.

C1::duration

chrono::duration<C1::rep, C1::period>

The duration type of the clock.

C1::time_point

chrono::time_point<C1> or chrono::time_point<C2, C1::duration>

The time_point type of the clock. Different clocks are permitted to share a time_point definition if it is valid to compare their time_points by comparing their respective durations. C1 and C2 must refer to the same epoch.

C1::is_steady

constexpr bool

true if t1 <= t2 is always true, else false. Note: A clock that can be adjusted backwards is not steady

C1::now()

C1::time_point

Returns a time_point representing the current point in time.


Models of Clock:

A type TC meets the TrivialClock requirements if:

  • TC satisfies the Clock requirements,
  • the types TC::rep, TC::duration, and TC::time_point satisfy the requirements of EqualityComparable, LessThanComparable, DefaultConstructible, CopyConstructible, CopyAssignable, Destructible, and the requirements of numeric types.
[Note] Note

This means, in particular, that operations on these types will not throw exceptions.

  • lvalues of the types TC::rep, TC::duration, and TC::time_point are swappable,
  • the function TC::now() does not throw exceptions, and
  • the type TC::time_point::clock meets the TrivialClock requirements, recursively.

Models of TrivialClock:

A type EcC meets the EcClock requirements if

  • TC satisfies the TrivialClock requirements, and
  • it add now() interfaces allowing to recover internal error codes as described in the following table.

In this table C1 denotes a EcClock type and ec is an instance of a boost::system::error_code.

Table 4.2. Clock Requirements

expression

return type

operational semantics

C1::now(ec)

C1::time_point

Returns a time_point representing the current point in time. ec will stores the error-code in case something was wrong internally.

C1::now(boost::throws())

C1::time_point

Returns a time_point representing the current point in time. Throws a boost::system::system_error exception in case something was wrong internally.


Models of Clock:

This file contains time_point specific classes and non-member functions.

namespace boost {
  namespace chrono {

    template <class Clock, class Duration = typename Clock::duration>
    class time_point;

  }
  template <class Clock, class Duration1, class Duration2>
  struct common_type<time_point<Clock, Duration1>,
                     time_point<Clock, Duration2> >;

  namespace chrono {

    // time_point arithmetic
    template <class Clock, class Duration1, class Rep2, class Period2>
    constexpr time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type>
    operator+(const time_point<Clock, Duration1>& lhs,
              const duration<Rep2, Period2>& rhs);

    template <class Rep1, class Period1, class Clock, class Duration2>
    constexpr time_point<Clock, typename common_type<duration<Rep1, Period1>, Duration2>::type>
    operator+(const duration<Rep1, Period1>& lhs,
              const time_point<Clock, Duration2>& rhs);

    template <class Clock, class Duration1, class Rep2, class Period2>
    constexpr time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type>
    operator-(const time_point<Clock, Duration1>& lhs,
              const duration<Rep2, Period2>& rhs);

    template <class Clock, class Duration1, class Duration2>
    constexpr typename common_type<Duration1, Duration2>::type
    operator-(const time_point<Clock, Duration1>& lhs,
              const time_point<Clock, Duration2>& rhs);

    // time_point comparisons
    template <class Clock, class Duration1, class Duration2>
    constexpr bool
    operator==(const time_point<Clock, Duration1>& lhs,
               const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Duration2>
    constexpr bool
    operator!=(const time_point<Clock, Duration1>& lhs,
               const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Duration2>
    constexpr bool
    operator<(const time_point<Clock, Duration1>& lhs,
              const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Duration2>
    constexpr bool
    operator<=(const time_point<Clock, Duration1>& lhs,
               const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Duration2>
    constexpr bool
    operator>(const time_point<Clock, Duration1>& lhs,
              const time_point<Clock, Duration2>& rhs);
    template <class Clock, class Duration1, class Duration2>
    constexpr bool
    operator>=(const time_point<Clock, Duration1>& lhs,
               const time_point<Clock, Duration2>& rhs);

    // time_point_cast
    template <class ToDuration, class Clock, class Duration>
    constexpr time_point<Clock, ToDuration>
    time_point_cast(const time_point<Clock, Duration>& t);

  }
}
template <class Clock, class Duration1, class Duration2>
struct common_type<chrono::time_point<Clock, Duration1>, chrono::time_point<Clock, Duration2> >
{
    typedef chrono::time_point<Clock, typename common_type<Duration1, Duration2>::type> type;
};

The common_type of two time_points is a time_point with the same Clock (both have the same Clock), and the common_type of the two durations.

A time_point represents a point in time with respect to a specific clock.

template <class Clock, class Duration>
class time_point {
public:
    typedef Clock                     clock;
    typedef Duration                  duration;
    typedef typename duration::rep    rep;
    typedef typename duration::period period;
private:
    duration d_; // exposition only
public:
    constexpr time_point();

    constexpr explicit time_point(const duration& d);

    // conversions
    template <class Duration2>
    constexpr
    time_point(const time_point<clock, Duration2>& t);

    // observer
    constexpr duration time_since_epoch() const;

    // arithmetic

    #ifdef BOOST_CHRONO_EXTENSIONS
    constexpr time_point  operator+();
    constexpr time_point  operator-();
    time_point& operator++();
    time_point  operator++(int);
    time_point& operator--();
    time_point  operator--(int);

    time_point& __time_point__op_plus_eq_1(const rep& d);
    time_point& operator-=(const rep& d);
    #endif

    time_point& __time_point__op_plus_eq_2(const duration& d);
    time_point& operator-=(const duration& d);

    // special values

    static constexpr time_point min();
    static constexpr time_point max();
};

Clock must meet the Clock requirements.

Duration must be an instantiation of duration, compile diagnostic otherwise.

constexpr time_point();

Effects: Constructs an object of time_point, initializing d_ with duration::zero(). This time_point represents the epoch.

constexpr time_point(const duration& d);

Effects: Constructs an object of time_point, initializing d_ with d. This time_point represents the epoch + d.

template <class Duration2>
constexpr
time_point(const time_point<clock, Duration2>& t);

Requires: This function will not participate in overload resolution unless Duration2 is implicitly convertible to duration.

Effects: Constructs an object of time_point, initializing d_ with t.time_since_epoch().

constexpr duration time_since_epoch() const;

Returns: d_.

constexpr time_point operator+() const;

Returns: *this.

constexpr time_point operator-() const;

Returns: time_point(-d_).

time_point& operator++();

Effects: ++d_.

Returns: *this.

time_point operator++(int);

Returns: time_point(d_++).

time_point& operator--();

Effects: --d_.

Returns: *this.

time_point operator--(int);

Returns: time_point(d_--).

time_point& operator+=(const rep& r);

Effects: d_ += duration(r).

Returns: *this.

time_point& operator-=(const rep& r);

Effects: d_ -= duration(r)

Returns: *this.

time_point& operator+=(const duration& d);

Effects: d_ += d.

Returns: *this.

time_point& operator-=(const duration& d);

Effects: d_ -= d

Returns: *this.

static constexpr time_point min();

Returns: time_point(duration::min()).

static constexpr time_point max();

Returns: time_point(duration::max()).

template <class Clock, class Duration1, class Rep2, class Period2>
constexpr
time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type>
operator+(const time_point<Clock, Duration1>& lhs,
          const duration<Rep2, Period2>& rhs);

Returns: CT(lhs.time_since_epoch() + rhs) where CT is the type of the return value.

template <class Rep1, class Period1, class Clock, class Duration2>
constexpr
time_point<Clock, typename common_type<duration<Rep1, Period1>, Duration2>::type>
operator+(const duration<Rep1, Period1>& lhs,
          const time_point<Clock, Duration2>& rhs);

Returns: rhs + lhs.

template <class Clock, class Duration1, class Rep2, class Period2>
constexpr
time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2> >::type>
operator-(const time_point<Clock, Duration1>& lhs,
          const duration<Rep2, Period2>& rhs);

Returns: lhs + (-rhs).

template <class Clock, class Duration1, class Duration2>
constexpr
typename common_type<Duration1, Duration2>::type
operator-(const time_point<Clock, Duration1>& lhs,
          const time_point<Clock, Duration2>& rhs);

Returns: lhs.time_since_epoch() - rhs.time_since_epoch().

template <class Clock, class Duration1, class Duration2>
constexpr
bool operator==(const time_point<Clock, Duration1>& lhs,
                const time_point<Clock, Duration2>& rhs);

Returns: lhs.time_since_epoch() == rhs.time_since_epoch().

template <class Clock, class Duration1, class Duration2>
constexpr
bool operator!=(const time_point<Clock, Duration1>& lhs,
                const time_point<Clock, Duration2>& rhs);

Returns: !(lhs == rhs).

template <class Clock, class Duration1, class Duration2>
constexpr
bool operator< (const time_point<Clock, Duration1>& lhs,
                const time_point<Clock, Duration2>& rhs);

Returns: lhs.time_since_epoch() < rhs.time_since_epoch().

template <class Clock, class Duration1, class Duration2>
constexpr
bool operator<=(const time_point<Clock, Duration1>& lhs,
                const time_point<Clock, Duration2>& rhs);

Returns: !(rhs < lhs).

template <class Clock, class Duration1, class Duration2>
constexpr
bool operator>(const time_point<Clock, Duration1>& lhs,
               const time_point<Clock, Duration2>& rhs);

Returns: rhs < lhs.

template <class Clock, class Duration1, class Duration2>
constexpr
bool operator>=(const time_point<Clock, Duration1>& lhs,
                const time_point<Clock, Duration2>& rhs);

Returns: !(lhs < rhs).

template <class ToDuration, class Clock, class Duration>
constexpr
time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t);

Requires: This function will not participate in overload resolution unless ToDuration is an instantiation of duration.

Returns: time_point<Clock, ToDuration>(duration_cast<ToDuration>(t.time_since_epoch())).

This file contains the standard clock classes. The types defined in this section satisfy the TrivialClock requirements

namespace boost {
  namespace chrono {

    // Clocks
    class system_clock;
    class steady_clock;
    class high_resolution_clock;

    template <class CharT>
    struct clock_string<system_clock, CharT>;
    template <class CharT>
    struct clock_string<steady_clock, CharT>;

  }
}

The system_clock class provides a means of obtaining the current wall-clock time from the system-wide real-time clock. The current time can be obtained by calling system_clock::now(). Instances of system_clock::time_point can be converted to and from time_t with the system_clock::to_time_t() and system_clock::to_time_point() functions. If system clock is not steady, a subsequent call to system_clock::now() may return an earlier time than a previous call (e.g. if the operating system clock is manually adjusted, or synchronized with an external clock).

The current implementation of system_clock is related an epoch (midnight UTC of January 1, 1970), but this is not in the contract. You need to use the static function static

std::time_t to_time_t(const time_point& t);

which returns a time_t type that is based on midnight UTC of January 1, 1970.

class system_clock {
public:
    typedef see bellow          duration;
    typedef duration::rep                        rep;
    typedef duration::period                     period;
    typedef chrono::time_point<system_clock>     time_point;
    static constexpr bool is_steady =            false;


    static time_point  now() noexcept;
    static time_point  now(system::error_code & ec);

    // Map to C API
    static std::time_t to_time_t(const time_point& t) noexcept;
    static time_point  from_time_t(std::time_t t) noexcept;
};

system_clock satisfy the Clock requirements:

  • system_clock::duration::min() < system_clock::duration::zero() is true.
  • The nested duration typedef has a resolution that depends on the one provided by the platform.
time_t to_time_t(const time_point& t) noexcept;

Returns: A time_t such that the time_t and t represent the same point in time, truncated to the coarser of the precisions among time_t and time_point.

time_point from_time_t(time_t t) noexcept;

Returns: A time_point such that the time_point and t represent the same point in time, truncated to the coarser of the precisions among time_point and time_t.

Defined if the platform support steady clocks.

steady_clock satisfy the Clock requirements.

steady_clock class provides access to the system-wide steady clock. The current time can be obtained by calling steady_clock::now(). There is no fixed relationship between values returned by steady_clock::now() and wall-clock time.

#ifdef BOOST_HAS_CLOCK_STEADY
    class steady_clock {
    public:
        typedef nanoseconds                          duration;
        typedef duration::rep                        rep;
        typedef duration::period                     period;
        typedef chrono::time_point<steady_clock>     time_point;
        static constexpr bool is_steady =            true;

        static time_point  now() noexcept;
        static time_point  now(system::error_code & ec);
    };
#endif

high_resolution_clock satisfy the Clock requirements.

#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
  typedef steady_clock high_resolution_clock;  // as permitted by [time.clock.hires]
#else
  typedef system_clock high_resolution_clock;  // as permitted by [time.clock.hires]
#endif
template <class CharT>
struct clock_string<system_clock, CharT>
{
    static std::basic_string<CharT> name();
    static std::basic_string<CharT> since();
};

clock_string<>::name() returns "system_clock".

clock_string<>::since() returns " since Jan 1, 1970"

#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY

template <class CharT>
struct clock_string<steady_clock, CharT>
{
    static std::basic_string<CharT> name();
    static std::basic_string<CharT> since();
};
#endif

clock_string<>::name() returns "steady_clock".

clock_string<>::since() returns " since boot"

namespace boost {
namespace chrono {

    template <class Clock, class CharT>
    struct clock_string;

}
}
template <class Clock, class CharT>
struct clock_string;

This template must be specialized for specific clocks. The specialization must define the following functions

static std::basic_string<CharT> name();
static std::basic_string<CharT> since();

clock_string<>::name() return the clock name, which usually corresponds to the class name.

clock_string<>::since() return the textual format of the clock epoch.

Register duration<> and time_point<> class templates to Boost.Typeof.

namespace boost {
namespace chrono {

    template <class CharT>
    class duration_punct;

    template <class CharT, class Traits>
        std::basic_ostream<CharT, Traits>&
        duration_short(std::basic_ostream<CharT, Traits>& os);

    template <class CharT, class Traits>
        std::basic_ostream<CharT, Traits>&
        duration_long(std::basic_ostream<CharT, Traits>& os);

    template <class CharT, class Traits, class Rep, class Period>
        std::basic_ostream<CharT, Traits>&
        operator<<(std::basic_ostream<CharT, Traits>& os, const duration<Rep, Period>& d);

    template <class CharT, class Traits, class Rep, class Period>
        std::basic_istream<CharT, Traits>&
        operator>>(std::basic_istream<CharT, Traits>& is, duration<Rep, Period>& d)

    template <class CharT, class Traits, class Clock, class Duration>
        std::basic_ostream<CharT, Traits>&
        operator<<(std::basic_ostream<CharT, Traits>& os,
               const time_point<Clock, Duration>& tp);

    template <class CharT, class Traits, class Clock, class Duration>
        std::basic_istream<CharT, Traits>&
        operator>>(std::basic_istream<CharT, Traits>& is,
               time_point<Clock, Duration>& tp);

}
}

The duration unit names can be customized through the facet: duration_punct. duration unit names come in two varieties: long and short. The default constructed duration_punct provides names in the long format. These names are English descriptions. Other languages are supported by constructing a duration_punct with the proper spellings for "hours", "minutes" and "seconds", and their abbreviations (for the short format).

template <class CharT>
class duration_punct
    : public std::locale::facet
{
public:
    typedef std::basic_string<CharT> string_type;
    enum {use_long, use_short};

    static std::locale::id id;

    explicit duration_punct(int use = use_long);

    duration_punct(int use,
        const string_type& long_seconds, const string_type& long_minutes,
        const string_type& long_hours, const string_type& short_seconds,
        const string_type& short_minutes, const string_type& short_hours);

    duration_punct(int use, const duration_punct& d);

    template <class Period> string_type short_name() const;
    template <class Period> string_type long_name() const;
    template <class Period> string_type name() const;

    bool is_short_name() const;
    bool is_long_name() const;
};

The short or long format can be easily chosen by streaming a duration_short or duration_long manipulator respectively.

template <class CharT, class Traits>
    std::basic_ostream<CharT, Traits>&
    duration_short(std::basic_ostream<CharT, Traits>& os);

Effects: Set the duration_punct facet to stream durations and time_points as abbreviations.

Returns: the output stream

template <class CharT, class Traits>
    std::basic_ostream<CharT, Traits>&
    duration_long(std::basic_ostream<CharT, Traits>& os);

Effects: Set the duration_punct facet to stream durations and time_points as long text.

Returns: the output stream

Any duration can be streamed out to a basic_ostream. The run-time value of the duration is formatted according to the rules and current format settings for duration::rep. This is followed by a single space and then the compile-time unit name of the duration. This unit name is built on the string returned from ratio_string<> and the data used to construct the duration_punct which was inserted into the stream's locale. If a duration_punct has not been inserted into the stream's locale, a default constructed duration_punct will be added to the stream's locale.

A time_point is formatted by outputting its internal duration followed by a string that describes the time_point::clock epoch. This string will vary for each distinct clock, and for each implementation of the supplied clocks.

template <class CharT, class Traits, class Rep, class Period>
    std::basic_ostream<CharT, Traits>&
    operator<<(std::basic_ostream<CharT, Traits>& os, const duration<Rep, Period>& d);

Effects: outputs the duration as an abrevieated or long text format depending on the state of the duration_punct facet.

Returns: the output stream

template <class CharT, class Traits, class Rep, class Period>
    std::basic_istream<CharT, Traits>&
    operator>>(std::basic_istream<CharT, Traits>& is, duration<Rep, Period>& d)

Effects: reads a duration from the input stream. If a format error is found, the input stream state will be set to failbit.

Returns: the input stream

template <class CharT, class Traits, class Clock, class Duration>
    std::basic_ostream<CharT, Traits>&
    operator<<(std::basic_ostream<CharT, Traits>& os,
           const time_point<Clock, Duration>& tp);

Effects: outputs the time_point as an abrevieated or long text format depending on the state of the duration_punct facet.

Returns: the output stream

template <class CharT, class Traits, class Clock, class Duration>
    std::basic_istream<CharT, Traits>&
    operator>>(std::basic_istream<CharT, Traits>& is,
           time_point<Clock, Duration>& tp);

Effects: reads a time_point from the input stream. If a format error is found, the input stream state will be set to failbit.

Returns: the input stream

namespace boost { namespace chrono {
  template <class To, class Rep, class Period>
  To floor(const duration<Rep, Period>& d);
} }

This function round down the given parameter.

namespace boost { namespace chrono {
  template <class To, class Rep, class Period>
  To round(const duration<Rep, Period>& d);
} }

This function round to nearest, to even on tie the given parameter.

namespace boost { namespace chrono {
  template <class To, class Rep, class Period>
  To ceil(const duration<Rep, Period>& d);
} }

This function round up the given parameter.

Knowing how long a program takes to execute is useful in both test and production environments. It is also helpful if such timing information is broken down into real (wall clock) time, CPU time spent by the user, and CPU time spent by the operating system servicing user requests.

Process clocks don't include the time spent by the child process.

#define BOOST_CHRONO_HAS_PROCESS_CLOCKS

namespace boost { namespace chrono {

    class process_real_cpu_clock;
    class process_user_cpu_clock;
    class process_system_cpu_clock;
    class process_cpu_clock;

    template <typename Rep>
    struct process_times;
    template <class CharT, class Traits, class Rep>
    std::basic_ostream<CharT, Traits>&
    operator<<(std::basic_ostream<CharT, Traits>& os,
            process_times<Rep> const& rhs);

    template <class CharT, class Traits, class Rep>
    std::basic_istream<CharT, Traits>&
    operator>>(std::basic_istream<CharT, Traits>& is,
            process_times<Rep> const& rhs);

    template <class Rep>
    struct duration_values<process_times<Rep> >;

    template <class CharT>
    struct clock_string<process_real_cpu_clock, CharT>;
    struct clock_string<process_user_cpu_clock, CharT>;
    struct clock_string<process_system_cpu_clock, CharT>;
    struct clock_string<process_cpu_clock, CharT>;

} }
namespace std {
    template <class Rep>
    class numeric_limits<boost::chrono::process_times<Rep> >;
}

This macro is defined if the platform supports process clocks.

process_real_cpu_clock satisfy the Clock requirements.

process_real_cpu_clock class provides access to the real process wall-clock steady clock, i.e. the real CPU-time clock of the calling process. The process relative current time can be obtained by calling process_real_cpu_clock::now().

class process_real_cpu_clock {
public:
    typedef nanoseconds                          duration;
    typedef duration::rep                        rep;
    typedef duration::period                     period;
    typedef chrono::time_point<process_real_cpu_clock>    time_point;
    static constexpr bool is_steady =            true;

    static time_point now(  ) noexcept;
    static time_point now( system::error_code & ec );
};

process_user_cpu_clock satisfy the Clock requirements.

process_user_cpu_clock class provides access to the user CPU-time steady clock of the calling process. The process relative user current time can be obtained by calling process_user_cpu_clock::now().

class process_user_cpu_clock {
public:
    typedef nanoseconds                          duration;
    typedef duration::rep                        rep;
    typedef duration::period                     period;
    typedef chrono::time_point<process_user_cpu_clock>    time_point;
    static constexpr bool is_steady =            true;

    static time_point now(  ) noexcept;
    static time_point now( system::error_code & ec );
};

process_system_cpu_clock satisfy the Clock requirements.

process_system_cpu_clock class provides access to the system CPU-time steady clockof the calling process. The process relative system current time can be obtained by calling process_system_cpu_clock::now().

class process_system_cpu_clock {
public:
    typedef nanoseconds                          duration;
    typedef duration::rep                        rep;
    typedef duration::period                     period;
    typedef chrono::time_point<process_system_cpu_clock>    time_point;
    static constexpr bool is_steady =            true;

    static time_point now(  ) noexcept;
    static time_point now( system::error_code & ec );
};

process_cpu_clock can be considered as a tuple<process_real_cpu_clock, process_user_cpu_clock, process_system_cpu_clock>.

process_cpu_clock provides a thin wrapper around the operating system's process time API. For POSIX-like systems, that's the times() function, while for Windows, it's the GetProcessTimes() function.

The process relative real, user and system current time can be obtained at once by calling process_clocks::now().

class process_cpu_clock
{
public:
    typedef process_times<nanoseconds::rep> times ;

    typedef duration<times,  nano>                  duration;
    typedef duration::rep                           rep;
    typedef duration::period                        period;
    typedef chrono::time_point<process_cpu_clock>   time_point;
    static constexpr bool is_steady =               true;

    static time_point now(  ) noexcept;
    static time_point now( system::error_code & ec );
};

This class is the representation of the process_cpu_clock::duration class. As such it needs to implements the arithmetic operators.

template <typename Rep>
struct process_times : arithmetic<process_times<Rep>,
    multiplicative<process_times<Rep>, Rep,
    less_than_comparable<process_times<Rep> > > >
{
    Rep real;    // real (i.e wall clock) time
    Rep user;    // user cpu time
    Rep system;  // system cpu time

    times();
    times(
        process_real_cpu_clock::rep r,
        process_user_cpu_clock::rep u,
        process_system_cpu_clock::rep s);

    template <typename Rep2>
    explicit process_times(
        Rep2 r);
    template <typename Rep2>
    explicit process_times(
        process_times<Rep2> const& rhs);
    operator rep() const;

    bool operator==(process_times const& rhs);
    template <typename Rep2>
    bool operator==(process_times<Rep2> const& rhs);

    times operator+=(process_times const& rhs);
    times operator-=(process_times const& rhs);
    times operator*=(process_times const& rhs);
    times operator/=(process_times const& rhs);
    bool operator<(process_times const & rhs) const;
};
template <class CharT, class Traits, class Rep>
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os,
        process_times<Rep> const& rhs);

Effects: Output each part separated by ';' and sourrounded by '{', '}'.

Throws: None.

template <class CharT, class Traits, class Rep>
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is,
        process_times<Rep> const& rhs);

Effects: overrides the value of rhs if the input stream has the format "{r;u;s}". Otherwise, set the input stream state as failbit | eofbit.

Throws: None.

template <class Rep>
struct duration_values<process_times<Rep> >
{
    static process_times<Rep> zero();
    static process_times<Rep> max();
    static process_times<Rep> min();
};

The times specific functions zero(), max() and min() uses the relative functions on the representation of each component.

template <class CharT>
struct clock_string<process_real_cpu_clock, CharT>
{
    static std::basic_string<CharT> name();
    static std::basic_string<CharT> since();
};

clock_string<>::name() returns "process_real_cpu_clock".

clock_string<>::since() returns " since process start-up"

template <class CharT>
struct clock_string<process_user_cpu_clock, CharT>
{
    static std::basic_string<CharT> name();
    static std::basic_string<CharT> since();
};

clock_string<>::name() returns "process_user_cpu_clock".

clock_string<>::since() returns " since process start-up"

template <class CharT>
struct clock_string<process_system_cpu_clock, CharT>
{
    static std::basic_string<CharT> name();
    static std::basic_string<CharT> since();
};

clock_string<>::name() returns "process_system_cpu_clock".

clock_string<>::since() returns " since process start-up"

template <class CharT>
struct clock_string<process_cpu_clock, CharT>
{
    static std::basic_string<CharT> name();
    static std::basic_string<CharT> since();
};

clock_string<>::name() returns "process_cpu_clock".

clock_string<>::since() returns " since process start-up"

namespace std {
    template <>
    class numeric_limits<boost::chrono::process_times<Rep>> {
        typedef boost::chrono::process_times<Rep> Res;

    public:
        static const bool is_specialized = true;
        static Res min();
        static Res max();
        static Res lowest();
        static const int digits;
        static const int digits10;
        static const bool is_signed = false;
        static const bool is_integer = true;
        static const bool is_exact = true;
        static const int radix = 0;
    };
}

The process_times<Rep> specialization functions min(), max() and lowest() uses the relative functions on the representation of each component.

Notes

  • min() returns the tuple of mins.
  • max() returns the tuple of maxs.
  • lowest() returns the tuple of lowests.
  • digits is the sum of (binary) digits.
  • digits10 is the sum of digits10s.

Knowing the time a thread takes to execute is useful in both test and production environments.

#define BOOST_CHRONO_HAS_THREAD_CLOCK
#define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY
namespace boost { namespace chrono {

    class thread_clock;
    template <class CharT>
    struct clock_string<thread_clock, CharT>;

} }

This macro is defined if the platform supports thread clocks.

This macro is defined if the platform has a thread clock. Its value is true if it is steady and false otherwise.

thread_clock satisfy the Clock requirements.

thread_clock class provides access to the real thread wall-clock, i.e. the real CPU-time clock of the calling thread. The thread relative current time can be obtained by calling thread_clock::now().

class thread_clock {
public:
    typedef nanoseconds                          duration;
    typedef duration::rep                        rep;
    typedef duration::period                     period;
    typedef chrono::time_point<thread_clock>     time_point;
    static constexpr bool is_steady =            BOOST_CHRONO_THREAD_CLOCK_IS_STEADY;

    static time_point now(  ) noexcept;
    static time_point now( system::error_code & ec );
};
#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK)
template <class CharT>
struct clock_string<thread_clock, CharT>
{
    static std::basic_string<CharT> name();
    static std::basic_string<CharT> since();
};
#endif

clock_string<>::name() returns "thread_clock".

clock_string<>::since() returns " since thread start-up"


PrevUpHomeNext