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.
source to share
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.
source to share