[futures.promise]

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

## 32.10 Futures [[futures]](futures#promise)

### 32.10.6 Class template promise [futures.promise]

[ð](#lib:promise)

namespace std {template<class R>class promise {public: promise(); template<class Allocator> promise(allocator_arg_t, const Allocator& a);
 promise(promise&& rhs) noexcept;
 promise(const promise&) = delete; ~promise(); // assignment promise& operator=(promise&& rhs) noexcept;
 promise& operator=(const promise&) = delete; void swap(promise& other) noexcept; // retrieving the result future<R> get_future(); // setting the resultvoid set_value(*see below*); void set_exception(exception_ptr p); // setting the result with deferred notificationvoid set_value_at_thread_exit(*see below*); void set_exception_at_thread_exit(exception_ptr p); };}

[1](#1)

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

For the primary template, R shall be an object type that
meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#1.sentence-1)

[2](#2)

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

The implementation provides the template promise and two specializations,promise<R&> and promise<​void>[.](#2.sentence-1)

These differ only in the argument type
of the member functions set_value and set_value_at_thread_exit,
as set out in their descriptions, below[.](#2.sentence-2)

[3](#3)

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

The set_value, set_exception, set_value_at_thread_exit,
and set_exception_at_thread_exit member functions behave as though
they acquire a single mutex associated with the promise object while updating the
promise object[.](#3.sentence-1)

[ð](#lib:promise,constructor)

`promise();
template<class Allocator>
  promise(allocator_arg_t, const Allocator& a);
`

[4](#4)

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

*Effects*: Creates a shared state[.](#4.sentence-1)

The second
constructor uses the allocator a to allocate memory for the shared
state[.](#4.sentence-2)

[ð](#lib:promise,constructor_)

`promise(promise&& rhs) noexcept;
`

[5](#5)

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

*Effects*: Transfers ownership of the shared state
of rhs (if any) to the newly-constructed object[.](#5.sentence-1)

[6](#6)

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

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

[ð](#lib:promise,destructor)

`~promise();
`

[7](#7)

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

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

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

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

[8](#8)

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

*Effects*: Abandons any shared state ([[futures.state]](futures.state "32.10.5 Shared state")) and then as ifpromise(std​::​move(rhs)).swap(*this)[.](#8.sentence-1)

[9](#9)

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

*Returns*: *this[.](#9.sentence-1)

[ð](#lib:swap,promise)

`void swap(promise& other) noexcept;
`

[10](#10)

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

*Effects*: Exchanges the shared state of *this and other[.](#10.sentence-1)

[11](#11)

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

*Postconditions*: *this has the shared state (if any) that other had
prior to the call to swap[.](#11.sentence-1)

other has the shared state (if any) that*this had prior to the call to swap[.](#11.sentence-2)

[ð](#lib:get_future,promise)

`future<R> get_future();
`

[12](#12)

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

*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 toset_value,set_exception,set_value_at_thread_exit, orset_exception_at_thread_exit[.](#12.sentence-1)

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

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

â *end note*]

[13](#13)

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

*Returns*: A future<R> object with the same shared state as*this[.](#13.sentence-1)

[14](#14)

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

*Throws*: future_error if *this has no shared state or ifget_future has already been called on a promise with the same
shared state as *this[.](#14.sentence-1)

[15](#15)

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

*Error conditions*: 

- [(15.1)](#15.1)

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

- [(15.2)](#15.2)

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

[ð](#lib:set_value,promise)

`void promise::set_value(const R& r);
void promise::set_value(R&& r);
void promise<R&>::set_value(R& r);
void promise<void>::set_value();
`

[16](#16)

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

*Effects*: Atomically stores the value r in the shared state and
makes that state ready ([[futures.state]](futures.state "32.10.5 Shared state"))[.](#16.sentence-1)

[17](#17)

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

*Throws*: 

- [(17.1)](#17.1)

future_error if its shared state
already has a stored value or exception, or

- [(17.2)](#17.2)

for the first version, any exception thrown by the constructor selected to copy an object of R, or

- [(17.3)](#17.3)

for the second version, any exception thrown by the constructor selected to move an object of R[.](#17.sentence-1)

[18](#18)

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

*Error conditions*: 

- [(18.1)](#18.1)

  promise_already_satisfied if its shared state
already has a stored value or exception[.](#18.1.sentence-1)

- [(18.2)](#18.2)

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

[ð](#lib:set_exception,promise)

`void set_exception(exception_ptr p);
`

[19](#19)

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

*Preconditions*: p is not null[.](#19.sentence-1)

[20](#20)

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

*Effects*: Atomically stores the exception pointer p in the shared state
and makes that state ready ([[futures.state]](futures.state "32.10.5 Shared state"))[.](#20.sentence-1)

[21](#21)

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

*Throws*: future_error if its shared state
already has a stored value or exception[.](#21.sentence-1)

[22](#22)

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

*Error conditions*: 

- [(22.1)](#22.1)

  promise_already_satisfied if its shared state
already has a stored value or exception[.](#22.1.sentence-1)

- [(22.2)](#22.2)

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

[ð](#lib:set_value_at_thread_exit,promise)

`void promise::set_value_at_thread_exit(const R& r);
void promise::set_value_at_thread_exit(R&& r);
void promise<R&>::set_value_at_thread_exit(R& r);
void promise<void>::set_value_at_thread_exit();
`

[23](#23)

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

*Effects*: Stores the value r in the shared state without making that
state ready immediately[.](#23.sentence-1)

Schedules that 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[.](#23.sentence-2)

[24](#24)

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

*Throws*: 

- [(24.1)](#24.1)

future_error if its shared state
already has a stored value or exception, or

- [(24.2)](#24.2)

for the first version, any exception thrown by the constructor selected to copy an object of R, or

- [(24.3)](#24.3)

for the second version, any exception thrown by the constructor selected to move an object of R[.](#24.sentence-1)

[25](#25)

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

*Error conditions*: 

- [(25.1)](#25.1)

  promise_already_satisfied if its shared state
already has a stored value or exception[.](#25.1.sentence-1)

- [(25.2)](#25.2)

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

[ð](#lib:set_exception_at_thread_exit,promise)

`void set_exception_at_thread_exit(exception_ptr p);
`

[26](#26)

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

*Preconditions*: p is not null[.](#26.sentence-1)

[27](#27)

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

*Effects*: Stores the exception pointer p in the shared state without
making that state ready immediately[.](#27.sentence-1)

Schedules that 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[.](#27.sentence-2)

[28](#28)

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

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

[29](#29)

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

*Error conditions*: 

- [(29.1)](#29.1)

  promise_already_satisfied if its shared state
already has a stored value or exception[.](#29.1.sentence-1)

- [(29.2)](#29.2)

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

[ð](#lib:swap,promise_)

`template<class R>
  void swap(promise<R>& x, promise<R>& y) noexcept;
`

[30](#30)

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

*Effects*: As if by x.swap(y)[.](#30.sentence-1)
