NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
duration.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_TIME_DURATION_HPP__
2#define NEFORCE_CORE_TIME_DURATION_HPP__
3
10
13NEFORCE_BEGIN_NAMESPACE__
14
15template <typename Rep, typename Period = ratio<1>>
16struct duration;
17
18template <typename Clock, typename Dur>
19struct time_point;
20
22NEFORCE_BEGIN_INNER__
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<gcd_numerator::value, (Period1::den / gcd_denominator::value) * Period2::den>;
44
45public:
46 using type = duration<common_rep, typename result_ratio::type>;
47};
48
49NEFORCE_END_INNER__
51
52template <typename Rep1, typename Period1, typename Rep2, typename Period2>
53struct common_type<duration<Rep1, Period1>, duration<Rep2, Period2>>
54: inner::__duration_common_type<common_type<Rep1, Rep2>, typename Period1::type, typename Period2::type> {};
55
56template <typename Rep, typename Period>
57struct common_type<duration<Rep, Period>, duration<Rep, Period>> {
58 using type = duration<common_type_t<Rep>, typename Period::type>;
59};
60
61template <typename Rep, typename Period>
62struct common_type<duration<Rep, Period>> {
63 using type = duration<common_type_t<Rep>, typename Period::type>;
64};
65
67NEFORCE_BEGIN_INNER__
68
69template <typename ToDur, typename ConvFactor, typename CommonRep, bool NumIsOne = false, bool DenIsOne = false>
70struct __duration_cast_impl {
71 template <typename Rep, typename Period>
72 static constexpr ToDur __cast(const duration<Rep, Period>& value) {
73 return ToDur(static_cast<typename ToDur::rep>(static_cast<CommonRep>(value.count()) *
74 static_cast<CommonRep>(ConvFactor::num) /
75 static_cast<CommonRep>(ConvFactor::den)));
76 }
77};
78
79template <typename ToDur, typename ConvFactor, typename CommonRep>
80struct __duration_cast_impl<ToDur, ConvFactor, CommonRep, true, true> {
81 template <typename Rep, typename Period>
82 static constexpr ToDur __cast(const duration<Rep, Period>& value) {
83 return ToDur(static_cast<typename ToDur::rep>(value.count()));
84 }
85};
86
87template <typename ToDur, typename ConvFactor, typename CommonRep>
88struct __duration_cast_impl<ToDur, ConvFactor, CommonRep, true, false> {
89 template <typename Rep, typename Period>
90 static constexpr ToDur __cast(const duration<Rep, Period>& value) {
91 return ToDur(static_cast<typename ToDur::rep>(static_cast<CommonRep>(value.count()) /
92 static_cast<CommonRep>(ConvFactor::den)));
93 }
94};
95
96template <typename ToDur, typename ConvFactor, typename CommonRep>
97struct __duration_cast_impl<ToDur, ConvFactor, CommonRep, false, true> {
98 template <typename Rep, typename Period>
99 static constexpr ToDur __cast(const duration<Rep, Period>& value) {
100 return ToDur(static_cast<typename ToDur::rep>(static_cast<CommonRep>(value.count()) *
101 static_cast<CommonRep>(ConvFactor::num)));
102 }
103};
104
105NEFORCE_END_INNER__
107
113
119template <typename T>
121
122template <typename Rep, typename Period>
123struct is_duration<duration<Rep, Period>> : true_type {};
124
129template <typename T>
130NEFORCE_INLINE17 constexpr bool is_duration_v = is_duration<T>::value;
131
132
143template <typename ToDur, typename Rep, typename Period, enable_if_t<is_duration<ToDur>::value, int> = 0>
144constexpr ToDur time_cast(const duration<Rep, Period>& value) {
145 using to_period = typename ToDur::period;
146 using to_rep = typename ToDur::rep;
147 using conversion_factor = ratio_divide<Period, to_period>;
148 using common_rep = common_type_t<to_rep, Rep, intmax_t>;
149 using duration_caster = inner::__duration_cast_impl<ToDur, conversion_factor, common_rep,
150 conversion_factor::num == 1, conversion_factor::den == 1>;
151 return duration_caster::__cast(value);
152}
153
154
165
166
175template <typename Rep, typename Period>
176struct duration {
177 static_assert(!is_duration_v<Rep>, "rep cannot be a duration");
178 static_assert(is_ratio_v<Period>, "period must be a specialization of ratio");
179 static_assert(Period::num > 0, "period must be positive");
180
181private:
189 template <typename R1, typename R2, intmax_t Gcd1 = _NEFORCE gcd(R1::num, R2::num),
190 intmax_t Gcd2 = _NEFORCE gcd(R1::den, R2::den)>
191 using divide = ratio<(R1::num / Gcd1) * (R2::den / Gcd2), (R1::den / Gcd2) * (R2::num / Gcd1)>;
192
197 template <typename Period2>
198 using is_harmonic = bool_constant<divide<Period2, Period>::den == 1>;
199
200public:
201 using rep = Rep;
202 using period = typename Period::type;
203
204private:
205 rep rep_ = _NEFORCE initialize<rep>();
206
207public:
211 constexpr duration() = default;
212
216 duration(const duration&) = default;
217
221 constexpr duration& operator=(const duration&) = default;
222
230 template <typename Rep2, typename = enable_if_t<is_convertible_v<const Rep2&, rep>>>
231 constexpr explicit duration(const Rep2& rep2) :
232 rep_(static_cast<rep>(rep2)) {}
233
243 template <typename Rep2, typename Period2,
247 constexpr duration(const duration<Rep2, Period2>& dur) :
248 rep_(_NEFORCE time_cast<duration>(dur).count()) {}
249
258 template <typename Clock, typename Dur, typename Dummy = enable_if_t<is_duration_v<Dur>>>
259 explicit constexpr duration(time_point<Clock, Dur> tp);
260
261
266 NEFORCE_NODISCARD constexpr rep count() const noexcept { return rep_; }
267
273 return duration<common_type_t<rep>, period>(rep_);
274 }
275
281 return duration<common_type_t<rep>, period>(-rep_);
282 }
283
288 constexpr duration& operator++() {
289 ++rep_;
290 return *this;
291 }
292
297 constexpr duration operator++(int) { return duration(rep_++); }
298
303 constexpr duration& operator--() {
304 --rep_;
305 return *this;
306 }
307
312 constexpr duration operator--(int) { return duration(rep_--); }
313
319 constexpr duration& operator+=(const duration& dur) {
320 rep_ += dur.count();
321 return *this;
322 }
323
329 constexpr duration& operator-=(const duration& dur) {
330 rep_ -= dur.count();
331 return *this;
332 }
333
339 constexpr duration& operator*=(const rep& rhs) {
340 rep_ *= rhs;
341 return *this;
342 }
343
349 constexpr duration& operator/=(const rep& rhs) {
350 rep_ /= rhs;
351 return *this;
352 }
353
360 template <typename U = rep, enable_if_t<!is_floating_point_v<U>, int> = 0>
361 constexpr duration& operator%=(const rep& rhs) {
362 rep_ %= rhs;
363 return *this;
364 }
365
372 template <typename U = rep, enable_if_t<!is_floating_point_v<U>, int> = 0>
373 constexpr duration& operator%=(const duration& rhs) {
374 rep_ %= rhs.count();
375 return *this;
376 }
377
378
383 static constexpr duration zero() noexcept { return duration(rep(0)); }
384
389 static constexpr duration min() noexcept { return duration(numeric_traits<Rep>::lowest()); }
390
395 static constexpr duration max() noexcept { return duration(numeric_traits<Rep>::max()); }
396
397 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr duration<Rep, nano> to_nano() const {
398 return _NEFORCE time_cast<nanoseconds>(*this);
399 }
400 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr duration<Rep, micro> to_micro() const {
401 return _NEFORCE time_cast<microseconds>(*this);
402 }
403 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr duration<Rep, milli> to_milli() const {
404 return _NEFORCE time_cast<milliseconds>(*this);
405 }
406 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr duration<Rep> to_sec() const {
407 return _NEFORCE time_cast<seconds>(*this);
408 }
409 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr duration<Rep, ratio<60>> to_minu() const {
410 return _NEFORCE time_cast<minutes>(*this);
411 }
412 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr duration<Rep, ratio<3600>> to_hour() const {
413 return _NEFORCE time_cast<hours>(*this);
414 }
415 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr duration<Rep, ratio<86400>> to_day() const {
416 return _NEFORCE time_cast<days>(*this);
417 }
418 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr duration<Rep, ratio<604800>> to_week() const {
419 return _NEFORCE time_cast<weeks>(*this);
420 }
421 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr duration<Rep, ratio<31556952>> to_year() const {
422 return _NEFORCE time_cast<years>(*this);
423 }
424 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr duration<Rep, ratio<2629746>> to_month() const {
425 return _NEFORCE time_cast<months>(*this);
426 }
427};
428
430NEFORCE_BEGIN_INNER__
431
437template <typename Rep1, typename Rep2, typename CommonRep = common_type_t<Rep1, Rep2>>
438using __common_rep_t = enable_if_t<is_convertible_v<const Rep2&, CommonRep>, CommonRep>;
439
440NEFORCE_END_INNER__
442
443
454template <typename Rep1, typename Period1, typename Rep2, typename Period2>
457 using duration1 = duration<Rep1, Period1>;
458 using duration2 = duration<Rep2, Period2>;
459 using common_duration = common_type_t<duration1, duration2>;
460 return common_duration(common_duration(lhs).count() + common_duration(rhs).count());
461}
462
473template <typename Rep1, typename Period1, typename Rep2, typename Period2>
476 using duration1 = duration<Rep1, Period1>;
477 using duration2 = duration<Rep2, Period2>;
478 using common_duration = common_type_t<duration1, duration2>;
479 return common_duration(common_duration(lhs).count() - common_duration(rhs).count());
480}
481
491template <typename Rep1, typename Period, typename Rep2>
493 const Rep2& scalar) {
494 using common_duration = duration<common_type_t<Rep1, Rep2>, Period>;
495 return common_duration(common_duration(value).count() * scalar);
496}
497
507template <typename Rep1, typename Rep2, typename Period>
508constexpr duration<inner::__common_rep_t<Rep2, Rep1>, Period> operator*(const Rep1& scalar,
509 const duration<Rep2, Period>& value) {
510 return value * scalar;
511}
512
522template <typename Rep1, typename Period, typename Rep2>
524operator/(const duration<Rep1, Period>& value, const Rep2& scalar) {
525 using common_duration = duration<common_type_t<Rep1, Rep2>, Period>;
526 return common_duration(common_duration(value).count() / scalar);
527}
528
539template <typename Rep1, typename Period1, typename Rep2, typename Period2>
541 using duration1 = duration<Rep1, Period1>;
542 using duration2 = duration<Rep2, Period2>;
543 using common_duration = common_type_t<duration1, duration2>;
544 return common_duration(lhs).count() / common_duration(rhs).count();
545}
546
556template <typename Rep1, typename Period, typename Rep2>
558operator%(const duration<Rep1, Period>& value, const Rep2& scalar) {
559 using common_duration = duration<common_type_t<Rep1, Rep2>, Period>;
560 return common_duration(common_duration(value).count() % scalar);
561}
562
573template <typename Rep1, typename Period1, typename Rep2, typename Period2>
576 using duration1 = duration<Rep1, Period1>;
577 using duration2 = duration<Rep2, Period2>;
578 using common_duration = common_type_t<duration1, duration2>;
579 return common_duration(common_duration(lhs).count() % common_duration(rhs).count());
580}
581
592template <typename Rep1, typename Period1, typename Rep2, typename Period2>
593constexpr bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
594 using duration1 = duration<Rep1, Period1>;
595 using duration2 = duration<Rep2, Period2>;
596 using common_duration = common_type_t<duration1, duration2>;
597 return common_duration(lhs).count() == common_duration(rhs).count();
598}
599
610template <typename Rep1, typename Period1, typename Rep2, typename Period2>
611constexpr bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
612 return !(lhs == rhs);
613}
614
625template <typename Rep1, typename Period1, typename Rep2, typename Period2>
626constexpr bool operator<(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
627 using duration1 = duration<Rep1, Period1>;
628 using duration2 = duration<Rep2, Period2>;
629 using common_duration = common_type_t<duration1, duration2>;
630 return common_duration(lhs).count() < common_duration(rhs).count();
631}
632
643template <typename Rep1, typename Period1, typename Rep2, typename Period2>
644constexpr bool operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
645 return !(rhs < lhs);
646}
647
658template <typename Rep1, typename Period1, typename Rep2, typename Period2>
659constexpr bool operator>(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
660 return rhs < lhs;
661}
662
673template <typename Rep1, typename Period1, typename Rep2, typename Period2>
674constexpr bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
675 return !(lhs < rhs);
676}
677
678
687template <typename ToDur, typename Rep, typename Period>
688NEFORCE_NODISCARD constexpr enable_if_t<is_duration_v<ToDur>, ToDur> floor(const duration<Rep, Period>& dur) {
689 auto to = time_cast<ToDur>(dur);
690 if (to > dur) {
691 return to - ToDur{1};
692 }
693 return to;
694}
695
704template <typename ToDur, typename Rep, typename Period>
705NEFORCE_NODISCARD constexpr enable_if_t<is_duration_v<ToDur>, ToDur> ceil(const duration<Rep, Period>& dur) {
706 auto to = time_cast<ToDur>(dur);
707 if (to < dur) {
708 return to + ToDur{1};
709 }
710 return to;
711}
712 // Duration
714
716NEFORCE_BEGIN_INNER__
717
724template <typename Dur, char... Digits>
725constexpr Dur __check_overflow() noexcept {
726 using value_type = static_parse_int<Digits...>;
727 constexpr typename Dur::rep rep = value_type::value;
728 static_assert(rep >= 0 && rep == value_type::value, "literal value cannot be represented by duration type");
729 return Dur(rep);
730}
731
732NEFORCE_END_INNER__
734
739NEFORCE_BEGIN_LITERALS__
740
746
752constexpr duration<decimal_t, ratio<3600, 1>> operator""_h(const decimal_t hours) noexcept {
754}
755
761template <char... Digits>
762constexpr hours operator""_h() noexcept {
763 return inner::__check_overflow<hours, Digits...>();
764}
765
771constexpr duration<decimal_t, ratio<60, 1>> operator""_min(const decimal_t mins) noexcept {
773}
774
780template <char... Digits>
781constexpr minutes operator""_min() noexcept {
782 return inner::__check_overflow<minutes, Digits...>();
783}
784
790constexpr duration<decimal_t> operator""_s(const decimal_t secs) noexcept { return duration<decimal_t>{secs}; }
791
797template <char... Digits>
798constexpr seconds operator""_s() noexcept {
799 return inner::__check_overflow<seconds, Digits...>();
800}
801
807constexpr duration<decimal_t, milli> operator""_ms(const decimal_t msecs) noexcept {
808 return duration<decimal_t, milli>{msecs};
809}
810
816template <char... Digits>
817constexpr milliseconds operator""_ms() noexcept {
818 return inner::__check_overflow<milliseconds, Digits...>();
819}
820
826constexpr duration<decimal_t, micro> operator""_us(const decimal_t usecs) noexcept {
827 return duration<decimal_t, micro>{usecs};
828}
829
835template <char... Digits>
836constexpr microseconds operator""_us() noexcept {
837 return inner::__check_overflow<microseconds, Digits...>();
838}
839
845constexpr duration<decimal_t, nano> operator""_ns(const decimal_t nsecs) noexcept {
846 return duration<decimal_t, nano>{nsecs};
847}
848
854template <char... Digits>
855constexpr nanoseconds operator""_ns() noexcept {
856 return inner::__check_overflow<nanoseconds, Digits...>();
857}
858 // UserLiterals
860
861NEFORCE_END_LITERALS__
862
864NEFORCE_BEGIN_INNER__
865
866void NEFORCE_API sleep_for_aux(ssize_t s, ssize_t ns);
867
868NEFORCE_END_INNER__
870
871NEFORCE_BEGIN_THIS_THREAD__
872
878
885template <typename Rep, typename Period>
887 if (time <= time.zero()) {
888 return;
889 }
890
891#ifdef NEFORCE_PLATFORM_WINDOWS
892 const nanoseconds ns = time.to_nano();
893 inner::sleep_for_aux(0, ns.count());
894#elif defined(NEFORCE_PLATFORM_LINUX)
895 const seconds s = time.to_sec();
896 const nanoseconds ns(time - s);
897 inner::sleep_for_aux(s.count(), ns.count());
898#endif
899}
900 // Thread
902
903NEFORCE_END_THIS_THREAD__
904
905NEFORCE_END_NAMESPACE__
906#endif // NEFORCE_CORE_TIME_DURATION_HPP__
static constexpr T lowest() noexcept
获取类型的最低值
static constexpr T max() noexcept
获取类型的最大值
时间类
constexpr bool is_floating_point_v
is_floating_point的便捷变量模板
long double decimal_t
扩展精度浮点数类型
constexpr iter_difference_t< Iterator > count(Iterator first, Iterator last, const T &value)
统计范围内等于指定值的元素数量
duration< int64_t, micro > microseconds
微秒持续时间
duration< int64_t, milli > milliseconds
毫秒持续时间
duration< int64_t, ratio< 86400 > > days
天持续时间
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)
大于比较运算符
duration< int64_t, ratio< 3600 > > hours
小时持续时间
constexpr duration< inner::__common_rep_t< Rep1, Rep2 >, Period > operator*(const duration< Rep1, Period > &value, const Rep2 &scalar)
乘法运算符(持续时间 * 标量)
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 bool operator>=(const duration< Rep1, Period1 > &lhs, const duration< Rep2, Period2 > &rhs)
大于等于比较运算符
constexpr bool is_duration_v
is_duration的便捷变量模板
constexpr bool operator==(const duration< Rep1, Period1 > &lhs, const duration< Rep2, Period2 > &rhs)
等于比较运算符
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 enable_if_t< is_duration_v< ToDur >, ToDur > floor(const duration< Rep, Period > &dur)
向下取整持续时间转换
constexpr common_type_t< duration< Rep1, Period1 >, duration< Rep2, Period2 > > 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)
取模运算符(持续时间 % 标量)
duration< int64_t, ratio< 604800 > > weeks
周持续时间
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 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
秒持续时间
constexpr T gcd(const T &m, const T &n) noexcept
计算最大公约数
int64_t intmax_t
最大有符号整数类型
int64_t ssize_t
有符号大小类型
constexpr bool is_ratio_v
is_ratio的便捷变量模板
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的便捷别名
数学函数库
比率计算
查找多个类型的公共类型
持续时间类模板
constexpr duration operator--(int)
后置自减运算符
constexpr duration & operator+=(const duration &dur)
加法赋值运算符
constexpr duration()=default
默认构造函数
constexpr duration operator++(int)
后置自增运算符
constexpr duration & operator--()
前置自减运算符
constexpr duration & operator%=(const duration &rhs)
持续时间取模赋值运算符
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 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
获取最大持续时间
检查是否为持续时间类型
比率类模板
根据前缀自动识别进制并解析整数
时间点类模板