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 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_ALWAYS_INLINE duration<Rep, nano> to_nano() const { return _NEFORCE time_cast<nanoseconds>(*this); }
398 NEFORCE_ALWAYS_INLINE duration<Rep, micro> to_micro() const { return _NEFORCE time_cast<microseconds>(*this); }
399 NEFORCE_ALWAYS_INLINE duration<Rep, milli> to_milli() const { return _NEFORCE time_cast<milliseconds>(*this); }
400 NEFORCE_ALWAYS_INLINE duration<Rep> to_sec() const { return _NEFORCE time_cast<seconds>(*this); }
401 NEFORCE_ALWAYS_INLINE duration<Rep, ratio<60>> to_minu() const { return _NEFORCE time_cast<minutes>(*this); }
402 NEFORCE_ALWAYS_INLINE duration<Rep, ratio<3600>> to_hour() const { return _NEFORCE time_cast<hours>(*this); }
403 NEFORCE_ALWAYS_INLINE duration<Rep, ratio<86400>> to_day() const { return _NEFORCE time_cast<days>(*this); }
404 NEFORCE_ALWAYS_INLINE duration<Rep, ratio<604800>> to_week() const { return _NEFORCE time_cast<weeks>(*this); }
405 NEFORCE_ALWAYS_INLINE duration<Rep, ratio<31556952>> to_year() const { return _NEFORCE time_cast<years>(*this); }
406 NEFORCE_ALWAYS_INLINE duration<Rep, ratio<2629746>> to_month() const { return _NEFORCE time_cast<months>(*this); }
407};
408
410NEFORCE_BEGIN_INNER__
411
417template <typename Rep1, typename Rep2, typename CommonRep = common_type_t<Rep1, Rep2>>
418using __common_rep_t = enable_if_t<is_convertible_v<const Rep2&, CommonRep>, CommonRep>;
419
420NEFORCE_END_INNER__
422
423
434template <typename Rep1, typename Period1, typename Rep2, typename Period2>
437 using duration1 = duration<Rep1, Period1>;
438 using duration2 = duration<Rep2, Period2>;
439 using common_duration = common_type_t<duration1, duration2>;
440 return common_duration(common_duration(lhs).count() + common_duration(rhs).count());
441}
442
453template <typename Rep1, typename Period1, typename Rep2, typename Period2>
456 using duration1 = duration<Rep1, Period1>;
457 using duration2 = duration<Rep2, Period2>;
458 using common_duration = common_type_t<duration1, duration2>;
459 return common_duration(common_duration(lhs).count() - common_duration(rhs).count());
460}
461
471template <typename Rep1, typename Period, typename Rep2>
473 const Rep2& scalar) {
474 using common_duration = duration<common_type_t<Rep1, Rep2>, Period>;
475 return common_duration(common_duration(value).count() * scalar);
476}
477
487template <typename Rep1, typename Rep2, typename Period>
488constexpr duration<inner::__common_rep_t<Rep2, Rep1>, Period> operator*(const Rep1& scalar,
489 const duration<Rep2, Period>& value) {
490 return value * scalar;
491}
492
502template <typename Rep1, typename Period, typename Rep2>
504operator/(const duration<Rep1, Period>& value, const Rep2& scalar) {
505 using common_duration = duration<common_type_t<Rep1, Rep2>, Period>;
506 return common_duration(common_duration(value).count() / scalar);
507}
508
519template <typename Rep1, typename Period1, typename Rep2, typename Period2>
521 using duration1 = duration<Rep1, Period1>;
522 using duration2 = duration<Rep2, Period2>;
523 using common_duration = common_type_t<duration1, duration2>;
524 return common_duration(lhs).count() / common_duration(rhs).count();
525}
526
536template <typename Rep1, typename Period, typename Rep2>
538operator%(const duration<Rep1, Period>& value, const Rep2& scalar) {
539 using common_duration = duration<common_type_t<Rep1, Rep2>, Period>;
540 return common_duration(common_duration(value).count() % scalar);
541}
542
553template <typename Rep1, typename Period1, typename Rep2, typename Period2>
556 using duration1 = duration<Rep1, Period1>;
557 using duration2 = duration<Rep2, Period2>;
558 using common_duration = common_type_t<duration1, duration2>;
559 return common_duration(common_duration(lhs).count() % common_duration(rhs).count());
560}
561
572template <typename Rep1, typename Period1, typename Rep2, typename Period2>
573constexpr bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
574 using duration1 = duration<Rep1, Period1>;
575 using duration2 = duration<Rep2, Period2>;
576 using common_duration = common_type_t<duration1, duration2>;
577 return common_duration(lhs).count() == common_duration(rhs).count();
578}
579
590template <typename Rep1, typename Period1, typename Rep2, typename Period2>
591constexpr bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
592 return !(lhs == rhs);
593}
594
605template <typename Rep1, typename Period1, typename Rep2, typename Period2>
606constexpr bool operator<(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
607 using duration1 = duration<Rep1, Period1>;
608 using duration2 = duration<Rep2, Period2>;
609 using common_duration = common_type_t<duration1, duration2>;
610 return common_duration(lhs).count() < common_duration(rhs).count();
611}
612
623template <typename Rep1, typename Period1, typename Rep2, typename Period2>
624constexpr bool operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
625 return !(rhs < lhs);
626}
627
638template <typename Rep1, typename Period1, typename Rep2, typename Period2>
639constexpr bool operator>(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
640 return rhs < lhs;
641}
642
653template <typename Rep1, typename Period1, typename Rep2, typename Period2>
654constexpr bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs) {
655 return !(lhs < rhs);
656}
657
658
667template <typename ToDur, typename Rep, typename Period>
668NEFORCE_NODISCARD constexpr enable_if_t<is_duration_v<ToDur>, ToDur> floor(const duration<Rep, Period>& dur) {
669 auto to = time_cast<ToDur>(dur);
670 if (to > dur) {
671 return to - ToDur{1};
672 }
673 return to;
674}
675
684template <typename ToDur, typename Rep, typename Period>
685NEFORCE_NODISCARD constexpr enable_if_t<is_duration_v<ToDur>, ToDur> ceil(const duration<Rep, Period>& dur) {
686 auto to = time_cast<ToDur>(dur);
687 if (to < dur) {
688 return to + ToDur{1};
689 }
690 return to;
691}
692 // Duration
694
696NEFORCE_BEGIN_INNER__
697
704template <typename Dur, char... Digits>
705constexpr Dur __check_overflow() noexcept {
706 using value_type = static_parse_int<Digits...>;
707 constexpr typename Dur::rep rep = value_type::value;
708 static_assert(rep >= 0 && rep == value_type::value, "literal value cannot be represented by duration type");
709 return Dur(rep);
710}
711
712NEFORCE_END_INNER__
714
719NEFORCE_BEGIN_LITERALS__
720
726
732constexpr duration<decimal_t, ratio<3600, 1>> operator""_h(const decimal_t hours) noexcept {
734}
735
741template <char... Digits>
742constexpr hours operator""_h() noexcept {
743 return inner::__check_overflow<hours, Digits...>();
744}
745
751constexpr duration<decimal_t, ratio<60, 1>> operator""_min(const decimal_t mins) noexcept {
753}
754
760template <char... Digits>
761constexpr minutes operator""_min() noexcept {
762 return inner::__check_overflow<minutes, Digits...>();
763}
764
770constexpr duration<decimal_t> operator""_s(const decimal_t secs) noexcept { return duration<decimal_t>{secs}; }
771
777template <char... Digits>
778constexpr seconds operator""_s() noexcept {
779 return inner::__check_overflow<seconds, Digits...>();
780}
781
787constexpr duration<decimal_t, milli> operator""_ms(const decimal_t msecs) noexcept {
788 return duration<decimal_t, milli>{msecs};
789}
790
796template <char... Digits>
797constexpr milliseconds operator""_ms() noexcept {
798 return inner::__check_overflow<milliseconds, Digits...>();
799}
800
806constexpr duration<decimal_t, micro> operator""_us(const decimal_t usecs) noexcept {
807 return duration<decimal_t, micro>{usecs};
808}
809
815template <char... Digits>
816constexpr microseconds operator""_us() noexcept {
817 return inner::__check_overflow<microseconds, Digits...>();
818}
819
825constexpr duration<decimal_t, nano> operator""_ns(const decimal_t nsecs) noexcept {
826 return duration<decimal_t, nano>{nsecs};
827}
828
834template <char... Digits>
835constexpr nanoseconds operator""_ns() noexcept {
836 return inner::__check_overflow<nanoseconds, Digits...>();
837}
838 // UserLiterals
840
841NEFORCE_END_LITERALS__
842
844NEFORCE_BEGIN_INNER__
845
846void NEFORCE_API sleep_for_aux(ssize_t s, ssize_t ns);
847
848NEFORCE_END_INNER__
850
851NEFORCE_BEGIN_THIS_THREAD__
852
858
865template <typename Rep, typename Period>
867 if (time <= time.zero()) {
868 return;
869 }
870
871#ifdef NEFORCE_PLATFORM_WINDOWS
872 const nanoseconds ns = time.to_nano();
873 inner::sleep_for_aux(0, ns.count());
874#elif defined(NEFORCE_PLATFORM_LINUX)
875 const seconds s = time.to_sec();
876 const nanoseconds ns(time - s);
877 inner::sleep_for_aux(s.count(), ns.count());
878#endif
879}
880 // Thread
882
883NEFORCE_END_THIS_THREAD__
884
885NEFORCE_END_NAMESPACE__
886#endif // NEFORCE_CORE_TIME_DURATION_HPP__
static NEFORCE_NODISCARD constexpr T max() noexcept
获取类型的最大值
static NEFORCE_NODISCARD constexpr T lowest() noexcept
获取类型的最低值
时间类
NEFORCE_INLINE17 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 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)
不等于比较运算符
NEFORCE_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 bool operator==(const duration< Rep1, Period1 > &lhs, const duration< Rep2, Period2 > &rhs)
等于比较运算符
NEFORCE_NODISCARD constexpr enable_if_t< is_duration_v< ToDur >, ToDur > ceil(const duration< Rep, Period > &dur)
向上取整持续时间转换
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)
加法运算符
NEFORCE_INLINE17 constexpr bool is_duration_v
is_duration的便捷变量模板
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
秒持续时间
NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14 T gcd(const T &m, const T &n) noexcept
计算最大公约数
int64_t intmax_t
最大有符号整数类型
int64_t ssize_t
有符号大小类型
NEFORCE_INLINE17 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的便捷别名
NEFORCE_ALWAYS_INLINE 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 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
获取最大持续时间
检查是否为持续时间类型
比率类模板
根据前缀自动识别进制并解析整数
时间点类模板