atomic 注释24:爷模板类 _Atomic_storage<T,size_t> 的指针爹类 _Atomic_pointer<T>、 _Atomic_pointer< T& >及其成员函数测试

(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)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangzhangkeji

谢谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值