48483f21cd7d28a864478a6c487d09fa5c1a20e6
[WebKit.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     constexpr Seconds() { }
41     
42     explicit constexpr Seconds(double value)
43         : m_value(value)
44     {
45     }
46     
47     constexpr double value() const { return m_value; }
48     
49     constexpr double minutes() const { return m_value / 60; }
50     constexpr double seconds() const { return m_value; }
51     constexpr double milliseconds() const { return seconds() * 1000; }
52     constexpr double microseconds() const { return milliseconds() * 1000; }
53     constexpr double nanoseconds() const { return microseconds() * 1000; }
54
55     // Keep in mind that Seconds is held in double. If the value is not in range of 53bit integer, the result may not be precise.
56     template<typename T> T minutesAs() const { static_assert(std::is_integral<T>::value, ""); return clampToAccepting64<T>(minutes()); }
57     template<typename T> T secondsAs() const { static_assert(std::is_integral<T>::value, ""); return clampToAccepting64<T>(seconds()); }
58     template<typename T> T millisecondsAs() const { static_assert(std::is_integral<T>::value, ""); return clampToAccepting64<T>(milliseconds()); }
59     template<typename T> T microsecondsAs() const { static_assert(std::is_integral<T>::value, ""); return clampToAccepting64<T>(microseconds()); }
60     template<typename T> T nanosecondsAs() const { static_assert(std::is_integral<T>::value, ""); return clampToAccepting64<T>(nanoseconds()); }
61     
62     static constexpr Seconds fromMinutes(double minutes)
63     {
64         return Seconds(minutes * 60);
65     }
66
67     static constexpr Seconds fromHours(double hours)
68     {
69         return Seconds(hours * 3600);
70     }
71
72     static constexpr Seconds fromMilliseconds(double milliseconds)
73     {
74         return Seconds(milliseconds / 1000);
75     }
76     
77     static constexpr Seconds fromMicroseconds(double microseconds)
78     {
79         return fromMilliseconds(microseconds / 1000);
80     }
81     
82     static constexpr Seconds fromNanoseconds(double nanoseconds)
83     {
84         return fromMicroseconds(nanoseconds / 1000);
85     }
86     
87     static constexpr Seconds infinity()
88     {
89         return Seconds(std::numeric_limits<double>::infinity());
90     }
91     
92     explicit constexpr operator bool() const { return !!m_value; }
93     
94     constexpr Seconds operator+(Seconds other) const
95     {
96         return Seconds(value() + other.value());
97     }
98     
99     constexpr Seconds operator-(Seconds other) const
100     {
101         return Seconds(value() - other.value());
102     }
103     
104     constexpr Seconds operator-() const
105     {
106         return Seconds(-value());
107     }
108     
109     // It makes sense to consider scaling a duration, like, "I want to wait 5 times as long as
110     // last time!".
111     constexpr Seconds operator*(double scalar) const
112     {
113         return Seconds(value() * scalar);
114     }
115     
116     constexpr Seconds operator/(double scalar) const
117     {
118         return Seconds(value() / scalar);
119     }
120     
121     // It's reasonable to think about ratios between Seconds.
122     constexpr double operator/(Seconds other) const
123     {
124         return value() / other.value();
125     }
126     
127     Seconds operator%(double scalar) const
128     {
129         return Seconds(fmod(value(), scalar));
130     }
131     
132     // This solves for r, where:
133     //
134     //     floor(this / other) + r / other = this / other
135     //
136     // Therefore, if this is Seconds then r is Seconds.
137     Seconds operator%(Seconds other) const
138     {
139         return Seconds(fmod(value(), other.value()));
140     }
141     
142     Seconds& operator+=(Seconds other)
143     {
144         return *this = *this + other;
145     }
146     
147     Seconds& operator-=(Seconds other)
148     {
149         return *this = *this - other;
150     }
151     
152     Seconds& operator*=(double scalar)
153     {
154         return *this = *this * scalar;
155     }
156     
157     Seconds& operator/=(double scalar)
158     {
159         return *this = *this / scalar;
160     }
161     
162     Seconds& operator%=(double scalar)
163     {
164         return *this = *this % scalar;
165     }
166     
167     Seconds& operator%=(Seconds other)
168     {
169         return *this = *this % other;
170     }
171     
172     WTF_EXPORT_PRIVATE WallTime operator+(WallTime) const;
173     WTF_EXPORT_PRIVATE MonotonicTime operator+(MonotonicTime) const;
174     WTF_EXPORT_PRIVATE TimeWithDynamicClockType operator+(const TimeWithDynamicClockType&) const;
175     
176     WTF_EXPORT_PRIVATE WallTime operator-(WallTime) const;
177     WTF_EXPORT_PRIVATE MonotonicTime operator-(MonotonicTime) const;
178     WTF_EXPORT_PRIVATE TimeWithDynamicClockType operator-(const TimeWithDynamicClockType&) const;
179     
180     constexpr bool operator==(Seconds other) const
181     {
182         return m_value == other.m_value;
183     }
184     
185     constexpr bool operator!=(Seconds other) const
186     {
187         return m_value != other.m_value;
188     }
189     
190     constexpr bool operator<(Seconds other) const
191     {
192         return m_value < other.m_value;
193     }
194     
195     constexpr bool operator>(Seconds other) const
196     {
197         return m_value > other.m_value;
198     }
199     
200     constexpr bool operator<=(Seconds other) const
201     {
202         return m_value <= other.m_value;
203     }
204     
205     constexpr bool operator>=(Seconds other) const
206     {
207         return m_value >= other.m_value;
208     }
209     
210     WTF_EXPORT_PRIVATE void dump(PrintStream&) const;
211     
212 private:
213     double m_value { 0 };
214 };
215
216 inline namespace seconds_literals {
217
218 constexpr Seconds operator"" _min(long double minutes)
219 {
220     return Seconds::fromMinutes(minutes);
221 }
222
223 constexpr Seconds operator"" _h(long double hours)
224 {
225     return Seconds::fromHours(hours);
226 }
227
228 constexpr Seconds operator"" _s(long double seconds)
229 {
230     return Seconds(seconds);
231 }
232
233 constexpr Seconds operator"" _ms(long double milliseconds)
234 {
235     return Seconds::fromMilliseconds(milliseconds);
236 }
237
238 constexpr Seconds operator"" _us(long double microseconds)
239 {
240     return Seconds::fromMicroseconds(microseconds);
241 }
242
243 constexpr Seconds operator"" _ns(long double nanoseconds)
244 {
245     return Seconds::fromNanoseconds(nanoseconds);
246 }
247
248 constexpr Seconds operator"" _min(unsigned long long minutes)
249 {
250     return Seconds::fromMinutes(minutes);
251 }
252
253 constexpr Seconds operator"" _h(unsigned long long hours)
254 {
255     return Seconds::fromHours(hours);
256 }
257
258 constexpr Seconds operator"" _s(unsigned long long seconds)
259 {
260     return Seconds(seconds);
261 }
262
263 constexpr Seconds operator"" _ms(unsigned long long milliseconds)
264 {
265     return Seconds::fromMilliseconds(milliseconds);
266 }
267
268 constexpr Seconds operator"" _us(unsigned long long microseconds)
269 {
270     return Seconds::fromMicroseconds(microseconds);
271 }
272
273 constexpr Seconds operator"" _ns(unsigned long long nanoseconds)
274 {
275     return Seconds::fromNanoseconds(nanoseconds);
276 }
277
278 } // inline seconds_literals
279
280 WTF_EXPORT_PRIVATE void sleep(Seconds);
281
282 } // namespace WTF
283
284 namespace std {
285
286 inline bool isnan(WTF::Seconds seconds)
287 {
288     return std::isnan(seconds.value());
289 }
290
291 inline bool isinf(WTF::Seconds seconds)
292 {
293     return std::isinf(seconds.value());
294 }
295
296 inline bool isfinite(WTF::Seconds seconds)
297 {
298     return std::isfinite(seconds.value());
299 }
300
301 } // namespace std
302
303 using namespace WTF::seconds_literals;
304 using WTF::Seconds;
305
306 #endif // WTF_Seconds_h