(52) 模板类 _Atomic_integral《T, u_long_long》 及其特化版本 _Atomic_integral《_Ty, 1》。该系列模板类在 _Atomic_storage<_Ty> 的基础上增加了对数据的原子运算,加减法,逻辑与或运算等。先给出其源代码:
template <class _Ty, size_t = sizeof(_Ty)> // 泛化模板类没有给出定义
struct _Atomic_integral; // not defined
// 整数都原子性的支持:加法、a++、++a、a--、--a 以及按位的 与and、或or、异或xor 运算。
template <class _Ty> // atomic integral operations using 1-byte intrinsics
struct _Atomic_integral<_Ty, 1> : _Atomic_storage<_Ty> // 使用内部函数对 1 字节的整数进行原子操作
{
using _Base = _Atomic_storage<_Ty>; // 由于继承,本类仍将具有 1 字节的数据空间,存储了要保护的数据
using typename _Base::_TVal; // 类的声明,使在本域内可见
using _Base::_Base; // 没有找到这个定义。但编译器也不报错。但自己模仿这种写法则会报错。
_TVal fetch_add(const _TVal _Operand, const memory_order _Order = memory_order_seq_cst) noexcept
{
char _Result;
/*
#define _ATOMIC_CHOOSE_INTRINSIC(_Order, _Result, _Intrinsic, ...) \
_Check_memory_order(_Order); \
_Result = _Intrinsic(__VA_ARGS__)
*/
_ATOMIC_CHOOSE_INTRINSIC(_Order, _Result, _InterlockedExchangeAdd8,
_Atomic_address_as<char>(this->_Storage), static_cast<char>(_Operand));
// SHORT _InterlockedExchangeAdd8( volatile BYTE* Target, BYTE Value );
// 该函数原子地增加形参 1 的值,但返回值是形参1 的旧值
return static_cast<_TVal>(_Result);
}
_TVal operator ++ (int) noexcept // a++
{
return static_cast<_TVal>(_InterlockedExchangeAdd8(_Atomic_address_as<char>(this->_Storage), 1));
}
_TVal operator ++ () noexcept // ++a
{
unsigned char _Before = static_cast<unsigned char> (
_InterlockedExchangeAdd8(_Atomic_address_as<char>(this->_Storage), 1) );
++_Before;
return static_cast<_TVal>(_Before);
}
_TVal operator--(int) noexcept // a--
{
return static_cast<_TVal>(_InterlockedExchangeAdd8(_Atomic_address_as<char>(this->_Storage), -1));
}
_TVal operator--() noexcept // --a
{
unsigned char _Before = static_cast<unsigned char>(
_InterlockedExchangeAdd8(_Atomic_address_as<char>(this->_Storage), -1) );
--_Before;
return static_cast<_TVal>(_Before);
}
_TVal fetch_and(const _TVal _Operand, const memory_order _Order = memory_order_seq_cst) noexcept
{
char _Result;
// BYTE _InterlockedAnd8( volatile BYTE* Target, BYTE Value );
// 该函数原子性的对形参1 进行按位与操作,返回的是形参1 的旧值。
_ATOMIC_CHOOSE_INTRINSIC( _Order, _Result, _InterlockedAnd8,
_Atomic_address_as<char>(this->_Storage), static_cast<char>(_Operand));
return static_cast<_TVal>(_Result);
}
_TVal fetch_or(const _TVal _Operand, const memory_order _Order = memory_order_seq_cst) noexcept
{
char _Result;
// BYTE _InterlockedOr8( volatile BYTE* Target, BYTE Value );
// 该函数原子性的完成对形参1 的或操作,但返回形参 1 的旧值。
_ATOMIC_CHOOSE_INTRINSIC( _Order, _Result, _InterlockedOr8,
_Atomic_address_as<char>(this->_Storage), static_cast<char>(_Operand));
return static_cast<_TVal>(_Result);
}
_TVal fetch_xor(const _TVal _Operand, const memory_order _Order = memory_order_seq_cst) noexcept
{
char _Result;
// BYTE _InterlockedXor8( volatile BYTE* Destination, BYTE Value );
// 此函数原子性的完成对形参1 的异或操作,返回的是形参 1 的旧值
_ATOMIC_CHOOSE_INTRINSIC( _Order, _Result, _InterlockedXor8,
_Atomic_address_as<char>(this->_Storage), static_cast<char>(_Operand));
return static_cast<_TVal>(_Result);
}
};
++ 接着测试一下其成员函数的返回值:
(53)
谢谢