Skip to content

Commit 7e0e1c7

Browse files
authored
Merge 2025-06 LWG Motion 26
P3503R3 Make type-erased allocator use in promise and packaged_task consistent
2 parents cab0d01 + 14e4ec9 commit 7e0e1c7

File tree

1 file changed

+38
-25
lines changed

1 file changed

+38
-25
lines changed

source/threads.tex

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10730,9 +10730,6 @@
1073010730
void set_value_at_thread_exit(@\seebelow@);
1073110731
void set_exception_at_thread_exit(exception_ptr p);
1073210732
};
10733-
10734-
template<class R, class Alloc>
10735-
struct uses_allocator<promise<R>, Alloc>;
1073610733
}
1073710734
\end{codeblock}
1073810735

@@ -10752,20 +10749,6 @@
1075210749
they acquire a single mutex associated with the promise object while updating the
1075310750
promise object.
1075410751

10755-
\indexlibrarymember{uses_allocator}{promise}%
10756-
\begin{itemdecl}
10757-
template<class R, class Alloc>
10758-
struct uses_allocator<promise<R>, Alloc>
10759-
: true_type { };
10760-
\end{itemdecl}
10761-
10762-
\begin{itemdescr}
10763-
\pnum
10764-
\expects
10765-
\tcode{Alloc} meets
10766-
the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}.
10767-
\end{itemdescr}
10768-
1076910752
\indexlibraryctor{promise}%
1077010753
\begin{itemdecl}
1077110754
promise();
@@ -11867,6 +11850,8 @@
1186711850
packaged_task() noexcept;
1186811851
template<class F>
1186911852
explicit packaged_task(F&& f);
11853+
template<class F, class Allocator>
11854+
explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
1187011855
~packaged_task();
1187111856

1187211857
// no copy
@@ -11916,6 +11901,19 @@
1191611901
explicit packaged_task(F&& f);
1191711902
\end{itemdecl}
1191811903

11904+
\begin{itemdescr}
11905+
\pnum
11906+
\effects
11907+
Equivalent to
11908+
\tcode{packaged_task(allocator_arg, allocator<int>(), std::forward<F>(f))}.
11909+
\end{itemdescr}
11910+
11911+
\indexlibraryctor{packaged_task}%
11912+
\begin{itemdecl}
11913+
template<class F, class Allocator>
11914+
explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
11915+
\end{itemdecl}
11916+
1191911917
\begin{itemdescr}
1192011918
\pnum
1192111919
\constraints
@@ -11926,17 +11924,27 @@
1192611924
\mandates
1192711925
\tcode{is_invocable_r_v<R, decay_t<F>\&, ArgTypes...>} is \tcode{true}.
1192811926

11927+
\pnum
11928+
\expects
11929+
\tcode{Allocator} meets the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}.
11930+
1192911931
\pnum
1193011932
\effects
11933+
Let \tcode{A2} be
11934+
\tcode{allocator_traits<Allocator>::rebind_alloc<\unspec>}
11935+
and let \tcode{a2} be an object of type \tcode{A2} initialized with
11936+
\tcode{A2(a)}.
1193111937
Constructs a new \tcode{packaged_task} object with
1193211938
a stored task of type \tcode{decay_t<F>} and a shared state.
1193311939
Initializes the object's stored task with \tcode{std::forward<F>(f)}.
11940+
Uses \tcode{a2} to allocate storage for the shared state and stores a copy
11941+
of \tcode{a2} in the shared state.
1193411942

1193511943
\pnum
1193611944
\throws
11937-
Any exceptions thrown by the copy or move constructor of \tcode{f}, or
11938-
\tcode{bad_alloc} if memory for the internal data structures
11939-
cannot be allocated.
11945+
Any exceptions thrown by the initialization of the stored task.
11946+
If storage for the shared state cannot be allocated, any exception thrown by
11947+
\tcode{A2::allocate}.
1194011948
\end{itemdescr}
1194111949

1194211950
\indexlibraryctor{packaged_task}%
@@ -12146,9 +12154,16 @@
1214612154
\begin{itemdescr}
1214712155
\pnum
1214812156
\effects
12149-
As if \tcode{*this = packaged_task(std::move(f))}, where
12157+
Equivalent to:
12158+
\begin{codeblock}
12159+
if (!valid()) {
12160+
throw future_error(future_errc::no_state);
12161+
}
12162+
*this = packaged_task(allocator_arg, a, std::move(f));
12163+
\end{codeblock}
12164+
where
1215012165
\tcode{f} is the task stored in
12151-
\tcode{*this}.
12166+
\tcode{*this} and \tcode{a} is the allocator stored in the shared state.
1215212167
\begin{note}
1215312168
This constructs a new shared state for \tcode{*this}. The
1215412169
old state is abandoned\iref{futures.state}.
@@ -12157,9 +12172,7 @@
1215712172
\pnum
1215812173
\throws
1215912174
\begin{itemize}
12160-
\item \tcode{bad_alloc} if memory for the new shared state cannot be allocated.
12161-
\item Any exception thrown by the move constructor of the task stored in the shared
12162-
state.
12175+
\item Any exception thrown by the \tcode{packaged_task} constructor.
1216312176
\item \tcode{future_error} with an error condition of \tcode{no_state} if \tcode{*this}
1216412177
has no shared state.
1216512178
\end{itemize}

0 commit comments

Comments
 (0)