aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src/vcpkg_Chrono.cpp
blob: 1bcb439bef66f987df0bcc5be984c5e8877bbddc (plain)
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
#include "pch.h"
#include "vcpkg_Chrono.h"
#include "vcpkg_Checks.h"

namespace vcpkg
{
    static std::string format_time_userfriendly(const std::chrono::nanoseconds& nanos)
    {
        using std::chrono::hours;
        using std::chrono::minutes;
        using std::chrono::seconds;
        using std::chrono::milliseconds;
        using std::chrono::microseconds;
        using std::chrono::nanoseconds;
        using std::chrono::duration_cast;

        const double nanos_as_double = static_cast<double>(nanos.count());

        if (duration_cast<hours>(nanos) > hours())
        {
            auto t = nanos_as_double / duration_cast<nanoseconds>(hours(1)).count();
            return Strings::format("%.4g h", t);
        }

        if (duration_cast<minutes>(nanos) > minutes())
        {
            auto t = nanos_as_double / duration_cast<nanoseconds>(minutes(1)).count();
            return Strings::format("%.4g min", t);
        }

        if (duration_cast<seconds>(nanos) > seconds())
        {
            auto t = nanos_as_double / duration_cast<nanoseconds>(seconds(1)).count();
            return Strings::format("%.4g s", t);
        }

        if (duration_cast<milliseconds>(nanos) > milliseconds())
        {
            auto t = nanos_as_double / duration_cast<nanoseconds>(milliseconds(1)).count();
            return Strings::format("%.4g ms", t);
        }

        if (duration_cast<microseconds>(nanos) > microseconds())
        {
            auto t = nanos_as_double / duration_cast<nanoseconds>(microseconds(1)).count();
            return Strings::format("%.4g us", t);
        }

        return Strings::format("%.4g ns", nanos_as_double);
    }

    ElapsedTime ElapsedTime::createStarted()
    {
        ElapsedTime t;
        t.m_startTick = std::chrono::high_resolution_clock::now();
        return t;
    }

    std::string ElapsedTime::toString() const
    {
        return format_time_userfriendly(elapsed<std::chrono::nanoseconds>());
    }

    Stopwatch Stopwatch::createUnstarted()
    {
        return Stopwatch();
    }

    Stopwatch Stopwatch::createStarted()
    {
        return Stopwatch().start();
    }

    bool Stopwatch::isRunning() const
    {
        return this->m_isRunning;
    }

    const Stopwatch& Stopwatch::start()
    {
        Checks::check_exit(!this->m_isRunning, "This stopwatch is already running.");
        this->m_isRunning = true;
        this->m_startTick = std::chrono::high_resolution_clock::now();
        return *this;
    }

    const Stopwatch& Stopwatch::stop()
    {
        auto tick = std::chrono::high_resolution_clock::now();
        Checks::check_exit(this->m_isRunning, "This stopwatch is already stopped.");
        this->m_isRunning = false;
        this->m_elapsedNanos += tick - this->m_startTick;
        return *this;
    }

    Stopwatch& Stopwatch::reset()
    {
        this->m_elapsedNanos = std::chrono::nanoseconds();
        this->m_isRunning = false;
        return *this;
    }

    std::string Stopwatch::toString() const
    {
        return format_time_userfriendly(this->elapsedNanos());
    }

    Stopwatch::Stopwatch() : m_isRunning(false), m_elapsedNanos(0), m_startTick() { }

    std::chrono::nanoseconds Stopwatch::elapsedNanos() const
    {
        if (this->m_isRunning)
        {
            return std::chrono::high_resolution_clock::now() - this->m_startTick + this->m_elapsedNanos;
        }

        return this->m_elapsedNanos;
    }
}