(65)接着阅读 爷模板类 _Atomic_storage《T , size_t》 的指针爹类 _Atomic_pointer《T》 。源码如下:
// 指针类原子量支持的运算有:加减法、a++、++a、a--、--a、+=、-= 。
template <class _Ty> // 此时 _Ty 是指针类型如 int *
struct _Atomic_pointer : _Atomic_storage<_Ty> // 指针支持加减自增自减操作,但取消了与或异或操作
{
using _Base = _Atomic_storage<_Ty>;
using difference_type = ptrdiff_t; // long long = ptrdiff_t
using _Base::_Base;
//***指针的加法***
// 不同数据类型的指针,移动的步长是不一样的,与数据类型有关。
_Ty fetch_add(const ptrdiff_t _Diff, const memory_order _Order = memory_order_seq_cst) noexcept
{
const ptrdiff_t _Shift_bytes = static_cast<ptrdiff_t>( // 把指针的步数换算成以字节为单位的字节数
static_cast<size_t>(_Diff) * sizeof(remove_pointer_t<_Ty>) );
ptrdiff_t _Result;
// 该函数原子地增加形参 1 的值,但返回值是形参 1 的旧值。
_ATOMIC_CHOOSE_INTRINSIC( _Order, _Result, _InterlockedExchangeAdd64,
_Atomic_address_as<long long>(this->_Storage), _Shift_bytes);
return reinterpret_cast<_Ty>(_Result); // 返回的是原指针的值
}
/*
#define _ATOMIC_CHOOSE_INTRINSIC(_Order, _Result, _Intrinsic, ...) \
_Check_memory_order(_Order); \
_Result = _Intrinsic(__VA_ARGS__)
*/
_Ty fetch_add(const ptrdiff_t _Diff, const memory_order _Order) volatile noexcept
{
return const_cast<_Atomic_pointer*>(this)->fetch_add(_Diff, _Order);
}
_Ty fetch_add(const ptrdiff_t _Diff) volatile noexcept // 函数重载
{
return const_cast<_Atomic_pointer*>(this)->fetch_add(_Diff);
}
//***指针的减法***
_Ty fetch_sub(const ptrdiff_t _Diff, const memory_order _Order) noexcept
{
return fetch_add(static_cast<ptrdiff_t>(0 - static_cast<size_t>(_Diff)), _Order);
}
_Ty fetch_sub(const ptrdiff_t _Diff, const memory_order _Order) volatile noexcept
{
return fetch_add(static_cast<ptrdiff_t>(0 - static_cast<size_t>(_Diff)), _Order);
}
_Ty fetch_sub(const ptrdiff_t _Diff) volatile noexcept // 返回的是原指针的值
{
return fetch_add(static_cast<ptrdiff_t>(0 - static_cast<size_t>(_Diff)));
}
_Ty fetch_sub(const ptrdiff_t _Diff) noexcept
{
return fetch_add(static_cast<ptrdiff_t>(0 - static_cast<size_t>(_Diff)));
}
//***指针自增***
_Ty operator++(int) volatile noexcept { return fetch_add(1); } // 返回旧值
_Ty operator++(int) noexcept { return fetch_add(1); }
_Ty operator++() volatile noexcept { return fetch_add(1) + 1; } // 返回新的原子量的值
_Ty operator++() noexcept { return fetch_add(1) + 1; }
//***指针自减***
_Ty operator--(int) volatile noexcept { return fetch_add(-1); } // 返回旧值
_Ty operator--(int) noexcept { return fetch_add(-1); }
_Ty operator--() volatile noexcept { return fetch_add(-1) - 1; } // 返回新的原子量的值
_Ty operator--() noexcept { return fetch_add(-1) - 1; }
//***复合加减运算符***
_Ty operator+=(const ptrdiff_t _Diff) volatile noexcept
{
return fetch_add(_Diff) + _Diff; // 返回值是原子量更新后的值
}
_Ty operator+=(const ptrdiff_t _Diff) noexcept
{
return fetch_add(_Diff) + _Diff; // 返回值是原子量更新后的值
}
_Ty operator-=(const ptrdiff_t _Diff) volatile noexcept
{
return fetch_add(static_cast<ptrdiff_t>(0 - static_cast<size_t>(_Diff))) - _Diff;
}
_Ty operator-=(const ptrdiff_t _Diff) noexcept // 返回值原子量更新后的值
{
return fetch_add(static_cast<ptrdiff_t>(0 - static_cast<size_t>(_Diff))) - _Diff;
}
};
++ 给出其成员函数的测试结果:
(66) 接着给出 类型 _Atomic_pointer《T》 的特化版本 _Atomic_pointer《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, 8> { typename _Atomic_storage_types<_Ty>::_TStorage _Storage; };
*/
template <class _Ty> // 引用类型的成员函数都没有了 volatile 修饰符
struct _Atomic_pointer<_Ty&> : _Atomic_storage<_Ty&>
{
using _Base = _Atomic_storage<_Ty&>;
using difference_type = ptrdiff_t;
using _Base::_Base;
//***指针的加减法***
_Ty fetch_add(const ptrdiff_t _Diff, const memory_order _Order = memory_order_seq_cst) const noexcept
{
const ptrdiff_t _Shift_bytes = static_cast<ptrdiff_t>(
static_cast<size_t>(_Diff) * sizeof(remove_pointer_t<_Ty>) );
ptrdiff_t _Result;
// 该函数原子地增加形参 1 的值,但返回值是形参 1 的旧值。
_ATOMIC_CHOOSE_INTRINSIC( _Order, _Result, _InterlockedExchangeAdd64,
_Atomic_address_as<long long>(this->_Storage), _Shift_bytes);
return reinterpret_cast<_Ty>(_Result); // 返回的是原指针的值
}
/*
#define _ATOMIC_CHOOSE_INTRINSIC(_Order, _Result, _Intrinsic, ...) \
_Check_memory_order(_Order); \
_Result = _Intrinsic(__VA_ARGS__)
*/
_Ty fetch_sub(const ptrdiff_t _Diff) const noexcept // 返回的是原指针的值
{
return fetch_add(static_cast<ptrdiff_t>(0 - static_cast<size_t>(_Diff)));
}
_Ty fetch_sub(const ptrdiff_t _Diff, const memory_order _Order) const noexcept
{
return fetch_add(static_cast<ptrdiff_t>(0 - static_cast<size_t>(_Diff)), _Order);
}
//***自增自减运算符***
_Ty operator++(int) const noexcept { return fetch_add(1); } // 返回旧值
_Ty operator++() const noexcept { return fetch_add(1) + 1; } // 返回新的原子量的值
_Ty operator--(int) const noexcept { return fetch_add(-1); } // 返回旧值
_Ty operator--() const noexcept { return fetch_add(-1) - 1; } // 返回新的原子量的值
//***复合加减运算符***
_Ty operator+=(const ptrdiff_t _Diff) const noexcept // 返回值是原子量更新后的值
{
return fetch_add(_Diff) + _Diff;
}
_Ty operator-=(const ptrdiff_t _Diff) const noexcept // 返回值是原子量更新后的值
{
return fetch_add(static_cast<ptrdiff_t>(0 - static_cast<size_t>(_Diff))) - _Diff;
}
};
++ 测试结果如下:
(67)
谢谢