1#ifndef NEFORCE_CORE_TIME_DURATION_HPP__
2#define NEFORCE_CORE_TIME_DURATION_HPP__
13NEFORCE_BEGIN_NAMESPACE__
15template <
typename Rep,
typename Period = ratio<1>>
18template <
typename Clock,
typename Dur>
34template <
typename CommonT,
typename Period1,
typename Period2,
typename Dummy =
void>
35struct __duration_common_type {};
37template <
typename CommonT,
typename Period1,
typename Period2>
38struct __duration_common_type<CommonT, Period1, Period2,
void_t<typename CommonT::type>> {
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>;
46 using type = duration<common_rep, typename result_ratio::type>;
52template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
54: inner::__duration_common_type<common_type<Rep1, Rep2>, typename Period1::type, typename Period2::type> {};
56template <
typename Rep,
typename Period>
58 using type = duration<common_type_t<Rep>,
typename Period::type>;
61template <
typename Rep,
typename Period>
63 using type = duration<common_type_t<Rep>,
typename Period::type>;
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)));
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()));
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)));
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)));
122template <
typename Rep,
typename Period>
143template <typename ToDur, typename Rep, typename Period, enable_if_t<is_duration<ToDur>::value,
int> = 0>
145 using to_period =
typename ToDur::period;
146 using to_rep =
typename ToDur::rep;
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);
175template <
typename Rep,
typename Period>
179 static_assert(Period::num > 0,
"period must be positive");
189 template <
typename R1,
typename R2,
intmax_t Gcd1 = _NEFORCE
gcd(R1::num, R2::num),
191 using divide =
ratio<(R1::num / Gcd1) * (R2::den / Gcd2), (R1::den / Gcd2) * (R2::num / Gcd1)>;
197 template <
typename Period2>
230 template <
typename Rep2,
typename = enable_if_t<is_convertible_v<const Rep2&, rep>>>
232 rep_(static_cast<
rep>(rep2)) {}
243 template <
typename Rep2,
typename Period2,
258 template <
typename Clock,
typename Dur,
typename Dummy = enable_if_t<is_duration_v<Dur>>>
266 NEFORCE_NODISCARD
constexpr rep count() const noexcept {
return rep_; }
360 template <
typename U = rep, enable_if_t<!is_
floating_po
int_v<U>,
int> = 0>
372 template <
typename U = rep, enable_if_t<!is_
floating_po
int_v<U>,
int> = 0>
406 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr duration<Rep> to_sec()
const {
437template <
typename Rep1,
typename Rep2,
typename CommonRep = common_type_t<Rep1, Rep2>>
454template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
460 return common_duration(common_duration(lhs).
count() + common_duration(rhs).
count());
473template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
479 return common_duration(common_duration(lhs).
count() - common_duration(rhs).
count());
491template <
typename Rep1,
typename Period,
typename Rep2>
493 const Rep2& scalar) {
495 return common_duration(common_duration(value).
count() * scalar);
507template <
typename Rep1,
typename Rep2,
typename Period>
510 return value * scalar;
522template <
typename Rep1,
typename Period,
typename Rep2>
526 return common_duration(common_duration(value).
count() / scalar);
539template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
544 return common_duration(lhs).count() / common_duration(rhs).count();
556template <
typename Rep1,
typename Period,
typename Rep2>
560 return common_duration(common_duration(value).
count() % scalar);
573template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
579 return common_duration(common_duration(lhs).
count() % common_duration(rhs).
count());
592template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
597 return common_duration(lhs).count() == common_duration(rhs).count();
610template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
612 return !(lhs == rhs);
625template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
630 return common_duration(lhs).count() < common_duration(rhs).count();
643template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
658template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
673template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
687template <
typename ToDur,
typename Rep,
typename Period>
691 return to - ToDur{1};
704template <
typename ToDur,
typename Rep,
typename Period>
708 return to + ToDur{1};
724template <
typename Dur,
char... Digits>
725constexpr Dur __check_overflow() noexcept {
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");
739NEFORCE_BEGIN_LITERALS__
761template <
char... Digits>
762constexpr hours operator""_h() noexcept {
763 return inner::__check_overflow<
hours, Digits...>();
780template <
char... Digits>
782 return inner::__check_overflow<
minutes, Digits...>();
797template <
char... Digits>
799 return inner::__check_overflow<
seconds, Digits...>();
816template <
char... Digits>
818 return inner::__check_overflow<
milliseconds, Digits...>();
835template <
char... Digits>
837 return inner::__check_overflow<
microseconds, Digits...>();
854template <
char... Digits>
856 return inner::__check_overflow<
nanoseconds, Digits...>();
861NEFORCE_END_LITERALS__
871NEFORCE_BEGIN_THIS_THREAD__
885template <
typename Rep,
typename Period>
891#ifdef NEFORCE_PLATFORM_WINDOWS
893 inner::sleep_for_aux(0, ns.
count());
894#elif defined(NEFORCE_PLATFORM_LINUX)
903NEFORCE_END_THIS_THREAD__
905NEFORCE_END_NAMESPACE__
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
计算最大公约数
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的类型
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
复制构造函数
typename Period::type period
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
获取最大持续时间
static constexpr bool value