[futures.task.members]

# 32 Concurrency support library [[thread]](./#thread)

## 32.10 Futures [[futures]](futures#task.members)

### 32.10.10 Class template packaged_task [[futures.task]](futures.task#members)

#### 32.10.10.2 Member functions [futures.task.members]

[ð](#lib:packaged_task,constructor)

`packaged_task() noexcept;
`

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12606)

*Effects*: The object has no shared state and no stored task[.](#1.sentence-1)

[ð](#lib:packaged_task,constructor_)

`template<class F>
  explicit packaged_task(F&& f);
`

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12618)

*Effects*: Equivalent topackaged_task(allocator_arg, allocator<int>(), std​::​forward<F>(f))[.](#2.sentence-1)

[ð](#lib:packaged_task,constructor__)

`template<class F, class Allocator>
  explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
`

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12631)

*Constraints*: remove_cvref_t<F> is not the same type as packaged_task<R(ArgTypes...)>[.](#3.sentence-1)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12636)

*Mandates*: is_invocable_r_v<R, decay_t<F>&, ArgTypes...> is true[.](#4.sentence-1)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12640)

*Preconditions*: Allocator meets the *Cpp17Allocator* requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1 General"))[.](#5.sentence-1)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12644)

*Effects*: Let A2 beallocator_traits<Allocator>​::​rebind_alloc<*unspecified*> and let a2 be an object of type A2 initialized withA2(a)[.](#6.sentence-1)

Constructs a new packaged_task object with
a stored task of type decay_t<F> and a shared state[.](#6.sentence-2)

Initializes the object's stored task with std​::​forward<F>(f)[.](#6.sentence-3)

Uses a2 to allocate storage for the shared state and stores a copy
of a2 in the shared state[.](#6.sentence-4)

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12656)

*Throws*: Any exceptions thrown by the initialization of the stored task[.](#7.sentence-1)

If storage for the shared state cannot be allocated, any exception thrown byA2​::​allocate[.](#7.sentence-2)

[ð](#lib:packaged_task,constructor___)

`template<class F> packaged_task(F) -> packaged_task<see below>;
`

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12669)

*Constraints*: &F​::​operator() is well-formed when
treated as an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3 Context dependence")) and either

- [(8.1)](#8.1)

F​::​operator() is a non-static member function anddecltype(​&F​::​operator()) is either of the formR(G​::​*)(A...) cv &opt noexceptopt or of the formR(*)(G, A...) noexceptopt for a type G, or

- [(8.2)](#8.2)

F​::​operator() is a static member function anddecltype(&F​::​operator()) is of the formR(*)(A...) noexceptopt[.](#8.sentence-1)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12687)

*Remarks*: The deduced type is packaged_task<R(A...)>[.](#9.sentence-1)

[ð](#lib:packaged_task,constructor____)

`packaged_task(packaged_task&& rhs) noexcept;
`

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12698)

*Effects*: Transfers ownership ofrhs's shared state to *this, leaving rhs with no
shared state[.](#10.sentence-1)

Moves the stored task from rhs to *this[.](#10.sentence-2)

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12704)

*Postconditions*: rhs has no shared state[.](#11.sentence-1)

[ð](#lib:operator=,packaged_task)

`packaged_task& operator=(packaged_task&& rhs) noexcept;
`

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12715)

*Effects*: 

- [(12.1)](#12.1)

Releases any shared state ([[futures.state]](futures.state "32.10.5 Shared state"));

- [(12.2)](#12.2)

calls packaged_task(std​::​move(rhs)).swap(*this)[.](#12.sentence-1)

[ð](#lib:packaged_task,destructor)

`~packaged_task();
`

[13](#13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12731)

*Effects*: Abandons any shared state ([[futures.state]](futures.state "32.10.5 Shared state"))[.](#13.sentence-1)

[ð](#lib:swap,packaged_task)

`void swap(packaged_task& other) noexcept;
`

[14](#14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12742)

*Effects*: Exchanges the shared states and stored tasks of *this and other[.](#14.sentence-1)

[15](#15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12746)

*Postconditions*: *this has the same shared state
and stored task (if any) as other prior to the call to swap[.](#15.sentence-1)

other has the same shared state
and stored task (if any)
as *this prior to the call to swap[.](#15.sentence-2)

[ð](#lib:valid,packaged_task)

`bool valid() const noexcept;
`

[16](#16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12761)

*Returns*: true only if *this has a shared state[.](#16.sentence-1)

[ð](#lib:get_future,packaged_task)

`future<R> get_future();
`

[17](#17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12772)

*Synchronization*: Calls to this function do not introduce
data races ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races")) with calls tooperator() ormake_ready_at_thread_exit[.](#17.sentence-1)

[*Note [1](#note-1)*:

Such calls need not synchronize with each other[.](#17.sentence-2)

â *end note*]

[18](#18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12782)

*Returns*: A future object that shares the same shared state as *this[.](#18.sentence-1)

[19](#19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12786)

*Throws*: A future_error object if an error occurs[.](#19.sentence-1)

[20](#20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12790)

*Error conditions*: 

- [(20.1)](#20.1)

  future_already_retrieved if get_future has already been called on
a packaged_task object with the same shared state as *this[.](#20.1.sentence-1)

- [(20.2)](#20.2)

  no_state if *this has no shared state[.](#20.2.sentence-1)

[ð](#lib:operator(),packaged_task)

`void operator()(ArgTypes... args);
`

[21](#21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12805)

*Effects*: As if by *INVOKE*<R>(f, t1, t2, …, tN) ([[func.require]](func.require "22.10.4 Requirements")),
where f is the
stored task of *this andt1, t2, …, tN are the values in args...[.](#21.sentence-1)

If the task returns normally,
the return value is stored as the asynchronous result in the shared state of*this, otherwise the exception thrown by the task is stored[.](#21.sentence-2)

The
shared state of *this is made ready, and any threads blocked in a
function waiting for
the shared state of *this to become ready are unblocked[.](#21.sentence-3)

[22](#22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12817)

*Throws*: A future_error exception object if there is no shared
state or the stored task has already been invoked[.](#22.sentence-1)

[23](#23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12822)

*Error conditions*: 

- [(23.1)](#23.1)

  promise_already_satisfied if
the stored task has already been invoked[.](#23.1.sentence-1)

- [(23.2)](#23.2)

  no_state if *this has no shared state[.](#23.2.sentence-1)

[ð](#lib:make_ready_at_thread_exit,packaged_task)

`void make_ready_at_thread_exit(ArgTypes... args);
`

[24](#24)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12837)

*Effects*: As if by *INVOKE*<R>(f, t1, t2, …, tN) ([[func.require]](func.require "22.10.4 Requirements")),
where f is the stored task andt1, t2, …, tN are the values in args...[.](#24.sentence-1)

If the task returns normally,
the return value is stored as the asynchronous result in the shared state of*this, otherwise the exception thrown by the task is stored[.](#24.sentence-2)

In either
case, this is done without making that state ready ([[futures.state]](futures.state "32.10.5 Shared state")) immediately[.](#24.sentence-3)

Schedules
the shared state to be made ready when the current thread exits,
after all objects with thread storage duration associated with the current thread
have been destroyed[.](#24.sentence-4)

[25](#25)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12849)

*Throws*: future_error if an error condition occurs[.](#25.sentence-1)

[26](#26)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12853)

*Error conditions*: 

- [(26.1)](#26.1)

  promise_already_satisfied if the
stored task has already been invoked[.](#26.1.sentence-1)

- [(26.2)](#26.2)

  no_state if *this has no shared state[.](#26.2.sentence-1)

[ð](#lib:reset,packaged_task)

`void reset();
`

[27](#27)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12868)

*Effects*: Equivalent to:if (!valid()) {throw future_error(future_errc::no_state);}*this = packaged_task(allocator_arg, a, std::move(f)); wheref is the task stored in*this and a is the allocator stored in the shared state[.](#27.sentence-1)

[*Note [2](#note-2)*:

This constructs a new shared state for *this[.](#27.sentence-2)

The
old state is abandoned ([[futures.state]](futures.state "32.10.5 Shared state"))[.](#27.sentence-3)

â *end note*]

[28](#28)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12885)

*Throws*: 

- [(28.1)](#28.1)

  Any exception thrown by the packaged_task constructor[.](#28.1.sentence-1)

- [(28.2)](#28.2)

  future_error with an error condition of no_state if *this has no shared state[.](#28.2.sentence-1)
