Skip to content

Commit bf85ae2

Browse files
AlisdairMtkoeppe
authored andcommitted
P2869R4 Remove deprecated atomic free function API for shared_ptr
The Annex C wording is modeled on the compatibility with C form, and should be revised without the "difficulty of converting" clause, probably with a simple code example in "Effects".
1 parent e6f1ffb commit bf85ae2

File tree

3 files changed

+20
-268
lines changed

3 files changed

+20
-268
lines changed

source/compatibility.tex

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,23 @@
155155
// OK in \CppXXVI{}
156156
\end{codeblock}
157157

158+
\nodiffref
159+
\change
160+
Removal of atomic access API for \tcode{shared_ptr} objects.
161+
\rationale
162+
The old behavior was brittle. \tcode{shared_ptr} objects using the old API were
163+
not protected by the type system, and certain interactions with code not using
164+
this API would, in some cases, silently produce undefined behavior. A complete
165+
type-safe replacement is provided in the form of \tcode{atomic<shared_ptr<T>>}.
166+
\effect
167+
Deletion of an old feature where a superior replacement exists within the
168+
standard.
169+
\difficulty
170+
Violations will be diagnosed by the \Cpp{} translator, as there are no
171+
remaining overloads that would match such calls. Violations are addressed by
172+
replacing affected \tcode{shared_ptr<T>} objects with
173+
\tcode{atomic<shared_ptr<T>>}.
174+
158175
\nodiffref
159176
\change
160177
Remove the \tcode{basic_string::reserve()} overload with no parameters.

source/future.tex

Lines changed: 0 additions & 268 deletions
Original file line numberDiff line numberDiff line change
@@ -675,274 +675,6 @@
675675
\tcode{current}.
676676
\end{itemdescr}
677677

