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 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>
417template <
typename Rep1,
typename Rep2,
typename CommonRep = common_type_t<Rep1, Rep2>>
434template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
440 return common_duration(common_duration(lhs).
count() + common_duration(rhs).
count());
453template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
459 return common_duration(common_duration(lhs).
count() - common_duration(rhs).
count());
471template <
typename Rep1,
typename Period,
typename Rep2>
473 const Rep2& scalar) {
475 return common_duration(common_duration(value).
count() * scalar);
487template <
typename Rep1,
typename Rep2,
typename Period>
490 return value * scalar;
502template <
typename Rep1,
typename Period,
typename Rep2>
506 return common_duration(common_duration(value).
count() / scalar);
519template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
524 return common_duration(lhs).count() / common_duration(rhs).count();
536template <
typename Rep1,
typename Period,
typename Rep2>
540 return common_duration(common_duration(value).
count() % scalar);
553template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
559 return common_duration(common_duration(lhs).
count() % common_duration(rhs).
count());
572template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
577 return common_duration(lhs).count() == common_duration(rhs).count();
590template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
592 return !(lhs == rhs);
605template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
610 return common_duration(lhs).count() < common_duration(rhs).count();
623template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
638template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
653template <
typename Rep1,
typename Period1,
typename Rep2,
typename Period2>
667template <
typename ToDur,
typename Rep,
typename Period>
671 return to - ToDur{1};
684template <
typename ToDur,
typename Rep,
typename Period>
688 return to + ToDur{1};
704template <
typename Dur,
char... Digits>
705constexpr Dur __check_overflow() noexcept {
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");
719NEFORCE_BEGIN_LITERALS__
741template <
char... Digits>
742constexpr hours operator""_h() noexcept {
743 return inner::__check_overflow<
hours, Digits...>();
760template <
char... Digits>
762 return inner::__check_overflow<
minutes, Digits...>();
777template <
char... Digits>
779 return inner::__check_overflow<
seconds, Digits...>();
796template <
char... Digits>
798 return inner::__check_overflow<
milliseconds, Digits...>();
815template <
char... Digits>
817 return inner::__check_overflow<
microseconds, Digits...>();
834template <
char... Digits>
836 return inner::__check_overflow<
nanoseconds, Digits...>();
841NEFORCE_END_LITERALS__
851NEFORCE_BEGIN_THIS_THREAD__
865template <
typename Rep,
typename Period>
871#ifdef NEFORCE_PLATFORM_WINDOWS
873 inner::sleep_for_aux(0, ns.
count());
874#elif defined(NEFORCE_PLATFORM_LINUX)
883NEFORCE_END_THIS_THREAD__
885NEFORCE_END_NAMESPACE__
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
计算最大公约数
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的类型
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