(67) 接着,经过前面很长的铺垫,那么多基础类。整数,浮点数,指针,引用,各种类型都可以成员原子量 atomic《T》 中的数据成员。现在开始学习 atomic《T》 的父类 _Choose_atomic_base_t《T , T》 或 _Choose_atomic_base2_t《T , T》。因为众多的数据类型,只接受各不相同的数学运算。所以 atomic 的父类也是千奇百怪。先学习 atomic《T》 的继承关系。再学习其代码:
template <class _Ty, _Ty _Val>
struct integral_constant { static constexpr _Ty value = _Val; }; // 类内声明的静态变量,必须为常量
template <bool _Val>
using bool_constant = integral_constant<bool, _Val>;
using true_type = bool_constant<true > ;
using false_type = bool_constant<false> ;
//**********************************************************************************************
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> // If _Traits is empty, false_type 泛化模板类,处理模板参数的数量为 0 的情形
struct disjunction : false_type {}; // disj 有一个为真就为 真,所有都为假才为假。
template <class _First, class... _Rest> // the first true trait in _Traits, or the last trait if none are true
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 <bool>
struct _Select { template <class _Ty1, class> using _Apply = _Ty1; };
template <>
struct _Select<false> { template <class, class _Ty2> using _Apply = _Ty2; };
//***********************************************************************************************
template <class _TVal, class _Ty = _TVal> // 此处是为了区分浮点型与其它类型(整数、指针等)
using _Choose_atomic_base_t = typename _Select<is_floating_point_v<_TVal>> ::
template _Apply<_Atomic_floating<_Ty>, _Choose_atomic_base2_t<_TVal, _Ty>>;
template <class _Ty> // atomic value
struct atomic : _Choose_atomic_base_t<_Ty> { } ;
(68)接着学习 atomic《T》 的另一个父类 _Choose_atomic_base2_t《T , T》,适用于 T 非浮点数的情形:
_Atomic_integral<T , 8> : _Atomic_storage<T , 8> ; // 特化版本之间,对应完成继承
_Atomic_integral<T , 4> : _Atomic_storage<T , 4> ;
_Atomic_integral<T , 2> : _Atomic_storage<T , 2> ;
_Atomic_integral<T , 1> : _Atomic_storage<T , 1> ;
//************************************************************************************************
template <class _Ty, size_t = sizeof(_Ty)> // 有 1 2 4 8 的重载, 也有其泛化版本的定义
struct _Atomic_storage { };
template <class _Ty, size_t = sizeof(_Ty)> // 有 1 2 4 8 的重载,但其泛化版本无定义
struct _Atomic_integral : _Atomic_storage<_Ty> {};
template <class _Ty> // 本模板作为普通整形 atomic<int> 的父类 ,本类并无数据成员
struct _Atomic_integral_facade : _Atomic_integral<_Ty>{ };
//***************************************************************************************************
template <class _Ty> // 注意,这里把 bool 类型也视为了 integral 整数类型。
bool is_integral_v = _Is_any_of_v < remove_cv_t<_Ty> , bool , char, signed char, unsigned char,
wchar_t,
#ifdef __cpp_char8_t
char8_t,
#endif // __cpp_char8_t
char16_t, char32_t, short, unsigned short, int, unsigned int, long, unsigned long, long long, unsigned long long>;
//***************************************************************************************************
template <class _TVal, class _Ty = _TVal> // T为整数及其引用类型且非 bool时,atomic 的父类是 _Atomic_integral_facade<T>
using _Choose_atomic_base2_t = typename _Select< is_integral_v<_TVal> && !is_same_v<bool, _TVal>> ::
template _Apply< _Atomic_integral_facade<_Ty> , // 然后对 bool 、指针类型的情况继续选择
typename _Select<is_pointer_v<_TVal> && is_object_v<remove_pointer_t<_TVal>>>::
template _Apply< _Atomic_pointer<_Ty>, _Atomic_storage<_Ty> > // 指针类型,也要确定不是指向函数与引用的指针。
>; // 最后只剩下 bool 类型,故 atomic<bool> 直接继承 _Atomic_storage<T> 的泛化版本。
(69) 接着继续展开 atomic《T》当 T 为 bool 类型或指针类型时候的泛型推导 :
template <class>
bool is_pointer_v = false; // determine whether _Ty is a pointer
template <class _Ty>
bool is_pointer_v<_Ty*> = true;
template <class _Ty>
bool is_pointer_v<_Ty* const> = true;
template <class _Ty>
bool is_pointer_v<_Ty* volatile> = true;
template <class _Ty>
bool is_pointer_v<_Ty* const volatile> = true;
//*****************************************************************************
template <class _Ty>
struct remove_pointer { using type = _Ty; };
template <class _Ty>
struct remove_pointer<_Ty*> { using type = _Ty; };
template <class _Ty>
struct remove_pointer<_Ty* const> { using type = _Ty; };
template <class _Ty>
struct remove_pointer<_Ty* volatile> { using type = _Ty; };
template <class _Ty>
struct remove_pointer<_Ty* const volatile> { using type = _Ty; };
template <class _Ty>
using remove_pointer_t = typename remove_pointer<_Ty>::type;
//**************************************************************************************************
template <class _Ty> // only function types and reference types can't be const qualified
bool is_function_v = !is_const_v<const _Ty> && !is_reference_v<_Ty>;
template <class _Ty> // 对于函数和引用类型 is_const_v<const _Ty> = false ,这是编译器的特殊设置
struct is_function : bool_constant<is_function_v<_Ty>> {};
template <class _Ty> // only function types and reference types can't be const qualified
bool is_object_v = is_const_v<const _Ty> && !is_void_v<_Ty>;
(70) 通过以上的分析,泛型推导,了解了一些关于 atomic《T》的父类的知识。当 T 为整数及其引用、 bool 、浮点、指针类型、或自定义类型时, atomic《T》 的父类是不同的,父类类型可以是这些:_Atomic_floating《T》、_Atomic_integral_facade《T》、_Atomic_pointer《T》、_Atomic_storage《T》(适用于大小非 1 2 4 8 16 的自定义类型数据)、_Atomic_storage《T , 1》(适用于 1 字节的 bool 类型 、char 类型以及 1 字节大小的自定义类型)。
接着我们验证一下 atomic 类型的父类的类型:
++ 测试结果如下:
(71)接着给出 atomic《T》 的 父子继承关系的总图,更有利于弄清记忆这些类的定义、功能与作用:
(72)
谢谢