(22) 本头文件的定义的内容概览,以便查阅,先是 std 标准 命名空间里的内容:
++ 上面的 std { … } 命名空间里漏掉了一个重要的基础的全局函数,因为对 vs2019 还不是很熟悉其功能,单独列出如下:
++ 接着 给出 chrono 时间命名空间里的内容:
(23) 至此,给出本头文件的源码注释 ,总共 900 行左右:
// __msvc_chrono.hpp internal header
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// __msvc_chrono.hpp 此源文件
#pragma once
#ifndef __MSVC_CHRONO_HPP
#define __MSVC_CHRONO_HPP
#include <yvals.h>
#if _STL_COMPILER_PREPROCESSOR
#include <ctime>
#include <limits>
#include <ratio>
#include <type_traits>
#include <utility>
#include <xtimec.h>
#if _HAS_CXX20
#include <compare>
#endif
#pragma pack(push, _CRT_PACKING)
// 以下的结构体以及 union 将采用 8 字节对齐。入栈原来的对齐方式 _CRT_PACKING = 8
#pragma warning(push, _STL_WARNING_LEVEL)
//调整本源文件编译时候的警告级别,是较减少了警告。 _STL_WARNING_LEVEL = 3
// 0 不警告,4 全警告。并把原来的警告级别入栈
#pragma warning(disable : _STL_DISABLED_WARNINGS)
//#define _STL_DISABLED_WARNINGS 4180 4412 4455 4494 4514 4574 ......
// 表示禁用这些警告,忽略这些警告 <yvals_core.h>
_STL_DISABLE_CLANG_WARNINGS
// 按字面意思,禁止 clang 警告,最后还有对应的 宏定义,_STL_RESTORE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new
// 入栈系统之前的 new 的宏定义,并取消此宏定义。可能要自己定义内存管理方式
_STD_BEGIN
// #define _STD_BEGIN namespace std { 表示以下内容全部定义于 std 命名空间
namespace chrono
{
/*
template <bool _First_value, class _First, class... _Rest> // handle true trait or last trait
struct _Disjunction { using type = _First; }; //当模板参数只有一个类型时,才选择此泛型类
template <class _False, class _Next, class... _Rest> // first trait is false, try the next trait
struct _Disjunction<false, _False, _Next, _Rest...> {
using type = typename _Disjunction<_Next::value, _Next, _Rest...>::type;
};
//-----------------------------------------------------------------------
template <class... _Traits> 模板的泛型与特化,此泛型只对应 0 模板参数的情形 template<> disjunction {};
struct disjunction : false_type {}; // If _Traits is empty, false_type
template <class _First, class... _Rest> // 只要一个为真即可,全为 F 才返回 false
struct disjunction<_First, _Rest...> : _Disjunction<_First::value, _First, _Rest...>::type { };
//----------------------------------------------------------------------
template <class... _Traits>
bool disjunction_v = disjunction<_Traits...>::value;
template <class _Ty, class... _Types> // true if and only if _Ty is in _Types
bool _Is_any_of_v = disjunction_v< is_same<_Ty, _Types>... >;
template <class _Ty>
bool is_floating_point_v = _Is_any_of_v< remove_cv_t<_Ty>, float, double, long double >;
template <class _Ty>
struct is_floating_point : bool_constant<is_floating_point_v<_Ty>> {};
*/
template <class _Rep> // 测试一个类型是否是浮点类型之一:float、double、long double,是则返回 true
struct treat_as_floating_point : is_floating_point<_Rep> {}; // tests for floating-point type
template <class _Rep> // 布尔量
bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value;
//****************************************************************************************
template <class _Rep> // gets arithmetic properties of a type
struct duration_values // 获取类型的算术属性
{ // get zero value // 返回 _Rep 数据类型的 0 值,最小值,最大值
static _Rep zero() { return _Rep(0); }
/*
template <> // 举例,这是对 short 类型的特化版本
class numeric_limits<short> : public _Num_int_base {
public:
static short min() { return SHRT_MIN; } // 宏定义 SHRT_MIN = -32768
static short max() { return SHRT_MAX; } // 宏定义 SHRT_MAX = 32767
static short lowest() { return (min)(); }
};
*/
static _Rep min() { return numeric_limits<_Rep>::lowest(); } // get smallest value
static _Rep max() { return (numeric_limits<_Rep>::max)(); } // get largest value
};
//********************************************************************************************
#if _HAS_CXX20
template <class _Clock, class = void> // 模板变量的泛化与特化版本
bool _Is_clock_v = false; // 此模板变量名带有前置下划线
/*
template <class... _Types>
using void_t = void;
// 标准库中有三种时钟,system_clock,steady_clock 和 high_resolution_clock
struct system_clock
{
using rep = long long; // sizeof( long long ) = 8 字节
using period = ratio<1, 10'000'000>; // 100 nanoseconds = 100 纳秒
using duration = _CHRONO duration<rep, period>; // _CHRONO = ::std::chrono::
using time_point = _CHRONO time_point<system_clock>;
static constexpr bool is_steady = false;
static time_point now () {.....}
}
struct steady_clock // wraps QueryPerformanceCounter
{
using rep = long long;
using period = nano; // using nano = ratio<1, 1000000000>; 可见精度更高,纳秒
using duration = nanoseconds; // using nanoseconds = duration<long long, nano>;
using time_point = _CHRONO time_point<steady_clock>;
static constexpr bool is_steady = true;
static time_point now () {.....}
}
using high_resolution_clock = steady_clock; // 和时钟类 steady_clock 是等价的(是它的别名)。
*/
template <class _Clock> // 不存在 void_t<> ,本例中已有 6 个参数,若某个类型参数推断不出来,
bool _Is_clock_v< _Clock , void_t< typename _Clock::rep, // 据 sfinae原则,不是语法错误
typename _Clock::period, typename _Clock::duration, typename _Clock::time_point,
decltype(_Clock::is_steady), decltype( _Clock::now() ) >
> = true;
template <class _Clock>
struct is_clock : bool_constant<_Is_clock_v<_Clock>> {};
template <class _Clock> // 此模板变量去掉了前置的 下划线 "_"
bool is_clock_v = _Is_clock_v<_Clock>;
#endif // _HAS_CXX20
//**********************************************************************************
// template <intmax_t _Nx, intmax_t _Dx = 1> // 默认分母为一
// struct ratio {};
template < class _Rep, class _Period = ratio<1> >
class duration;
template <class _Ty> // 测试 _Ty 是否是 duration 模板的子类
constexpr bool _Is_duration_v = _Is_specialization_v<_Ty, duration>;
template <class _To, class _Rep, class _Period, enable_if_t<_Is_duration_v<_To>, int> = 0>
constexpr _To duration_cast( const duration<_Rep, _Period>& ) // 这是一个类型转换函数
noexcept( is_arithmetic_v<_Rep>&& is_arithmetic_v<typename _To::rep>); // strengthened
template <class _Rep, class _Period> // represents a time duration 代表一个时间持续时间
class duration
{
private:
_Rep _MyRep; // the stored rep
public:
using rep = _Rep; // 去掉了前置的下划线
using period = typename _Period::type; //= ratio<num, den>
// template <intmax_t _Nx, intmax_t _Dx = 1> // numerator 分子,被除数 ; denominator 分母
// struct ratio { using type = ratio<num, den>; }; // 这个 type 保存了简化版的比率
static_assert(!_Is_duration_v<_Rep>, "duration can't have duration as first template argument");
static_assert(_Is_ratio_v<_Period>, "period not an instance of std::ratio");
static_assert(0 < _Period::num, "period negative or zero"); // 时间只能往将来
// 默认构造函数
constexpr duration() = default;
/*
template <bool _Test, class _Ty = void> // no member "type" when !_Test
struct enable_if {};
template <class _Ty> // type is _Ty for _Test
struct enable_if<true, _Ty> { using type = _Ty; };
template <bool _Test, class _Ty = void>
using enable_if_t = typename enable_if<_Test, _Ty>::type;
//----------------------------------------------------------------------
template <class _From, class _To> // 注意到类型转换的方向即可
bool is_convertible_v = __is_convertible_to(_From, _To);
// 模板 treat_as_floating_point_v 的定义在本文件上面
//--------------------------------------------------------------------------
template <class _Ty>
bool is_integral_v = _Is_any_of_v<remove_cv_t<_Ty>, bool, char, signed char, unsigned char,
short, unsigned short, int, unsigned int, long, unsigned long, long long, unsigned long long>;
template <class _Ty>
bool is_floating_point_v = _Is_any_of_v<remove_cv_t<_Ty>, float, double, long double>;
template <class _Ty> // determine whether _Ty is an arithmetic type
bool is_arithmetic_v = is_integral_v<_Ty> || is_floating_point_v<_Ty>;
*/
template <class _Rep2, enable_if_t< // 把 _Rep2 类型的变量转换为 _Rep 类型存入类的数据成员
is_convertible_v<const _Rep2& , _Rep> &&
(treat_as_floating_point_v<_Rep> || !treat_as_floating_point_v<_Rep2>)
, int > = 0 >
constexpr explicit duration(const _Rep2& _Val) // 有参构造函数
noexcept( is_arithmetic_v<_Rep> && is_arithmetic_v<_Rep2>) // strengthened
: _MyRep(static_cast<_Rep>(_Val)) {}
// #define _CHRONO ::std::chrono::
// 此处 enable_if_t 的意思是,希望本类的数值是浮点类型;
// 若都是整数类型,则希望形参的 _Period2 可以更大,可以被本 duration 的计量周期整除。
template <class _Rep2, class _Period2, enable_if_t<
treat_as_floating_point_v< _Rep > || // 或,看来更喜欢本类的模板参数是浮点类型,数值范围更大
(_Ratio_divide_sfinae<_Period2, _Period>::den == 1 && !treat_as_floating_point_v<_Rep2> )
, int > = 0 >
constexpr duration(const duration<_Rep2, _Period2>& _Dur) // copy 构造函数
noexcept( is_arithmetic_v<_Rep> && is_arithmetic_v<_Rep2>)
: _MyRep(_CHRONO duration_cast<duration>(_Dur).count()) {}
// 返回存储的本类的数据成员
constexpr _Rep count() const noexcept(is_arithmetic_v<_Rep>) { return _MyRep; }
// 以下的成员函数,省略 constexpr 与 is_arithmetic_v<_Rep> 的判断,突出重点。
// 经测试,复杂的泛型推导,简单的结果:
// common_type_t< duration<int> > = duration<int>
// 取正与取负运算符: duration<int> a ; b = +a ; c = -a ; 就是此运算符函数
common_type_t<duration> operator+() { return common_type_t<duration>(*this); }
/*
template <class _Ty1, class _Ty2> // _STD declval<P>() 返回 P 类型对象的引用
using _Conditional_type = decltype(false ? _STD declval<_Ty1>() : _STD declval<_Ty2>());
//----------------------------------------------------------------------------------------
template <class _Ty1, class _Ty2, class = void> // 对 _Const_lvalue_cond_oper<...> 的展开,略
struct _Decayed_cond_oper : _Const_lvalue_cond_oper<_Ty1, _Ty2> {};
template <class _Ty1, class _Ty2> // 若 void_t<M> 有意义,则 type = decay_t<M> 就这个意思
struct _Decayed_cond_oper< _Ty1, _Ty2, void_t< _Conditional_type<_Ty1, _Ty2> > >
{ using type = decay_t<_Conditional_type<_Ty1, _Ty2>>; };
//--------------------------------------------------------------------------------------
template <class _Ty1, class _Ty2, class _Decayed1 = decay_t<_Ty1>, class _Decayed2 = decay_t<_Ty2>>
struct _Common_type2 : common_type<_Decayed1, _Decayed2> {};
template <class _Ty1, class _Ty2> // 若 _Ty1, _Ty2 都已经是最简情况,用此版本
struct _Common_type2<_Ty1, _Ty2, _Ty1, _Ty2> : _Decayed_cond_oper<_Ty1, _Ty2> {};
template <class _Ty1, class _Ty2>
struct common_type<_Ty1, _Ty2> : _Common_type2<_Ty1, _Ty2> {};
template <class _Ty1>
struct common_type<_Ty1> : common_type<_Ty1, _Ty1> {};
template <>
struct common_type<> {};
template <class... _Ty>
struct common_type;
template <class... _Ty> // 这里是简化版的定义,模板参数只有两个,不考虑模板参数更多的情况
using common_type_t = typename common_type<_Ty...>::type;
*/
common_type_t<duration> operator-() { return common_type_t<duration>(-_MyRep); }
duration& operator ++ () { ++_MyRep ; return *this ; } // ++a
duration& operator -- () { --_MyRep; return *this; } // --a
duration operator ++ (int) { return duration(_MyRep++); } // a++
duration operator -- (int) { return duration(_MyRep--); } // a--
duration& operator += (const duration& _Right) { _MyRep += _Right._MyRep; return *this; }
duration& operator -= (const duration& _Right) { _MyRep -= _Right._MyRep; return *this; }
duration& operator *= (const _Rep& _Right) { _MyRep *= _Right; return *this; }
duration& operator /= (const _Rep& _Right) { _MyRep /= _Right; return *this; }
duration& operator %= (const _Rep& _Right) { _MyRep %= _Right; return *this; }
duration& operator %= (const duration& _Right) { _MyRep %= _Right.count();return *this; }
static duration zero() { return duration( duration_values<_Rep>::zero() ); } // get zero value
static duration min () { return duration( duration_values<_Rep>::min() ) ; } // get minimum value
static duration max () { return duration( duration_values<_Rep>::max() ) ; } // get maximum value
};
//********************************************************************************************************
// 第一个模板参数Clock用来指定所要使用的时钟,
// 标准库中有三种时钟,system_clock,steady_clock 和 high_resolution_clock 。
// 看定义可知,只需要指定模板类的模板参数一,第二个参数不指定的话就默认采用形参一里的计时单位
template <class _Clock, class _Duration = typename _Clock::duration>
class time_point // represents a point in time
{
private: // 先对数据成员初始化为 0
_Duration _MyDur{ duration::zero() }; // duration since the epoch 纪元以来持续的时间
public:
using clock = _Clock; // 类型定义,去掉了模板形参类名的前置下划线 _
using duration = _Duration; // 类型定义,去掉了模板形参类名的前置下划线 _
using rep = typename _Duration::rep;
using period = typename _Duration::period;
// template <class _Ty> // 测试 _Ty 是否是 duration 模板的子类
// constexpr bool _Is_duration_v = _Is_specialization_v<_Ty, duration>;
static_assert(_Is_duration_v<_Duration>, // N4885 [time.point.general]/1授权 Duration为chrono::duration 的具体化。
"N4885 [time.point.general]/1 mandates Duration to be a specialization of chrono::duration.");
constexpr time_point() = default; // 默认的空的构造函数
// 以下开始省略多余的函数修饰符,突出重点
explicit time_point(const _Duration& _Other) : _MyDur(_Other) {} // 带参的构造函数
template <class _Duration2, enable_if_t<is_convertible_v<_Duration2, _Duration>, int> = 0>
time_point(const time_point<_Clock, _Duration2>& _Tp) // copy 构造函数
noexcept( is_arithmetic_v<rep> && is_arithmetic_v<typename _Duration2::rep>) // strengthened
: _MyDur(_Tp.time_since_epoch()) {}
_Duration time_since_epoch() { return _MyDur; } // 纪元,返回自己的数据成员的值
#if _HAS_CXX20
time_point& operator ++ () { ++_MyDur; return *this; } // ++a
time_point& operator -- () { --_MyDur; return *this; } // --a
time_point operator ++ (int) { return time_point{ _MyDur++ }; } // a++
time_point operator -- (int) { return time_point{ _MyDur-- }; } // a--
#endif // _HAS_CXX20
time_point& operator += (const _Duration& _Dur) { _MyDur += _Dur; return *this; }
time_point& operator -= (const _Duration& _Dur) { _MyDur -= _Dur; return *this; }
static time_point min() { return time_point( _Duration::min() ); }
static time_point max() { return time_point( _Duration::max() ); }
};
} // namespace chrono
//***************************************************************************************************
// template <class _Ty> // conj 参数全为 true 才为 true
// bool _Is_trivially_swappable_v = conjunction_v<is_trivially_destructible<_Ty>,
// is_trivially_move_constructible<_Ty>, is_trivially_move_assignable<_Ty>, negation<_Has_ADL_swap<_Ty>>>;
template <class _Rep, class _Period> // trivially 平凡地 验证数据的交换性能
constexpr bool _Is_trivially_swappable_v< chrono::duration<_Rep, _Period> > = _Is_trivially_swappable_v<_Rep>;
// 举例 _Is_trivially_swappable_v<int> = 1
template <class _Clock, class _Duration> // 模板的特化
constexpr bool _Is_trivially_swappable_v< chrono::time_point<_Clock, _Duration> >
= _Is_trivially_swappable_v<_Duration>;
//******************************************************************************************************
template < intmax_t _Ax, intmax_t _Bx, bool=( (_Ax / _Gcd<_Ax, _Bx>::value) <= INTMAX_MAX / _Bx ) >
struct _Lcm : integral_constant<intmax_t, (_Ax / _Gcd<_Ax, _Bx>::value) * _Bx> {};
template <intmax_t _Ax, intmax_t _Bx> // 模板类的泛化与特化
struct _Lcm<_Ax, _Bx, false> {}; // _Lcm 是最小公倍数 Least Common Multiple, LCM
// 宏定义 _CHRONO = ::std::chrono::
template <class _Rep1, class _Period1, class _Rep2, class _Period2>
struct common_type<_CHRONO duration<_Rep1, _Period1>, _CHRONO duration<_Rep2, _Period2>>
{ // 这个类的意思应该是找到两种计时单位里的共同的单位,好像是为了完成单位转换。新的计时单位更小了
using type = _CHRONO duration<common_type_t<_Rep1, _Rep2>,
ratio<_Gcd<_Period1::num, _Period2::num>::value, _Lcm<_Period1::den, _Period2::den>::value>
>;
};
template <class _Clock, class _Duration1, class _Duration2> // common type of two time points
struct common_type<_CHRONO time_point<_Clock, _Duration1>, _CHRONO time_point<_Clock, _Duration2>>
{
using type = _CHRONO time_point<_Clock, common_type_t<_Duration1, _Duration2>>;
};
//*************************************************************************************************
namespace chrono
{
template <class _Rep1, class _Period1, class _Rep2, class _Period2> // 时间值的加法运算
constexpr common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>> // 本行是函数返回值
operator + (const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right)
noexcept( is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>)
{
using _CD = common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>>;
return _CD(_CD(_Left).count() + _CD(_Right).count()); // 返回新的时间值
}
// 以下开始简写函数,去掉一些函数的修饰符,突出重点
template <class _Rep1, class _Period1, class _Rep2, class _Period2> // 时间值的减法运算
common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>> // 函数返回值
operator - (const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right)
{
using _CD = common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>>;
return _CD(_CD(_Left).count() - _CD(_Right).count()); // 左 - 右
}
template <class _Rep1, class _Period1, class _Rep2, enable_if_t< // 时间值的乘法运算
is_convertible_v<const _Rep2&, common_type_t<_Rep1, _Rep2> >, int > = 0>
duration<common_type_t<_Rep1, _Rep2>, _Period1>
operator * ( const duration<_Rep1, _Period1>& _Left, const _Rep2& _Right)
{
using _CR = common_type_t<_Rep1, _Rep2>;
using _CD = duration<_CR, _Period1>;
return _CD(_CD(_Left).count() * _Right);
}
template <class _Rep1, class _Rep2, class _Period2, enable_if_t< // 时间值的乘法运算
is_convertible_v<const _Rep1&, common_type_t<_Rep1, _Rep2>>, int> = 0>
duration<common_type_t<_Rep1, _Rep2>, _Period2>
operator * (const _Rep1& _Left, const duration<_Rep2, _Period2>& _Right)
{
return _Right * _Left; // 借助上面的函数定义,完成本函数的定义
}
//**************************************************************************************
// return type for duration / rep and duration % rep
template <class _CR, class _Period1, class _Rep2, bool = is_convertible_v<const _Rep2&, _CR>>
struct _Duration_div_mod1
{ // 可见,本模板是为了处理除法运算的返回值问题,定义了新类型
using type = duration<_CR, _Period1>;
};
template <class _CR, class _Period1, class _Rep2>
struct _Duration_div_mod1<_CR, _Period1, _Rep2, false> {}; // no return type
//------------------------------上下各是一组模板类的泛化与特化
template <class _CR, class _Period1, class _Rep2, bool = _Is_duration_v<_Rep2>>
struct _Duration_div_mod {}; // no return type。_Rep2 是 duration 的子类则为真
// return type for duration / rep and duration % rep
template <class _CR, class _Period1, class _Rep2>
struct _Duration_div_mod<_CR, _Period1, _Rep2, false> : _Duration_div_mod1<_CR, _Period1, _Rep2> { };
//**********************************************************************************************
template <class _Rep1, class _Period1, class _Rep2> // 时间值的除法运算,存在函数的重载
typename _Duration_div_mod<common_type_t<_Rep1, _Rep2>, _Period1, _Rep2>::type // 函数返回值
operator / ( const duration<_Rep1, _Period1>& _Left, const _Rep2& _Right)
{
using _CR = common_type_t<_Rep1, _Rep2>;
using _CD = duration<_CR, _Period1>;
return _CD(_CD(_Left).count() / _Right); // 整数除法
}
template <class _Rep1, class _Period1, class _Rep2, class _Period2> // 时间值的除法运算
common_type_t<_Rep1, _Rep2> // 函数返回值
operator / (const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right)
{
using _CD = common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>>;
return _CD(_Left).count() / _CD(_Right).count();
}
template <class _Rep1, class _Period1, class _Rep2> // 时间值的取余数、求模运算
typename _Duration_div_mod<common_type_t<_Rep1, _Rep2>, _Period1, _Rep2>::type // 函数返回值
operator % ( const duration<_Rep1, _Period1>& _Left, const _Rep2& _Right)
{
using _CR = common_type_t<_Rep1, _Rep2>;
using _CD = duration<_CR, _Period1>;
return _CD(_CD(_Left).count() % _Right);
}
template <class _Rep1, class _Period1, class _Rep2, class _Period2> // 时间值的取余数、求模运算
common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>> // 函数返回值
operator % (const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right)
{
using _CD = common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>>;
return _CD(_CD(_Left).count() % _CD(_Right).count());
}
//********************************************************************************************
template <class _Rep1, class _Period1, class _Rep2, class _Period2> // 时间值的相等比较 ==
bool operator == (const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right)
{
using _CT = common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>>;
return _CT(_Left).count() == _CT(_Right).count();
}
template <class _Rep1, class _Period1, class _Rep2, class _Period2> // 时间值的小于比较 <
bool operator < (const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right)
{
using _CT = common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>>;
return _CT(_Left).count() < _CT(_Right).count();
}
template <class _Rep1, class _Period1, class _Rep2, class _Period2> // 时间值的小于等于比较 <=
bool operator <= (const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right)
{
return !(_Right < _Left); // 借助 小于 < 比较的函数实现,实现本函数
}
template <class _Rep1, class _Period1, class _Rep2, class _Period2> // 时间值的大于比较 >
bool operator > ( const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right)
{
return _Right < _Left;
}
template <class _Rep1, class _Period1, class _Rep2, class _Period2> // 时间值的大于等于比较 >=
bool operator >= (const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right)
{
return !(_Left < _Right); // 借助 小于 < 比较的函数实现,实现本函数
}
#ifdef __cpp_lib_concepts
// clang-format off 实现的是运算符 operator<=> 略
template <class _Rep1, class _Period1, class _Rep2, class _Period2>
requires three_way_comparable<typename common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>>::rep>
_NODISCARD constexpr auto
operator<=>(const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) noexcept(
is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ {
// clang-format on
using _CT = common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>>;
return _CT(_Left).count() <=> _CT(_Right).count();
}
#endif // defined(__cpp_lib_concepts)
//********************************************************************************************
// 函数的模板参数,作为函数的返回值类型,那么就不可以省略模板函数的模板参数
// convert duration to another duration; truncate 将持续时间转换为另一个持续时间;截断
template <class _To, class _Rep, class _Period, enable_if_t<_Is_duration_v<_To>, int> _Enabled>
_NODISCARD constexpr _To duration_cast (const duration<_Rep, _Period>& _Dur) // 时间值的单位转换
{
using _CF = ratio_divide<_Period, typename _To::period>; // 分数除法 _CF 保存了左/右的结果
using _ToRep = typename _To::rep;
using _CR = common_type_t<_ToRep, _Rep, intmax_t>;
constexpr bool _Num_is_one = _CF::num == 1; // 最简单的单位转换,就是单位一样,true 时最简单
constexpr bool _Den_is_one = _CF::den == 1;
if (_Den_is_one) // 分母为 1 ,计时单位变小了
{
if (_Num_is_one) // ++++++*******+++++++这是最简单的情形
return static_cast<_To>(static_cast<_ToRep>(_Dur.count()));
else {
return static_cast<_To>( // 计时单位变小,数值变大,用乘法
static_cast<_ToRep>(static_cast<_CR>(_Dur.count()) * static_cast<_CR>(_CF::num)));
}
}
else // 分母不为 1 ,可能计时单位变大了
{
if (_Num_is_one) { // 分子为 1
return static_cast<_To>( // 计时单位变大,数值就要变小
static_cast<_ToRep>(static_cast<_CR>(_Dur.count()) / static_cast<_CR>(_CF::den)));
}
else {
return static_cast<_To>(static_cast<_ToRep>(
static_cast<_CR>(_Dur.count()) * static_cast<_CR>(_CF::num) / static_cast<_CR>(_CF::den)));
}
}
}
// 将持续时间转换为另一个持续时间;向负无穷大转动,即最大整数结果,使结果 <= _Dur
// convert duration to another duration; round towards negative infinity
// i.e. the greatest integral result such that the result <= _Dur
template <class _To, class _Rep, class _Period, enable_if_t<_Is_duration_v<_To>, int> = 0>
_To floor (const duration<_Rep, _Period>& _Dur) // 向下取整的转换
{
const _To _Casted{ _CHRONO duration_cast<_To>(_Dur) }; // 调用上面的基本转换函数
if (_Casted > _Dur) // floor 都是这个语义的
return _To{ _Casted.count() - static_cast<typename _To::rep>(1) };
return _Casted;
}
// 将持续时间转换为另一个持续时间;朝着正无穷大的方向旋转,即最小整数 结果,使得 _Dur<=结果
// convert duration to another duration; round towards positive infinity
// i.e. the least integral result such that _Dur <= the result
template <class _To, class _Rep, class _Period, enable_if_t<_Is_duration_v<_To>, int> = 0>
_To ceil(const duration<_Rep, _Period>& _Dur) // ceil 天花板,转换并向上取整
{
const _To _Casted{ _CHRONO duration_cast<_To>(_Dur) };
if (_Casted < _Dur)
return _To{ _Casted.count() + static_cast<typename _To::rep>(1) };
return _Casted;
}
template <class _Rep> // Tests whether _Val is even 测试参数是否是偶数,是则为真
bool _Is_even(_Rep _Val) { return _Val % 2 == 0; }
// 将持续时间转换为另一个持续时间,圆到最近,绑定到偶数,四舍五入
// convert duration to another duration, round to nearest, ties to even
template <class _To, class _Rep, class _Period, enable_if_t<
_Is_duration_v<_To> && !treat_as_floating_point_v<typename _To::rep>, int> = 0 >
_To round (const duration<_Rep, _Period>& _Dur) // 四舍五入,0.5则向最近的偶数取整
{
const _To _Floored { _CHRONO floor<_To>(_Dur) };
const _To _Ceiled { _Floored + _To{1} };
const auto _Floor_adjustment = _Dur - _Floored;
const auto _Ceil_adjustment = _Ceiled - _Dur;
if ( _Floor_adjustment < _Ceil_adjustment || // 四舍五入
(_Floor_adjustment == _Ceil_adjustment && _Is_even(_Floored.count())) )
{
return _Floored;
}
return _Ceiled;
}
// create a duration with count() the absolute value of _Dur.count()
// 使用count ()创建一个持续时间,该持续时间是Dur.count()的绝对值
// 举例 static numeric_limits<short> . is_signed = true;
template <class _Rep, class _Period, enable_if_t<numeric_limits<_Rep>::is_signed, int> = 0>
duration<_Rep, _Period> abs (const duration<_Rep, _Period> _Dur) // 时间值的绝对值转换
{
return _Dur < duration<_Rep, _Period>::zero() ? duration<_Rep, _Period>::zero() - _Dur : _Dur;
}
//***********************************************************************************************
using nanoseconds = duration<long long, nano>;
/*
template <intmax_t _Nx, intmax_t _Dx = 1> // 默认分母为一
struct ratio {};
template < class _Rep, class _Period = ratio<1> >
class duration;
template <class _Rep, class _Period> // 代表一个时间持续时间
class duration
{
_Rep _MyRep; // 存储的时间值
template < class _Rep2 > // 有参构造函数
duration(const _Rep2& _Val) : _MyRep( static_cast<_Rep>(_Val) ) {}
}
*/
using microseconds = duration<long long, micro>;
using milliseconds = duration<long long, milli>; // 以毫秒为计量单位
using seconds = duration<long long>; // 以 秒为计量单位
using minutes = duration<int, ratio<60>>; // 以 分为计量单位
using hours = duration<int, ratio<3600>>; // 以 时为计量单位
#if _HAS_CXX20
using days = duration<int, ratio_multiply<ratio<24>, hours::period>>; // 以 天 为计量单位 24*3600
using weeks = duration<int, ratio_multiply<ratio<7>, days::period>>; // 以 周 为计量单位
using years = duration<int, ratio_multiply<ratio<146097, 400>, days::period>>;
using months = duration<int, ratio_divide<years::period, ratio<12>>>; // 以 月 为计量单位
#endif // _HAS_CXX20
//************************************************************************************************
template <class _Clock, class _Duration, class _Rep, class _Period> // 时间值的加法
time_point<_Clock, common_type_t<_Duration, duration<_Rep, _Period>>> // 函数的返回值
operator + (const time_point<_Clock, _Duration>& _Left, const duration<_Rep, _Period>& _Right)
{
using _RT = time_point<_Clock, common_type_t<_Duration, duration<_Rep, _Period>>>;
return _RT(_Left.time_since_epoch() + _Right);
}
/*
template <class _Clock, class _Duration = typename _Clock::duration>
class time_point // represents a point in time
{
_Duration _MyDur{ duration::zero() }; // 先对数据成员初始化为 0
_Duration time_since_epoch() { return _MyDur; } // 纪元,返回自己的数据成员的值
}
*/
template <class _Rep, class _Period, class _Clock, class _Duration> // 时间值的加法的重载
time_point<_Clock, common_type_t<duration<_Rep, _Period>, _Duration>>
operator + (const duration<_Rep, _Period>& _Left, const time_point<_Clock, _Duration>& _Right)
{
return _Right + _Left;
}
template <class _Clock, class _Duration, class _Rep, class _Period> // 时间值的减法
time_point<_Clock, common_type_t<_Duration, duration<_Rep, _Period>>>
operator - (const time_point<_Clock, _Duration>& _Left, const duration<_Rep, _Period>& _Right)
{
using _RT = time_point<_Clock, common_type_t<_Duration, duration<_Rep, _Period>>>;
return _RT(_Left.time_since_epoch() - _Right);
}
template <class _Clock, class _Duration1, class _Duration2> // 时间值的减法的重载
common_type_t<_Duration1, _Duration2>
operator - ( const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right)
{
return _Left.time_since_epoch() - _Right.time_since_epoch();
}
//***********************************************************************************************
template <class _Clock, class _Duration1, class _Duration2> // 时间值的相等的比较 ==
bool // 函数的返回值
operator == (const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right)
{
return _Left.time_since_epoch() == _Right.time_since_epoch();
}
template <class _Clock, class _Duration1, class _Duration2> // 时间值的小于的比较 <
bool // 函数的返回值
operator < (const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right)
{
return _Left.time_since_epoch() < _Right.time_since_epoch();
}
template <class _Clock, class _Duration1, class _Duration2> // 时间值的小于等于的比较 <=
bool // 函数的返回值
operator <= (const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right)
{
return !(_Right < _Left); // 由上面的 小于 < 比较来实现
}
template <class _Clock, class _Duration1, class _Duration2> // 时间值的大于的比较 >
bool // 函数的返回值
operator > (const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right)
{
return _Right < _Left;
}
template <class _Clock, class _Duration1, class _Duration2> // 时间值的大于等于的比较 >=
bool // 函数的返回值
operator >= (const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right)
{
return !(_Left < _Right);
}
#ifdef __cpp_lib_concepts // 略,定义的 operator<=> 运算符
template <class _Clock, class _Duration1, three_way_comparable_with<_Duration1> _Duration2>
_NODISCARD constexpr auto
operator<=>(const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) noexcept(
is_arithmetic_v<typename _Duration1::rep>&& is_arithmetic_v<typename _Duration2::rep>) /* strengthened */ {
return _Left.time_since_epoch() <=> _Right.time_since_epoch();
}
#endif // defined(__cpp_lib_concepts)
//******************************************************************************************
// change the duration type of a time_point; truncate 更改时间点的持续时间类型;截断
template <class _To, class _Clock, class _Duration, enable_if_t<_Is_duration_v<_To>, int> = 0>
time_point<_Clock, _To> time_point_cast(const time_point<_Clock, _Duration>& _Time)
{ // 转换时间量的表示,计时单位不一样
return time_point<_Clock, _To>(_CHRONO duration_cast<_To>(_Time.time_since_epoch()));
}
// change the duration type of a time_point; round towards negative infinity
// 更改时间点的持续时间类型;向负无穷大方向圆整
template <class _To, class _Clock, class _Duration, enable_if_t<_Is_duration_v<_To>, int> = 0>
time_point<_Clock, _To> floor(const time_point<_Clock, _Duration>& _Time) // 时间转换,向下取整
{
return time_point<_Clock, _To>(_CHRONO floor<_To>(_Time.time_since_epoch()));
}
// change the duration type of a time_point; round towards positive infinity
// 更改时间点的持续时间类型;向正无穷大方向圆整
template <class _To, class _Clock, class _Duration, enable_if_t<_Is_duration_v<_To>, int> = 0>
time_point<_Clock, _To> ceil(const time_point<_Clock, _Duration>& _Time) // 时间转换,向上取整
{
return time_point<_Clock, _To>(_CHRONO ceil<_To>(_Time.time_since_epoch()));
}
// change the duration type of a time_point; round to nearest, ties to even
// 更改时间点的持续时间类型,圆到最近,绑定到偶数
template <class _To, class _Clock, class _Duration, enable_if_t< // 四舍五入, 0.5 则圆整为偶数
_Is_duration_v<_To> && !treat_as_floating_point_v<typename _To::rep>, int> = 0>
time_point<_Clock, _To> round(const time_point<_Clock, _Duration>& _Time)
{
return time_point<_Clock, _To>(_CHRONO round<_To>(_Time.time_since_epoch()));
}
//****************************************************************************
// 系统时钟可以修改,甚至可以网络对时,因此使用系统时间计算时间差可能不准。
// wraps GetSystemTimePreciseAsFileTime/GetSystemTimeAsFileTime
// 记录的是 当前距离 1970 年的时间,以 100 纳秒为单位
struct system_clock
{
using rep = long long; // sizeof( long long ) = 8 字节
using period = ratio<1, 10'000'000>; // 100 nanoseconds = 100 纳秒
using duration = _CHRONO duration<rep, period>; // _CHRONO = ::std::chrono::
using time_point = _CHRONO time_point<system_clock>;
/*
// 第一个模板参数Clock用来指定所要使用的时钟,
// 标准库中有三种时钟,system_clock,steady_clock 和 high_resolution_clock 。
// 看定义可知,只需要指定模板类的模板参数一,第二个参数不指定的话就默认采用形参一里的计时单位
template <class _Clock, class _Duration = typename _Clock::duration>
class time_point // represents a point in time
{
_Duration _MyDur{ duration::zero() }; // 先对数据成员初始化为 0
explicit time_point(const _Duration& _Other) : _MyDur(_Other) {} // 带参的构造函数
}
*/
static constexpr bool is_steady = false;
// _CRTIMP2_PURE long long __cdecl _Xtime_get_ticks(); 调用的更底层的函数,读取 cmos 等
_NODISCARD static time_point now() noexcept // get current time
{
return time_point(duration(_Xtime_get_ticks()));
}
_NODISCARD static __time64_t to_time_t(const time_point& _Time) noexcept //拿到时间里的数值
{ // convert to __time64_t ; __time64_t = long long
return duration_cast<seconds>(_Time.time_since_epoch()).count();
}
// using seconds = duration<long long>; // 以 秒为计量单位
_NODISCARD static time_point from_time_t(__time64_t _Tm) noexcept // 构造一个时间值
{ // convert from __time64_t
return time_point{ seconds{_Tm} };
}
};
#if _HAS_CXX20
template <class _Duration> // 定义了三个简写类型,系统秒数,系统天数
using sys_time = time_point<system_clock, _Duration>;
using sys_seconds = sys_time<seconds>;
using sys_days = sys_time<days>;
#endif // _HAS_CXX20
//*****************************************************************************************
// 固定时钟,相当于秒表。开始计时后,时间只会增长并且不能修改,适合用于记录程序耗时
// 返回的是距离本主机开机的时长,以 1 纳秒 为单位
struct steady_clock // wraps QueryPerformanceCounter
{
using rep = long long;
using period = nano; // using nano = ratio<1, 1000000000>; 可见精度更高,纳秒
using duration = nanoseconds; // using nanoseconds = duration<long long, nano>;
using time_point = _CHRONO time_point<steady_clock>;
static constexpr bool is_steady = true;
// 本类只有这一个成员函数
// 返回值类型是 time_point < steady_clock , duration<long_long,nano> >
_NODISCARD static time_point now() noexcept // get current time
{
const long long _Freq = _Query_perf_frequency(); // doesn't change after system boot
const long long _Ctr = _Query_perf_counter ();
static_assert(period::num == 1, "This assumes period::num == 1.");
// 10 MHz is a very common QPC frequency on modern PCs.
// Optimizing for this specific frequency can double the performance of this function
// by avoiding the expensive frequency conversion path.
// 10 MHz是现代PC上非常常见的 QPC 频率。
// 优化该特定频率可以避免昂贵的频率转换路径,从而使该功能的性能翻倍。
constexpr long long _TenMHz = 10'000'000; // 定义了一个数, 10兆
if (_Freq == _TenMHz)
{
static_assert(period::den % _TenMHz == 0, "It should never fail.");
constexpr long long _Multiplier = period::den / _TenMHz; // 等于 100
return time_point(duration(_Ctr * _Multiplier)); // 从 10^7 兆放大到纳秒,乘以 100
}
else
{
// Instead of just having "(_Ctr * period::den) / _Freq",
// the algorithm below prevents overflow when _Ctr is sufficiently large.
// It assumes that _Freq * period::den does not overflow, which is currently true for nano period.
// It is not realistic for _Ctr to accumulate to large values from zero with this assumption,
// but the initial value of _Ctr could be large.
// 与其只具有“(_Ctr* period::den) /_Freq”,下面的算法在_Ctr足够大时防止溢出。
// 它假设_Freq* period::den不溢出,目前对于nano周期是这样。
// 根据这个假设,_Ctr从零累积到大值是不现实的,但_Ctr的初始值可能会很大。
const long long _Whole = (_Ctr / _Freq) * period::den;
const long long _Part = (_Ctr % _Freq) * period::den / _Freq;
return time_point( duration(_Whole + _Part) );
}
}
};
using high_resolution_clock = steady_clock; // 和时钟类 steady_clock是等价的(是它的别名)。
} // namespace chrono
/*
// Convert duration to xtime, maximum 10 days from now, returns whether clamping occurred.
// If clamped, timeouts will be transformed into spurious non-timeout wakes,
// due to ABI restrictions where the other side of the DLL boundary overflows int32_t milliseconds.
// Every function calling this one is TRANSITION, ABI
将持续时间转换为xtime,从现在起最多10天,返回是否发生夹紧。
如果卡住,超时将被转换为虚假的非超时响应,这是由于ABI的限制,DLL边界的另一边溢出时间为int32_t毫秒。
调用这个函数的每个函数都是 TRANSITION、ABI
struct xtime { // store time with nanosecond resolution 纳秒级分辨率的存储时间
__time64_t sec; // typedef long long __time64_t
long nsec;
};
*/
// 存储纳秒级分辨率的时间值 // typedef long long __time64_t
// struct xtime { __time64_t sec ; long nsec ; }; 纳秒 = 10^9 不算太大
// 本函的形参 2 是相对于当前时间的时间间隔,圆整成 10 天以内,相对于 1970年 的绝对时刻,存入形参 1;
// 若发生了时长截断,形参2 大于 10 天,则返回 true ,否则返回 false。形参一是左值引用。
template <class _Rep, class _Period> // int 类型最大值 2,147,483,647 约等于 2 * 10 ^ 9 刚好够用
_NODISCARD bool _To_xtime_10_day_clamped(_CSTD xtime& _Xt, const _CHRONO duration<_Rep, _Period>& _Rel_time)
noexcept( is_arithmetic_v<_Rep> )
{
// using nanoseconds = duration<long long, nano>; 得到 10 天值的纳秒表示
constexpr _CHRONO nanoseconds _Ten_days{ _CHRONO hours{24} *10 };
// template < class _Rep, class _Period = ratio<1> >
// class duration; 将纳秒的 10 天值更换为 秒 级的 10 天值
constexpr _CHRONO duration<double> _Ten_days_d{ _Ten_days };
// 获得当前时间的距离 1970 年的时间间隔的纳秒级表示,往更小单位方向的计时转换,才是允许的。
_CHRONO nanoseconds _Tx0 = _CHRONO system_clock::now().time_since_epoch();
const bool _Clamped = _Ten_days_d < _Rel_time; // 若形参 2 的时长太大,则为 true ,需要裁剪时长
if (_Clamped) _Tx0 += _Ten_days;
else _Tx0 += _CHRONO duration_cast<_CHRONO nanoseconds>(_Rel_time);
// template <class _To, class _Rep, class _Period, enable_if_t<_Is_duration_v<_To>, int> _Enabled>
// _To duration_cast ( const duration<_Rep, _Period>&_Dur ) // 时间值的单位转换,truncate 截断
const auto _Whole_seconds = _CHRONO duration_cast<_CHRONO seconds>(_Tx0); // 以秒为单位
_Xt.sec = _Whole_seconds.count();
_Tx0 -= _Whole_seconds;
_Xt.nsec = static_cast<long>(_Tx0.count()); // 秒数 与 纳秒数
return _Clamped;
}
inline namespace literals
{
inline namespace chrono_literals // 在此命名空间里定义了一些函数,奇奇怪怪的形式的函数
{
// using hours = duration<int, ratio<3600>>; // 以 时为计量单位
_NODISCARD constexpr _CHRONO hours operator ""h(unsigned long long _Val)
noexcept /* strengthened */ { // 小时字面量 h
return _CHRONO hours(_Val);
}
// 以下开始省略函数的修饰符,突出重点
_CHRONO duration<double, ratio<3600>> operator ""h (long double _Val) {
return _CHRONO duration<double, ratio<3600>>(_Val); // 这样改写函数名,语义更明显
}
_CHRONO minutes operator ""min (unsigned long long _Val) { return _CHRONO minutes(_Val); }
_CHRONO duration<double, ratio<60>> operator ""min (long double _Val) { // 分钟字面量 min
return _CHRONO duration<double, ratio<60>>(_Val);
}
_CHRONO seconds operator ""s (unsigned long long _Val) { return _CHRONO seconds(_Val); }
_CHRONO duration<double> operator ""s (long double _Val) { // 秒字面量 s
return _CHRONO duration<double>(_Val);
}
// using milliseconds = duration<long long, milli>; // 以毫秒为计量单位
_CHRONO milliseconds operator ""ms (unsigned long long _Val) { return _CHRONO milliseconds(_Val); }
_CHRONO duration<double, milli> operator"" ms(long double _Val) { // 毫秒字面量 ms 看函数名即可
return _CHRONO duration<double, milli>(_Val);
}
// using micro = ratio<1, 1000000>;
// using microseconds = duration<long long, micro>;
_CHRONO microseconds operator ""us (unsigned long long _Val) { return _CHRONO microseconds(_Val); }
_CHRONO duration<double, micro> operator ""us (long double _Val) { // 微秒字面量 us
return _CHRONO duration<double, micro>(_Val);
}
_CHRONO nanoseconds operator ""ns (unsigned long long _Val) { return _CHRONO nanoseconds(_Val); }
_CHRONO duration<double, nano> operator ""ns (long double _Val) {
return _CHRONO duration<double, nano>(_Val);
}
} // namespace chrono_literals
} // namespace literals
namespace chrono { // 在 chrono 命名空间里包含 命名空间 chrono_literals 时间字面量函数
using namespace literals::chrono_literals;
} // namespace chrono
_STD_END
// #define _STD_END } ,在 std 命名空间里的操作结束
#pragma pop_macro("new")
// 恢复最开始隐藏的 new 宏定义,#pragma push_macro("new")
_STL_RESTORE_CLANG_WARNINGS
// 对应最开始的,此处是恢复 clang 警告
#pragma warning(pop)
// 恢复原来的警告级别 #pragma warning(push, _STL_WARNING_LEVEL)
#pragma pack(pop)
// 恢复原来的内存对齐方式 #pragma pack(push, _CRT_PACKING)
#endif // _STL_COMPILER_PREPROCESSOR,本文件在此 #if 成立时才存在
#endif // __MSVC_CHRONO_HPP
(24)
谢谢,暂时完结对本头文件的注释