678-
\rSec1[depr.util.smartptr.shared.atomic]{Deprecated \tcode{shared_ptr} atomic access}
679-
680-
\pnum
681-
The header \libheaderref{memory} has the following additions:
682-
683-
\indexlibraryglobal{shared_ptr}%
684-
\begin{codeblock}
685-
namespace std {
686-
template<class T>
687-
bool atomic_is_lock_free(const shared_ptr<T>* p);
688-
689-
template<class T>
690-
shared_ptr<T> atomic_load(const shared_ptr<T>* p);
691-
template<class T>
692-
shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
693-
694-
template<class T>
695-
void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
696-
template<class T>
697-
void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
698-
699-
template<class T>
700-
shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
701-
template<class T>
702-
shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
703-
704-
template<class T>
705-
bool atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
706-
template<class T>
707-
bool atomic_compare_exchange_strong(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
708-
template<class T>
709-
bool atomic_compare_exchange_weak_explicit(
710-
shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
711-
memory_order success, memory_order failure);
712-
template<class T>
713-
bool atomic_compare_exchange_strong_explicit(
714-
shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
715-
memory_order success, memory_order failure);
716-
}
717-
\end{codeblock}
718-
719-
\pnum
720-
Concurrent access to a \tcode{shared_ptr} object from multiple threads does not
721-
introduce a data race if the access is done exclusively via the functions in
722-
this subclause and the instance is passed as their first argument.
723-
724-
\pnum
725-
The meaning of the arguments of type \tcode{memory_order} is explained in~\ref{atomics.order}.
726-
727-
\indexlibrarymember{atomic_is_lock_free}{shared_ptr}%
728-
\begin{itemdecl}
729-
template<class T> bool atomic_is_lock_free(const shared_ptr<T>* p);
730-
\end{itemdecl}
731-
732-
\begin{itemdescr}
733-
\pnum
734-
\expects
735-
\tcode{p} is not null.
736-
737-
\pnum
738-
\returns
739-
\tcode{true} if atomic access to \tcode{*p} is lock-free, \tcode{false} otherwise.
740-
741-
\pnum
742-
\throws
743-
Nothing.
744-
\end{itemdescr}
745-
746-
\indexlibrarymember{atomic_load}{shared_ptr}%
747-
\begin{itemdecl}
748-
template<class T> shared_ptr<T> atomic_load(const shared_ptr<T>* p);
749-
\end{itemdecl}
750-
751-
\begin{itemdescr}
752-
\pnum
753-
\expects
754-
\tcode{p} is not null.
755-
756-
\pnum
757-
\returns
758-
\tcode{atomic_load_explicit(p, memory_order::seq_cst)}.
759-
760-
\pnum
761-
\throws
762-
Nothing.
763-
\end{itemdescr}
764-
765-
\indexlibrarymember{atomic_load_explicit}{shared_ptr}%
766-
\begin{itemdecl}
767-
template<class T> shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
768-
\end{itemdecl}
769-
770-
\begin{itemdescr}
771-
\pnum
772-
\expects
773-
\tcode{p} is not null.
774-
\tcode{mo} is neither \tcode{memory_order::release} nor \tcode{memory_order::acq_rel}.
775-
776-
\pnum
777-
\returns
778-
\tcode{*p}.
779-
780-
\pnum
781-
\throws
782-
Nothing.
783-
\end{itemdescr}
784-
785-
\indexlibrarymember{atomic_store}{shared_ptr}%
786-
\begin{itemdecl}
787-
template<class T> void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
788-
\end{itemdecl}
789-
790-
\begin{itemdescr}
791-
\pnum
792-
\expects
793-
\tcode{p} is not null.
794-
795-
\pnum
796-
\effects
797-
As if by \tcode{atomic_store_explicit(p, r, memory_order::seq_cst)}.
798-
799-
\pnum
800-
\throws
801-
Nothing.
802-
\end{itemdescr}
803-
804-
\indexlibrarymember{atomic_store_explicit}{shared_ptr}%
805-
\begin{itemdecl}
806-
template<class T> void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
807-
\end{itemdecl}
808-
809-
\begin{itemdescr}
810-
\pnum
811-
\expects
812-
\tcode{p} is not null.
813-
\tcode{mo} is neither \tcode{memory_order::acquire} nor \tcode{memory_order::acq_rel}.
814-
815-
\pnum
816-
\effects
817-
As if by \tcode{p->swap(r)}.
818-
819-
\pnum
820-
\throws
821-
Nothing.
822-
\end{itemdescr}
823-
824-
\indexlibrarymember{atomic_exchange}{shared_ptr}%
825-
\begin{itemdecl}
826-
template<class T> shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
827-
\end{itemdecl}
828-
829-
\begin{itemdescr}
830-
\pnum
831-
\expects
832-
\tcode{p} is not null.
833-
834-
\pnum
835-
\returns
836-
\tcode{atomic_exchange_explicit(p, r, memory_order::seq_cst)}.
837-
838-
\pnum
839-
\throws
840-
Nothing.
841-
\end{itemdescr}
842-
843-
\indexlibrarymember{atomic_exchange_explicit}{shared_ptr}%
844-
\begin{itemdecl}
845-
template<class T>
846-
shared_ptr<T> atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
847-
\end{itemdecl}
848-
849-
\begin{itemdescr}
850-
\pnum
851-
\expects
852-
\tcode{p} is not null.
853-
854-
\pnum
855-
\effects
856-
As if by \tcode{p->swap(r)}.
857-
858-
\pnum
859-
\returns
860-
The previous value of \tcode{*p}.
861-
862-
\pnum
863-
\throws
864-
Nothing.
865-
\end{itemdescr}
866-
867-
\indexlibrarymember{atomic_compare_exchange_weak}{shared_ptr}%
868-
\begin{itemdecl}
869-
template<class T>
870-
bool atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
871-
\end{itemdecl}
872-
873-
\begin{itemdescr}
874-
\pnum
875-
\expects
876-
\tcode{p} is not null and \tcode{v} is not null.
877-
878-
\pnum
879-
\returns
880-
\begin{codeblock}
881-
atomic_compare_exchange_weak_explicit(p, v, w, memory_order::seq_cst, memory_order::seq_cst)
882-
\end{codeblock}
883-
884-
\pnum
885-
\throws
886-
Nothing.
887-
\end{itemdescr}
888-
889-
\indexlibrarymember{atomic_compare_exchange_strong}{shared_ptr}%
890-
\begin{itemdecl}
891-
template<class T>
892-
bool atomic_compare_exchange_strong(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
893-
\end{itemdecl}
894-
895-
\begin{itemdescr}
896-
\pnum
897-
\returns
898-
\begin{codeblock}
899-
atomic_compare_exchange_strong_explicit(p, v, w, memory_order::seq_cst,
900-
memory_order::seq_cst)
901-
\end{codeblock}
902-
\end{itemdescr}
903-
904-
\indexlibrarymember{atomic_compare_exchange_weak_explicit}{shared_ptr}%
905-
\indexlibrarymember{atomic_compare_exchange_strong_explicit}{shared_ptr}%
906-
\begin{itemdecl}
907-
template<class T>
908-
bool atomic_compare_exchange_weak_explicit(
909-
shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
910-
memory_order success, memory_order failure);
911-
template<class T>
912-
bool atomic_compare_exchange_strong_explicit(
913-
shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
914-
memory_order success, memory_order failure);
915-
\end{itemdecl}
916-
917-
\begin{itemdescr}
918-
\pnum
919-
\expects
920-
\tcode{p} is not null and \tcode{v} is not null.
921-
The \tcode{failure} argument is neither \tcode{memory_order::release} nor
922-
\tcode{memory_order::acq_rel}.
923-
924-
\pnum
925-
\effects
926-
If \tcode{*p} is equivalent to \tcode{*v}, assigns \tcode{w} to
927-
\tcode{*p} and has synchronization semantics corresponding to the value of
928-
\tcode{success}, otherwise assigns \tcode{*p} to \tcode{*v} and has
929-
synchronization semantics corresponding to the value of \tcode{failure}.
930-
931-
\pnum
932-
\returns
933-
\tcode{true} if \tcode{*p} was equivalent to \tcode{*v}, \tcode{false} otherwise.
934-
935-
\pnum
936-
\throws
937-
Nothing.
938-
939-
\pnum
940-
\remarks
941-
Two \tcode{shared_ptr} objects are equivalent if they store the same
942-
pointer value and share ownership.
943-
The weak form may fail spuriously. See~\ref{atomics.types.operations}.
944-
\end{itemdescr}
945-
946678
\rSec1[depr.format]{Deprecated formatting}
947679

948680
\rSec2[depr.format.syn]{Header \tcode{<format>} synopsis}

source/xrefdelta.tex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
\removedxref{depr.strstreambuf.members}
6060
\removedxref{depr.strstreambuf.virtuals}
6161

62+
% P2869R4 Mandating Annex D
63+
\removedxref{depr.util.smartptr.shared.atomic}
64+
6265
%%% Renamed sections.
6366
%%% Examples:
6467
%

0 commit comments

Comments
 (0)