std::shared_ptr
has specializations for atomic operations like atomic_compare_exchange_weak
and family, but I cannot find documentation on equivale
The reason that it is possible to provide an atomic instance of std::shared_ptr
and it is not possible to do so for std::unique_ptr
is hinted at in their signature. Compare:
std::shared_ptr
vsstd::unique_ptr
where D
is the type of the Deleter.std::shared_ptr
needs to allocate a control-block where the strong and weak count are kept, so type-erasure of the deleter came at a trivial cost (a simply slightly larger control-block).
As a result, the layout of std::shared_ptr
is generally similar to:
template
struct shared_ptr {
T* _M_ptr;
SomeCounterClass* _M_counters;
};
And it is possible to atomically perform the exchange of those two pointers.
std::unique_ptr
has a zero-overhead policy; using a std::unique_ptr
should not incur any overhead compared to using a raw pointer.
As a result, the layout of std::unique_ptr
is generally similar to:
template >
struct unique_ptr {
tuple _M_t;
};
Where the tuple
uses EBO (Empty Base Optimization) so that whenever D is zero-sized then sizeof(unique_ptr
.
However, in the cases where D
is NOT zero-sized, the implementation boils down to:
template >
struct unique_ptr {
T* _M_ptr;
D _M_del;
};
This D
is the kicker here; it is not possible, in general, to guarantee that D
can be exchange in an atomic fashion without relying on mutexes.
Therefore, it is not possible to provide an std::atomic_compare_exchange*
suite of specialized routine for the generic std::unique_ptr
.
Note that the standard does not even guarantee that sizeof(unique_ptr
AFAIK, though it's a common optimization.