Skip to content

P2869R4 Remove deprecated atomic free function API for shared_ptr #6902

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions source/compatibility.tex
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,18 @@
// OK in \CppXXVI{}
\end{codeblock}

\nodiffref
\change
Removal of atomic access API for \tcode{shared_ptr} objects.
\rationale
The old behavior was brittle. \tcode{shared_ptr} objects using the old API were
not protected by the type system, and certain interactions with code not using
this API would, in some cases, silently produce undefined behavior. A complete
type-safe replacement is provided in the form of \tcode{atomic<shared_ptr<T>>}.
\effect
A valid \CppXXIII{} program that relies on the presence of the removed functions
may fail to compile.

\nodiffref
\change
Remove the \tcode{basic_string::reserve()} overload with no parameters.
Expand Down
268 changes: 0 additions & 268 deletions source/future.tex
Original file line number Diff line number Diff line change
Expand Up @@ -675,274 +675,6 @@
\tcode{current}.
\end{itemdescr}

\rSec1[depr.util.smartptr.shared.atomic]{Deprecated \tcode{shared_ptr} atomic access}

\pnum
The header \libheaderref{memory} has the following additions:

\indexlibraryglobal{shared_ptr}%
\begin{codeblock}
namespace std {
template<class T>
bool atomic_is_lock_free(const shared_ptr<T>* p);

template<class T>
shared_ptr<T> atomic_load(const shared_ptr<T>* p);
template<class T>
shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);

template<class T>
void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
template<class T>
void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);

template<class T>
shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
template<class T>
shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);

template<class T>
bool atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
template<class T>
bool atomic_compare_exchange_strong(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
template<class T>
bool atomic_compare_exchange_weak_explicit(
shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
memory_order success, memory_order failure);
template<class T>
bool atomic_compare_exchange_strong_explicit(
shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
memory_order success, memory_order failure);
}
\end{codeblock}

\pnum
Concurrent access to a \tcode{shared_ptr} object from multiple threads does not
introduce a data race if the access is done exclusively via the functions in
this subclause and the instance is passed as their first argument.

\pnum
The meaning of the arguments of type \tcode{memory_order} is explained in~\ref{atomics.order}.

\indexlibrarymember{atomic_is_lock_free}{shared_ptr}%
\begin{itemdecl}
template<class T> bool atomic_is_lock_free(const shared_ptr<T>* p);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{p} is not null.

\pnum
\returns
\tcode{true} if atomic access to \tcode{*p} is lock-free, \tcode{false} otherwise.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibrarymember{atomic_load}{shared_ptr}%
\begin{itemdecl}
template<class T> shared_ptr<T> atomic_load(const shared_ptr<T>* p);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{p} is not null.

\pnum
\returns
\tcode{atomic_load_explicit(p, memory_order::seq_cst)}.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibrarymember{atomic_load_explicit}{shared_ptr}%
\begin{itemdecl}
template<class T> shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{p} is not null.
\tcode{mo} is neither \tcode{memory_order::release} nor \tcode{memory_order::acq_rel}.

\pnum
\returns
\tcode{*p}.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibrarymember{atomic_store}{shared_ptr}%
\begin{itemdecl}
template<class T> void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{p} is not null.

\pnum
\effects
As if by \tcode{atomic_store_explicit(p, r, memory_order::seq_cst)}.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibrarymember{atomic_store_explicit}{shared_ptr}%
\begin{itemdecl}
template<class T> void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{p} is not null.
\tcode{mo} is neither \tcode{memory_order::acquire} nor \tcode{memory_order::acq_rel}.

\pnum
\effects
As if by \tcode{p->swap(r)}.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibrarymember{atomic_exchange}{shared_ptr}%
\begin{itemdecl}
template<class T> shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{p} is not null.

\pnum
\returns
\tcode{atomic_exchange_explicit(p, r, memory_order::seq_cst)}.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibrarymember{atomic_exchange_explicit}{shared_ptr}%
\begin{itemdecl}
template<class T>
shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{p} is not null.

\pnum
\effects
As if by \tcode{p->swap(r)}.

\pnum
\returns
The previous value of \tcode{*p}.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibrarymember{atomic_compare_exchange_weak}{shared_ptr}%
\begin{itemdecl}
template<class T>
bool atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{p} is not null and \tcode{v} is not null.

\pnum
\returns
\begin{codeblock}
atomic_compare_exchange_weak_explicit(p, v, w, memory_order::seq_cst, memory_order::seq_cst)
\end{codeblock}

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibrarymember{atomic_compare_exchange_strong}{shared_ptr}%
\begin{itemdecl}
template<class T>
bool atomic_compare_exchange_strong(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
atomic_compare_exchange_strong_explicit(p, v, w, memory_order::seq_cst,
memory_order::seq_cst)
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{atomic_compare_exchange_weak_explicit}{shared_ptr}%
\indexlibrarymember{atomic_compare_exchange_strong_explicit}{shared_ptr}%
\begin{itemdecl}
template<class T>
bool atomic_compare_exchange_weak_explicit(
shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
memory_order success, memory_order failure);
template<class T>
bool atomic_compare_exchange_strong_explicit(
shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
memory_order success, memory_order failure);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{p} is not null and \tcode{v} is not null.
The \tcode{failure} argument is neither \tcode{memory_order::release} nor
\tcode{memory_order::acq_rel}.

\pnum
\effects
If \tcode{*p} is equivalent to \tcode{*v}, assigns \tcode{w} to
\tcode{*p} and has synchronization semantics corresponding to the value of
\tcode{success}, otherwise assigns \tcode{*p} to \tcode{*v} and has
synchronization semantics corresponding to the value of \tcode{failure}.

\pnum
\returns
\tcode{true} if \tcode{*p} was equivalent to \tcode{*v}, \tcode{false} otherwise.

\pnum
\throws
Nothing.

\pnum
\remarks
Two \tcode{shared_ptr} objects are equivalent if they store the same
pointer value and share ownership.
The weak form may fail spuriously. See~\ref{atomics.types.operations}.
\end{itemdescr}

\rSec1[depr.format]{Deprecated formatting}

\rSec2[depr.format.syn]{Header \tcode{<format>} synopsis}
Expand Down
3 changes: 3 additions & 0 deletions source/xrefdelta.tex
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@
\removedxref{depr.strstreambuf.members}
\removedxref{depr.strstreambuf.virtuals}

% P2869R4 Remove deprecated shared_ptr atomic access
\removedxref{depr.util.smartptr.shared.atomic}

%%% Renamed sections.
%%% Examples:
%
Expand Down