Migrate some layout timer-related code from std::chrono to Seconds and MonotonicTime
[WebKit-https.git] / Source / WTF / wtf / Seconds.h
1 /*
2  * Copyright (C) 2016 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef WTF_Seconds_h
27 #define WTF_Seconds_h
28
29 #include <wtf/MathExtras.h>
30
31 namespace WTF {
32
33 class MonotonicTime;
34 class PrintStream;
35 class TimeWithDynamicClockType;
36 class WallTime;
37
38 class Seconds {
39 public:
40     Seconds() { }
41     
42     explicit constexpr Seconds(double value)
43         : m_value(value)
44     {
45     }
46     
47     double value() const { return m_value; }
48     
49     double minutes() const { return m_value / 60; }
50     double seconds() const { return m_value; }
51     double milliseconds() const { return seconds() * 1000; }
52     double microseconds() const { return milliseconds() * 1000; }
53     double nanoseconds() const { return microseconds() * 1000; }
54     
55     static constexpr Seconds fromMinutes(double minutes)
56     {
57         return Seconds(minutes * 60);
58     }
59
60     static constexpr Seconds fromMilliseconds(double milliseconds)
61     {
62         return Seconds(milliseconds / 1000);
63     }
64     
65     static constexpr Seconds fromMicroseconds(double microseconds)
66     {
67         return fromMilliseconds(microseconds / 1000);
68     }
69     
70     static constexpr Seconds fromNanoseconds(double nanoseconds)
71     {
72         return fromMicroseconds(nanoseconds / 1000);
73     }
74     
75     static constexpr Seconds infinity()
76     {
77         return Seconds(std::numeric_limits<double>::infinity());
78     }
79     
80     explicit operator bool() const { return !!m_value; }
81     
82     Seconds operator+(Seconds other) const
83     {
84         return Seconds(value() + other.value());
85     }
86     
87     Seconds operator-(Seconds other) const
88     {
89         return Seconds(value() - other.value());
90     }
91     
92     Seconds operator-() const
93     {
94         return Seconds(-value());
95     }
96     
97     // It makes sense to consider scaling a duration, like, "I want to wait 5 times as long as
98     // last time!".
99     Seconds operator*(double scalar) const
100     {
101         return Seconds(value() * scalar);
102     }
103     
104     Seconds operator/(double scalar) const
105     {
106         return Seconds(value() / scalar);
107     }
108     
109     // It's reasonable to think about ratios between Seconds.
110     double operator/(Seconds other) const
111     {
112         return value() / other.value();
113     }
114     
115     Seconds operator%(double scalar) const
116     {
117         return Seconds(fmod(value(), scalar));
118     }
119     
120     // This solves for r, where:
121     //
122     //     floor(this / other) + r / other = this / other
123     //
124     // Therefore, if this is Seconds then r is Seconds.
125     Seconds operator%(Seconds other) const
126     {
127         return Seconds(fmod(value(), other.value()));
128     }
129     
130     Seconds& operator+=(Seconds other)
131     {
132         return *this = *this + other;
133     }
134     
135     Seconds& operator-=(Seconds other)
136     {
137         return *this = *this - other;
138     }
139     
140     Seconds& operator*=(double scalar)
141     {
142         return *this = *this * scalar;
143     }
144     
145     Seconds& operator/=(double scalar)
146     {
147         return *this = *this / scalar;
148     }
149     
150     Seconds& operator%=(double scalar)
151     {
152         return *this = *this % scalar;
153     }
154     
155     Seconds& operator%=(Seconds other)
156     {
157         return *this = *this % other;
158     }
159     
160     WTF_EXPORT_PRIVATE WallTime operator+(WallTime) const;
161     WTF_EXPORT_PRIVATE MonotonicTime operator+(MonotonicTime) const;
162     WTF_EXPORT_PRIVATE TimeWithDynamicClockType operator+(const TimeWithDynamicClockType&) const;
163     
164     WTF_EXPORT_PRIVATE WallTime operator-(WallTime) const;
165     WTF_EXPORT_PRIVATE MonotonicTime operator-(MonotonicTime) const;
166     WTF_EXPORT_PRIVATE TimeWithDynamicClockType operator-(const TimeWithDynamicClockType&) const;
167     
168     bool operator==(Seconds other) const
169     {
170         return m_value == other.m_value;
171     }
172     
173     bool operator!=(Seconds other) const
174     {
175         return m_value != other.m_value;
176     }
177     
178     bool operator<(Seconds other) const
179     {
180         return m_value < other.m_value;
181     }
182     
183     bool operator>(Seconds other) const
184     {
185         return m_value > other.m_value;
186     }
187     
188     bool operator<=(Seconds other) const
189     {
190         return m_value <= other.m_value;
191     }
192     
193     bool operator>=(Seconds other) const
194     {
195         return m_value >= other.m_value;
196     }
197     
198     WTF_EXPORT_PRIVATE void dump(PrintStream&) const;
199     
200 private:
201     double m_value { 0 };
202 };
203
204 inline namespace seconds_literals {
205
206 constexpr Seconds operator"" _min(long double minutes)
207 {
208     return Seconds::fromMinutes(minutes);
209 }
210
211 constexpr Seconds operator"" _s(long double seconds)
212 {
213     return Seconds(seconds);
214 }
215
216 constexpr Seconds operator"" _ms(long double milliseconds)
217 {
218     return Seconds::fromMilliseconds(milliseconds);
219 }
220
221 constexpr Seconds operator"" _us(long double microseconds)
222 {
223     return Seconds::fromMicroseconds(microseconds);
224 }
225
226 constexpr Seconds operator"" _ns(long double nanoseconds)
227 {
228     return Seconds::fromNanoseconds(nanoseconds);
229 }
230
231 constexpr Seconds operator"" _min(unsigned long long minutes)
232 {
233     return Seconds::fromMinutes(minutes);
234 }
235
236 constexpr Seconds operator"" _s(unsigned long long seconds)
237 {
238     return Seconds(seconds);
239 }
240
241 constexpr Seconds operator"" _ms(unsigned long long milliseconds)
242 {
243     return Seconds::fromMilliseconds(milliseconds);
244 }
245
246 constexpr Seconds operator"" _us(unsigned long long microseconds)
247 {
248     return Seconds::fromMicroseconds(microseconds);
249 }
250
251 constexpr Seconds operator"" _ns(unsigned long long nanoseconds)
252 {
253     return Seconds::fromNanoseconds(nanoseconds);
254 }
255
256 } // inline seconds_literals
257
258 WTF_EXPORT_PRIVATE void sleep(Seconds);
259
260 } // namespace WTF
261
262 using namespace WTF::seconds_literals;
263 using WTF::Seconds;
264
265 #endif // WTF_Seconds_h