About the implementation of atomic_exchange_strong_explicit for shared_ptr

See this link:

template<typename _Tp>
  bool
  atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p,
                                          shared_ptr<_Tp>* __v,
                                          shared_ptr<_Tp> __w,
                                          memory_order,
                                          memory_order)
  {
    shared_ptr<_Tp> __x; // goes out of scope after __lock
    _Sp_locker __lock{__p, __v};
    owner_less<shared_ptr<_Tp>> __less;
    if (*__p == *__v && !__less(*__p, *__v) && !__less(*__v, *__p))
      {
        __x = std::move(*__p);
        *__p = std::move(__w);
        return true;
      }
    __x = std::move(*__v);
    *__v = *__p;
    return false;
  }

      

It seems to me that *__p == *__v

both !__less(*__p, *__v) && !__less(*__v, *__p)

indicate that pointers *__p

and *__v

are equal. Why are they both used there?

Thank.

+3


source to share


1 answer


As touched upon by this great answer , we need to be sure that both shared_ptrs

share the same object and share the same ownership of that object (do both shared pointers use the same ref counter?).

*__p == *__v

verifies the first part by comparison *__p.get() == *__v.get()

, and then !__less(*__p, *__v) && !__less(*__v, *__p)

ensures that both shared pointers share an internal reference count, thus satisfying both parts.



*__p == *__v

only checks for equality of the objects it owns, not the general state of the internal ref counter, which is what we need here, so we need an additional construct.

+1


source







All Articles