MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
duration.hpp
浏览该文件的文档.
1#ifndef MSTL_CORE_TIME_DURATION_HPP__
2#define MSTL_CORE_TIME_DURATION_HPP__
3
10
14
15template <typename Rep, typename Period = ratio<1>>
16struct duration;
17
18template <typename Clock, typename Dur>
19struct time_point;
20
23
34template <typename CommonT, typename Period1, typename Period2, typename Dummy = void>
35struct __duration_common_type {};
36
37template <typename CommonT, typename Period1, typename Period2>
38struct __duration_common_type<CommonT, Period1, Period2, void_t<typename CommonT::type>> {
39private:
40 using gcd_numerator = static_gcd<Period1::num, Period2::num>;
41 using gcd_denominator = static_gcd<Period1::den, Period2::den>;
42 using common_rep = typename CommonT::type;
43 using result_ratio = ratio<
44 gcd_numerator::value,
45 (Period1::den / gcd_denominator::value) * Period2::den
46 >;
47
48public:
49 using type = duration<common_rep, typename result_ratio::type>;
50};
51
54
55template <typename Rep1, typename Period1, typename Rep2, typename Period2>
56struct common_type<duration<Rep1, Period1>, duration<Rep2, Period2>>
57 : _INNER __duration_common_type<common_type<Rep1, Rep2>, typename Period1::type, typename Period2::type>
58{};
59
60template <typename Rep, typename Period>
61struct common_type<duration<Rep, Period>, duration<Rep, Period>> {
62 using type = duration<common_type_t<Rep>, typename Period::type>;
63};
64
65template <typename Rep, typename Period>
66struct common_type<duration<Rep, Period>> {
67 using type = duration<common_type_t<Rep>, typename Period::type>;
68};
69
72
73template <typename ToDur, typename ConvFactor, typename CommonRep, bool NumIsOne = false, bool DenIsOne = false>
74struct __duration_cast_impl {
75 template <typename Rep, typename Period>
76 static constexpr ToDur __cast(const duration<Rep, Period>& value) {
77 return ToDur(static_cast<typename ToDur::rep>(static_cast<CommonRep>(value.count())
78 * static_cast<CommonRep>(ConvFactor::num) / static_cast<CommonRep>(ConvFactor::den)));
79 }
80};
81
82template <typename ToDur, typename ConvFactor, typename CommonRep>
83struct __duration_cast_impl<ToDur, ConvFactor, CommonRep, true, true> {
84 template <typename Rep, typename Period>
85 static constexpr ToDur __cast(const duration<Rep, Period>& value) {
86 return ToDur(static_cast<typename ToDur::rep>(value.count()));
87 }
88};
89
90template <typename ToDur, typename ConvFactor, typename CommonRep>
91struct __duration_cast_impl<ToDur, ConvFactor, CommonRep, true, false> {
92 template <typename Rep, typename Period>
93 static constexpr ToDur __cast(const duration<Rep, Period>& value) {
94 return ToDur(static_cast<typename ToDur::rep>(
95 static_cast<CommonRep>(value.count()) / static_cast<CommonRep>(ConvFactor::den)));
96 }
97};
98
99template <typename ToDur, typename ConvFactor, typename CommonRep>
100struct __duration_cast_impl<ToDur, ConvFactor, CommonRep, false, true> {
101 template <typename Rep, typename Period>
102 static constexpr ToDur __cast(const duration<Rep, Period>& value) {
103 return ToDur(static_cast<typename ToDur::rep>(
104 static_cast<CommonRep>(value.count()) * static_cast<CommonRep>(ConvFactor::num)));
105 }
106};
107
110
116
122template <typename T>
124
125template <typename Rep, typename Period>
126struct is_duration<duration<Rep, Period>> : true_type {};
127
132template <typename T>
133MSTL_INLINE17 constexpr bool is_duration_v = is_duration<T>::value;
134
135
146template <typename ToDur, typename Rep, typename Period, enable_if_t<is_duration<ToDur>::value, int> = 0>
147constexpr ToDur time_cast(const duration<Rep, Period>& value) {
148 using to_period = typename ToDur::period;
149 using to_rep = typename ToDur::rep;
150 using conversion_factor = ratio_divide<Period, to_period>;
151 using common_rep = common_type_t<to_rep, Rep, intmax_t>;
152 using duration_caster = _INNER __duration_cast_impl<ToDur, conversion_factor, common_rep,
153 conversion_factor::num == 1, conversion_factor::den == 1>;
154 return duration_caster::__cast(value);
155}
156
157
168
169
178template <typename Rep, typename Period>
179struct duration {
180 static_assert(!is_duration_v<Rep>, "rep cannot be a duration");
181 static_assert(is_ratio_v<Period>, "period must be a specialization of ratio");
182 static_assert(Period::num > 0, "period must be positive");
183
184private:
192 template <typename R1, typename R2,
193 intmax_t Gcd1 = _MSTL gcd(R1::num, R2::num),
194 intmax_t Gcd2 = _MSTL gcd(R1::den, R2::den)>
195 using divide = ratio<(R1::num / Gcd1) * (R2::den / Gcd2), (R1::den / Gcd2) * (R2::num / Gcd1)>;
196
201 template <typename Period2>
202 using is_harmonic = bool_constant<divide<Period2, Period>::den == 1>;
203
204public:
205 using rep = Rep;
206 using period = typename Period::type;
207
208private:
209 rep rep_ = _MSTL initialize<rep>();
210
211public:
215 constexpr duration() = default;
216
220 duration(const duration&) = default;
221
225 constexpr duration& operator =(const duration&) = default;
226
234 template <typename Rep2, typename = enable_if_t<is_convertible_v<const Rep2&, rep>>>
235 constexpr explicit duration(const Rep2& rep2) : rep_(static_cast<rep>(rep2)) {}
236
246 template <typename Rep2, typename Period2, typename Dummy = enable_if_t<
247 is_convertible_v<const Rep2&, rep> && (is_floating_point_v<rep> || (is_harmonic<Period2>::value && !is_floating_point_v<Rep2>))>
248 >
249 constexpr duration(const duration<Rep2, Period2>& dur)
250 : rep_(_MSTL time_cast<duration>(dur).count()) {}
251
260 template <typename Clock, typename Dur, typename Dummy = enable_if_t<is_duration_v<Dur>>>
261 explicit constexpr duration(time_point<Clock, Dur> tp);
262
263
268 constexpr rep count() const noexcept { return rep_; }
269
275 operator +() const {
276 return duration<common_type_t<rep>, period>(rep_);
277 }
278
284 operator -() const {
285 return duration<common_type_t<rep>, period>(-rep_);
286 }
287
292 constexpr duration& operator ++() {
293 ++rep_;
294 return *this;
295 }
296
301 constexpr duration operator ++(int) {
302 return duration(rep_++);
303 }
304
309 constexpr duration& operator --() {
310 --rep_;
311 return *this;
312 }
313
318 constexpr duration operator --(int) {
319 return duration(rep_--);
320 }
321
327 constexpr duration& operator +=(const duration& dur) {
328 rep_ += dur.count();
329 return *this;
330 }
331
337 constexpr duration& operator -=(const duration& dur) {
338 rep_ -= dur.count();
339 return *this;
340 }
341
347 constexpr duration& operator *=(const rep& rhs) {
348 rep_ *= rhs;
349 return *this;
350 }
351
357 constexpr duration& operator /=(const rep& rhs) {
358 rep_ /= rhs;
359 return *this;
360 }
361
368 template <typename U = rep, enable_if_t<!is_floating_point_v<U>, int> = 0>
369 constexpr duration& operator %=(const rep& rhs) {
370 rep_ %= rhs;
371 return *this;
372 }
373
380 template <typename U = rep, enable_if_t<!is_floating_point_v<U>, int> = 0>
381 constexpr duration& operator %=(const duration& rhs) {
382 rep_ %= rhs.count();
383 return *this;
384 }
385
386
391 static constexpr duration zero() noexcept {
392 return duration(rep(0));
393 }
394
399 static constexpr duration min() noexcept {
401 }
402
407 static constexpr duration max() noexcept {
409 }
410
411 MSTL_ALWAYS_INLINE duration<Rep, nano> to_nano() const {
412 return _MSTL time_cast<nanoseconds>(*this);
413 }
414 MSTL_ALWAYS_INLINE duration<Rep, micro> to_micro() const {
415 return _MSTL time_cast<microseconds>(*this);
416 }
417 MSTL_ALWAYS_INLINE duration<Rep, milli> to_milli() const {
418 return _MSTL time_cast<milliseconds>(*this);
419 }
420 MSTL_ALWAYS_INLINE duration<Rep> to_sec() const {
421 return _MSTL time_cast<seconds>(*this);
422 }
423 MSTL_ALWAYS_INLINE duration<Rep, ratio<60>> to_minu() const {
424 return _MSTL time_cast<minutes>(*this);
425 }
426 MSTL_ALWAYS_INLINE duration<Rep, ratio<3600>> to_hour() const {
427 return _MSTL time_cast<hours>(*this);
428 }
429 MSTL_ALWAYS_INLINE duration<Rep, ratio<86400>> to_day() const {
430 return _MSTL time_cast<days>(*this);
431 }
432 MSTL_ALWAYS_INLINE duration<Rep, ratio<604800>> to_week() const {
433 return _MSTL time_cast<weeks>(*this);
434 }
435 MSTL_ALWAYS_INLINE duration<Rep, ratio<31556952>> to_year() const {
436 return _MSTL time_cast<years>(*this);
437 }
438 MSTL_ALWAYS_INLINE duration<Rep, ratio<2629746>> to_month() const {
439 return _MSTL time_cast<months>(*this);
440 }
441};
442
445
451template <typename Rep1, typename Rep2,
452 typename CommonRep = common_type_t<Rep1, Rep2>>
453using __common_rep_t = enable_if_t<is_convertible_v<const Rep2&, CommonRep>, CommonRep>;
454
457
458
469template <typename Rep1, typename Period1, typename Rep2, typename Period2>
472 using duration1 = duration<Rep1, Period1>;
473 using duration2 = duration<Rep2, Period2>;
474 using common_duration = common_type_t<duration1, duration2>;
475 return common_duration(common_duration(lhs).count() + common_duration(rhs).count());
476}
477
488template <typename Rep1, typename Period1, typename Rep2, typename Period2>
491 using duration1 = duration<Rep1, Period1>;
492 using duration2 = duration<Rep2, Period2>;
493 using common_duration = common_type_t<duration1, duration2>;
494 return common_duration(common_duration(lhs).count() - common_duration(rhs).count());
495}
496
506template <typename Rep1, typename Period, typename Rep2>
508operator *(const duration<Rep1, Period>& value, const Rep2& scalar) {
509 using common_duration = duration<common_type_t<Rep1, Rep2>, Period>;
510 return common_duration(common_duration(value).count() * scalar);
511}
512
522template <typename Rep1, typename Rep2, typename Period>
524operator *(const Rep1& scalar, const duration<Rep2, Period>& value) {
525 return value * scalar;
526}
527
537template <typename Rep1, typename Period, typename Rep2>
539operator /(const duration<Rep1, Period>& value, const Rep2& scalar) {
540 using common_duration = duration<common_type_t<Rep1, Rep2>, Period>;
541 return common_duration(common_duration(value).count() / scalar);
542}
543
554template <typename Rep1, typename Period1, typename Rep2, typename Period2>
557 using duration1 = duration<Rep1, Period1>;
558 using duration2 = duration<Rep2, Period2>;
559 using common_duration = common_type_t<duration1, duration2>;
560 return common_duration(lhs).count() / common_duration(rhs).count();
561}
562
572template <typename Rep1, typename Period, typename Rep2>
574operator %(const duration<Rep1, Period>& value, const Rep2& scalar) {
575 using common_duration = duration<common_type_t<Rep1, Rep2>, Period>;
576 return common_duration(common_duration(value).count() % scalar);
577}
578
589template <typename Rep1, typename Period1, typename Rep2, typename Period2>
592 using duration1 = duration<Rep1, Period1>;
593 using duration2 = duration<Rep2, Period2>;
594 using common_duration = common_type_t<duration1, duration2>;
595 return common_duration(common_duration(lhs).count() % common_duration(rhs).count());
596}
597
608template <typename Rep1, typename Period1, typename Rep2, typename Period2>
609constexpr bool operator ==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
610 using duration1 = duration<Rep1, Period1>;
611 using duration2 = duration<Rep2, Period2>;
612 using common_duration = common_type_t<duration1, duration2>;
613 return common_duration(lhs).count() == common_duration(rhs).count();
614}
615
626template <typename Rep1, typename Period1, typename Rep2, typename Period2>
627constexpr bool operator !=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
628 return !(lhs == rhs);
629}
630
641template <typename Rep1, typename Period1, typename Rep2, typename Period2>
642constexpr bool operator <(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
643 using duration1 = duration<Rep1, Period1>;
644 using duration2 = duration<Rep2, Period2>;
645 using common_duration = common_type_t<duration1, duration2>;
646 return common_duration(lhs).count() < common_duration(rhs).count();
647}
648
659template <typename Rep1, typename Period1, typename Rep2, typename Period2>
660constexpr bool operator <=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
661 return !(rhs < lhs);
662}
663
674template <typename Rep1, typename Period1, typename Rep2, typename Period2>
675constexpr bool operator >(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
676 return rhs < lhs;
677}
678
689template <typename Rep1, typename Period1, typename Rep2, typename Period2>
690constexpr bool operator >=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
691 return !(lhs < rhs);
692}
693
694
703template <typename ToDur, typename Rep, typename Period>
704MSTL_NODISCARD constexpr enable_if_t<is_duration_v<ToDur>, ToDur>
706 auto to = time_cast<ToDur>(dur);
707 if (to > dur) {
708 return to - ToDur{1};
709 }
710 return to;
711}
712
721template <typename ToDur, typename Rep, typename Period>
722MSTL_NODISCARD constexpr enable_if_t<is_duration_v<ToDur>, ToDur>
724 auto to = time_cast<ToDur>(dur);
725 if (to < dur) {
726 return to + ToDur{1};
727 }
728 return to;
729}
730 // Duration
732
735
742template <typename Dur, char... Digits>
743constexpr Dur __check_overflow() noexcept {
744 using value_type = static_parse_int<Digits...>;
745 constexpr typename Dur::rep rep = value_type::value;
746 static_assert(
747 rep >= 0 && rep == value_type::value,
748 "literal value cannot be represented by duration type");
749 return Dur(rep);
750}
751
754
760
766
772constexpr duration<decimal_t, ratio<3600, 1>> operator ""_h(const decimal_t hours) noexcept {
774}
775
781template <char... Digits>
782constexpr hours operator ""_h() noexcept {
783 return _INNER __check_overflow<hours, Digits...>();
784}
785
791constexpr duration<decimal_t, ratio<60, 1>> operator ""_min(const decimal_t mins) noexcept {
793}
794
800template <char... Digits>
801constexpr minutes operator ""_min() noexcept {
802 return _INNER __check_overflow<minutes, Digits...>();
803}
804
810constexpr duration<decimal_t> operator ""_s(const decimal_t secs) noexcept {
811 return duration<decimal_t>{secs};
812}
813
819template <char... Digits>
820constexpr seconds operator ""_s() noexcept {
821 return _INNER __check_overflow<seconds, Digits...>();
822}
823
829constexpr duration<decimal_t, milli> operator ""_ms(const decimal_t msecs) noexcept {
830 return duration<decimal_t, milli>{msecs};
831}
832
838template <char... Digits>
839constexpr milliseconds operator ""_ms() noexcept {
840 return _INNER __check_overflow<milliseconds, Digits...>();
841}
842
848constexpr duration<decimal_t, micro> operator ""_us(const decimal_t usecs) noexcept {
849 return duration<decimal_t, micro>{usecs};
850}
851
857template <char... Digits>
858constexpr microseconds operator ""_us() noexcept {
859 return _INNER __check_overflow<microseconds, Digits...>();
860}
861
867constexpr duration<decimal_t, nano> operator ""_ns(const decimal_t nsecs) noexcept {
868 return duration<decimal_t, nano>{nsecs};
869}
870
876template <char... Digits>
877constexpr nanoseconds operator ""_ns() noexcept {
878 return _INNER __check_overflow<nanoseconds, Digits...>();
879}
880 // UserLiterals
882
884
887void MSTL_API sleep_for_aux(int64_t s, int64_t ns);
890
892
898
905template <typename Rep, typename Period>
907 if (time <= time.zero()) return;
908
909#ifdef MSTL_PLATFORM_WINDOWS__
910 const nanoseconds ns = time.to_nano();
911 _INNER sleep_for_aux(0, ns.count());
912#elif defined(MSTL_PLATFORM_LINUX__)
913 const seconds s = time.to_sec();
914 const nanoseconds ns(time - s);
915 _INNER sleep_for_aux(s.count(), ns.count());
916#endif
917}
918 // Thread
920
922
924#endif // MSTL_CORE_TIME_DURATION_HPP__
static MSTL_NODISCARD constexpr T lowest() noexcept
获取类型的最低值
static MSTL_NODISCARD constexpr T max() noexcept
获取类型的最大值
long double decimal_t
扩展精度浮点数类型
long long int64_t
64位有符号整数类型
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
duration< int64_t, micro > microseconds
微秒持续时间
MSTL_INLINE17 constexpr bool is_duration_v
is_duration的便捷变量模板
duration< int64_t, milli > milliseconds
毫秒持续时间
duration< int64_t, ratio< 86400 > > days
天持续时间
constexpr bool operator>(const duration< Rep1, Period1 > &lhs, const duration< Rep2, Period2 > &rhs)
大于比较运算符
duration< int64_t, ratio< 3600 > > hours
小时持续时间
constexpr bool operator<(const duration< Rep1, Period1 > &lhs, const duration< Rep2, Period2 > &rhs)
小于比较运算符
duration< int64_t, ratio< 31556952 > > years
年持续时间(天文年)
constexpr bool operator!=(const duration< Rep1, Period1 > &lhs, const duration< Rep2, Period2 > &rhs)
不等于比较运算符
constexpr duration< _INNER __common_rep_t< Rep1, enable_if_t<!is_duration_v< Rep2 >, Rep2 > >, Period > operator%(const duration< Rep1, Period > &value, const Rep2 &scalar)
取模运算符(持续时间 % 标量)
MSTL_NODISCARD constexpr enable_if_t< is_duration_v< ToDur >, ToDur > ceil(const duration< Rep, Period > &dur)
向上取整持续时间转换
constexpr bool operator>=(const duration< Rep1, Period1 > &lhs, const duration< Rep2, Period2 > &rhs)
大于等于比较运算符
MSTL_NODISCARD constexpr enable_if_t< is_duration_v< ToDur >, ToDur > floor(const duration< Rep, Period > &dur)
向下取整持续时间转换
constexpr bool operator==(const duration< Rep1, Period1 > &lhs, const duration< Rep2, Period2 > &rhs)
等于比较运算符
constexpr duration< _INNER __common_rep_t< Rep1, enable_if_t<!is_duration_v< Rep2 >, Rep2 > >, Period > operator/(const duration< Rep1, Period > &value, const Rep2 &scalar)
除法运算符(持续时间 / 标量)
constexpr duration< _INNER __common_rep_t< Rep1, Rep2 >, Period > operator*(const duration< Rep1, Period > &value, const Rep2 &scalar)
乘法运算符(持续时间 * 标量)
duration< int64_t, nano > nanoseconds
纳秒持续时间
duration< int64_t, ratio< 60 > > minutes
分钟持续时间
duration< int64_t, ratio< 2629746 > > months
月持续时间(平均月)
constexpr common_type_t< duration< Rep1, Period1 >, duration< Rep2, Period2 > > operator+(const duration< Rep1, Period1 > &lhs, const duration< Rep2, Period2 > &rhs)
加法运算符
constexpr common_type_t< duration< Rep1, Period1 >, duration< Rep2, Period2 > > operator-(const duration< Rep1, Period1 > &lhs, const duration< Rep2, Period2 > &rhs)
减法运算符
duration< int64_t, ratio< 604800 > > weeks
周持续时间
constexpr bool operator<=(const duration< Rep1, Period1 > &lhs, const duration< Rep2, Period2 > &rhs)
小于等于比较运算符
constexpr ToDur time_cast(const duration< Rep, Period > &value)
持续时间类型转换
duration< int64_t > seconds
秒持续时间
MSTL_CONST_FUNCTION MSTL_CONSTEXPR14 T gcd(const T &m, const T &n) noexcept
计算最大公约数
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_LITERALS__
结束literals命名空间
#define MSTL_BEGIN_THIS_THREAD__
this_thread命名空间
#define MSTL_END_INNER__
结束inner命名空间
#define MSTL_END_THIS_THREAD__
结束this_thread命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
#define MSTL_BEGIN_LITERALS__
开始literals命名空间(内联)
int64_t intmax_t
最大有符号整数类型
typename _INNER __ratio_divide_impl< ratio1, ratio2 >::type ratio_divide
比率除法类型别名
void sleep_for(const duration< Rep, Period > time)
使当前线程睡眠指定时间
constexpr duration(time_point< Clock, Dur > tp)
从其他时间点构造
typename common_type< Types... >::type common_type_t
common_type的便捷别名
constexpr T initialize() noexcept(is_nothrow_default_constructible< T >::value)
返回类型T的默认初始化值
bool_constant< true > true_type
表示true的类型
void void_t
将任意类型映射为void
bool_constant< false > false_type
表示false的类型
integral_constant< bool, Value > bool_constant
布尔常量包装器
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
MSTL数学函数库
MSTL比率计算
查找多个类型的公共类型
持续时间类模板
constexpr duration & operator+=(const duration &dur)
加法赋值运算符
constexpr duration()=default
默认构造函数
constexpr duration & operator--()
前置自减运算符
constexpr duration(const duration< Rep2, Period2 > &dur)
从其他持续时间构造
constexpr duration & operator%=(const rep &rhs)
取模赋值运算符
duration(const duration &)=default
复制构造函数
constexpr duration & operator/=(const rep &rhs)
除法赋值运算符
constexpr duration & operator-=(const duration &dur)
减法赋值运算符
constexpr duration(const Rep2 &rep2)
从数值构造
constexpr rep count() const noexcept
获取计数值
constexpr duration & operator=(const duration &)=default
复制赋值运算符
constexpr duration & operator++()
前置自增运算符
constexpr duration< common_type_t< rep >, period > operator+() const
一元正号运算符
constexpr duration< common_type_t< rep >, period > operator-() const
一元负号运算符
constexpr duration & operator*=(const rep &rhs)
乘法赋值运算符
static constexpr duration zero() noexcept
获取零持续时间
static constexpr duration min() noexcept
获取最小持续时间
static constexpr duration max() noexcept
获取最大持续时间
检查是否为持续时间类型
比率类模板
根据前缀自动识别进制并解析整数
时间点类模板