(63)接着阅读 爷模板类 _Atomic_storage《T , size_t》 的浮点爹类 _Atomic_floating《T》 。适合浮点数的原子运算,就要少一点了
// 浮点类型的原子类型的运算:加减法、+=、-=
template <class _Ty> // provides atomic floating-point operations
struct _Atomic_floating : _Atomic_storage<_Ty> // 本模板为浮点类型提供原子操作
{
using _Base = _Atomic_storage<_Ty>; // float 的父类是 _Atomic_storage<float,4>
using difference_type = _Ty; // double 的父类是 _Atomic_storage<float,8>
using _Base::_Base;
_Ty fetch_add(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) noexcept
{
_Ty _Temp{this->load(memory_order_relaxed)};
// 当本类中存储的值 等于形参1 时,把形参 2 的值存入本类;
// 当本类中存储的值 不等于形参1 时,把本类中的值写入形参 1 。有点指令 cmpxchg 的语义。
// 返回值表示形参1 与本类中的值是否相等,是则返回 true。
// bool compare_exchange_strong (T& expected,T desired, memory_order order = seq_cst)
while (!this->compare_exchange_strong(_Temp, _Temp + _Operand, _Order)) {} // keep trying
return _Temp; // 可见,依然是返回原子量的旧值
}
_Ty fetch_add(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) volatile noexcept
{
return const_cast<_Atomic_floating*>(this)->fetch_add(_Operand, _Order);
}
_Ty fetch_sub(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) noexcept
{
_Ty _Temp{this->load(memory_order_relaxed)};
while (!this->compare_exchange_strong(_Temp, _Temp - _Operand, _Order)) {} // keep trying
return _Temp; // 可见,依然是返回原子量的旧值
}
_Ty fetch_sub(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) volatile noexcept
{
return const_cast<_Atomic_floating*>(this)->fetch_sub(_Operand, _Order);
}
_Ty operator+=(const _Ty _Operand) noexcept // 返回加法的结果
{
return fetch_add(_Operand) + _Operand;
}
_Ty operator+=(const _Ty _Operand) volatile noexcept // 返回加法的结果
{
return const_cast<_Atomic_floating*>(this)->fetch_add(_Operand) + _Operand;
}
_Ty operator-=(const _Ty _Operand) noexcept // 返回减法的结果
{
return fetch_sub(_Operand) - _Operand;
}
_Ty operator-=(const _Ty _Operand) volatile noexcept // 返回减法的结果
{
return const_cast<_Atomic_floating*>(this)->fetch_sub(_Operand) - _Operand;
}
};
++ 对成员函数的测试结果如下:
++ 以及:
(64)接着给出 类型 _Atomic_floating《T》 的特化版本 _Atomic_floating《T&》 的 源码与成员函数测试:
/* 这些注释说明了数据类性的数据成员是数据,引用类型的数据成员,依然是左值引用
template <class _Ty> // 对齐sizeof (T);x86堆栈在4字节边界上对齐8字节对象
struct _Atomic_padded { alignas(sizeof(_Ty)) mutable _Ty _Value; };
template <class _Ty>
struct _Atomic_storage_types { using _TStorage = _Atomic_padded<_Ty>; };
template <class _Ty>
struct _Atomic_storage_types<_Ty&> { using _TStorage = _Ty&; };
template <class _Ty>
struct _Atomic_storage<_Ty, 4> { typename _Atomic_storage_types<_Ty>::_TStorage _Storage; };
*/
// 浮点类型的原子类型的运算:加减法、+=、-=
template <class _Ty> // provides atomic floating-point operations
struct _Atomic_floating<_Ty&> : _Atomic_storage<_Ty&>
{
using _Base = _Atomic_storage<_Ty&>;
using difference_type = _Ty;
using _Base::_Base;
_Ty fetch_add(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) const noexcept
{
_Ty _Temp { this->load(memory_order_relaxed) } ;
// 当本类中存储的值 等于形参1 时,把形参 2 的值存入本类;
// 当本类中存储的值 不等于形参1 时,把本类中的值写入形参 1 。有点指令 cmpxchg 的语义。
// 返回值表示形参1 与本类中的值是否相等,是则返回 true。
// bool compare_exchange_strong (T& expected,T desired, memory_order order = seq_cst)
while (!const_cast<_Atomic_floating*>(this)->_Base::compare_exchange_strong( _Temp,
_Temp + _Operand, _Order)) { } // keep trying
return _Temp; // 可见,依然是返回原子量的旧值
}
_Ty fetch_sub(const _Ty _Operand, const memory_order _Order = memory_order_seq_cst) const noexcept
{
_Ty _Temp { this->load(memory_order_relaxed) };
while (!const_cast<_Atomic_floating*>(this)->_Base::compare_exchange_strong( _Temp,
_Temp - _Operand, _Order)) { } // keep trying
return _Temp;
}
_Ty operator += (const _Ty _Operand) const noexcept // 返回加法的结果
{
return fetch_add(_Operand) + _Operand;
}
_Ty operator -= (const _Ty _Operand) const noexcept // 返回减法的结果
{
return fetch_sub(_Operand) - _Operand;
}
};
++ 测试结果如下:
(65)
谢谢