Document Number: | N3041=10-0031 |
Date: | 2010-02-15 |
Project: | Programming Language C++ |
Detlef Vollmann <dv@vollmann.ch>
The adoption of N2996 and N2997 at the same meeting caused some editorial trouble, as the papers both were based on the previous working paper and were not properly aligned. [Big apologies to the editor!]
This paper tries to clean up the whole [futures] sub-clause.
Thanks to Anthony Williams, Jonathan Wakely, Daniel Krügler, Alisdair Meredith and Alberto Ganesh Barbati for their comments and contributions to this paper.
In 30.6.1 [futures.overview], header <future>
synopsis:
Add to enum class future_errc
:
result_not_asynchronous
In 30.6.1 [futures.overview], header <future>
synopsis:
Change:
constexpr error_code make_error_code(future_errc e); constexpr error_condition make_error_condition(future_errc e); extern const error_category* const future_category;
to
error_code make_error_code(future_errc e); error_condition make_error_condition(future_errc e); const error_category& future_category();
In 30.6.1 [futures.overview], header <future>
synopsis, after declaration of class template packaged_task
:
Add:
template <class R> void swap(packaged_task<R(ArgTypes...)>&, packaged_task<R(ArgTypes...)>&)
In 30.6.1 [futures.overview], header <future>
synopsis:
Change:
template <class F, class... Args> future<typename F::result_type> async(F&& f, Args&&... args); template <class F, class... Args> future<typename F::result_type> async(launch policy, F&& f, Args&&... args);
to
template <class F, class... Args> future<typename result_of<F(Args...)>::type> async(F&& f, Args&&... args); template <class F, class... Args> future<typename result_of<F(Args...)>::type> async(launch policy, F&& f, Args&&... args);
In 30.6.2 [futures.errors] near paragraph 1:
Change:
extern const error_category* const future_category;
future_category
shall point to a statically initialized
object of a type derived from class error_category
.
const error_category& future_category();
error_category
.
constexpr error_code make_error_code(future_errc e);
error_code(static_cast<int>(e), *future_category)
.
to
error_code make_error_code(future_errc e);
error_code(static_cast<int>(e), future_category())
.
constexpr error_code make_error_condition(future_errc e);
error_condition(static_cast<int>(e), *future_category)
.
to
error_condition make_error_condition(future_errc e);
error_condition(static_cast<int>(e), future_category())
.
In 30.6.4 [futures.state], title:
Change:
Associated state
to
Associated asynchronous state
In 30.6.4 [futures.state], paragraph 1:
Change:
If fully initialized,
objects of type future
([future.future]),
shared_future
([future.shared_future]),
atomic_future
([future.atomic_future]),
promise
([future.promise) and
packaged_task
([future.task]) reference
some state that is potentially shared between several such objects.
to
If fully initialized, objects that synchronize results across threads can reference some state that is potentially shared between several such objects.
[Note: Futures, promises and tasks defined in this clause reference such associated asynchronous state. --end note]
In 30.6.4 [futures.state], paragraph 2:
Change:
This associated state consists of some state information and some (possibly not yet evaluated) result, which can be a (possibly void) value or an exception.
to
This associated asynchronous state consists of some state information and some (possibly not yet evaluated) result, which can be a (possibly void) value or an exception.
[Note:
The result can be any kind of object including a function to compute
that result, as used by async
for policy=sync
.
--end note]
Before 20.6.4 [futures.state], paragraph 3:
Add:
Objects that read results from associated asynchronous state are called asynchronous return object.
In 30.6.4 [futures.state], paragraph 3:
Change:
The result of such an associated state can be set by
promise::set_value
promise::set_exception
packaged_task::operator()
to
Objects that provide such a result, are called asynchronous providers. The result of such an associated asynchronous state is set by respective functions on the asynchronous provider.
[Note: Such as promises or tasks. --end note]
In 30.6.5 [futures.promise], synopsis:
Remove:
void set_value(const R& r);
In 30.6.5 [futures.promise], paragraph 12:
Change:
swap(*this, other)
to
*this
and other
.
In 30.6.5 [futures.promise], after paragraph 13:
Add:
In 30.6.5 [futures.promise], before paragraph 17:
Change:
void set_value(const R& r);
to
void promise::set_value(const R& r);
In 30.6.5 [futures.promise], paragraph 18:
Change:
future_error
if its associated state is already ready.
to
future_error
if its associated state is already ready
or, for the first version an exception thrown by the
copy constructor of R
, or for the second version an exception
thrown by the move constructor of R
.
In 30.6.6 [futures.unique_future], paragraph 1:
Change:
The class template future
defines a type for
asynchronous return objects which do not share their associated
state. A default-constructed future
has no
associated state. future
objects with associated
state can only be created by use of
promise
([future.promise]) or packaged_task
([future.task]) objects, and share their associated state with
that promise
or packaged_task
. Their
values or exceptions can be set by use of the promise
([future.promise]) or packaged_task
([future.task])
object that shares the same associated state.
to
The class template future
defines a type for
asynchronous return objects which do not share their associated
asynchronous state with other asynchronous return objects.
A default-constructed future
has no
associated asynchronous state. future
objects with associated
asynchronous state can be created by functions on asynchronous providers
([futures.state] or by the move constructor
and share their associated asynchronous state with the original
asynchronous provider.
The result (values or exceptions) of future
objects
can be set by calling a respective function on an object that
shares the same associated asynchronous state.
In 30.6.6 [futures.unique_future], paragraph 3, introduction:
Change:
The effect of calling any member function other than the destructor
or the move-assignment operator on a future
for which valid() == false
is undefined.
to
The effect of calling any member function other than the destructor
or the move-assignment operator or valid()
on a
future
for which valid() == false
is undefined.
In 30.6.6 [futures.unique_future], paragraph 21, wait()
:
Change:
valid() == true
to
valid() == true
In 30.6.6 [futures.unique_future], paragraph 22ff, wait_for
:
Change:
valid() == true
rel_time
has elapsed.
true
only if the associated state is ready.
to
valid() == true
rel_time
has elapsed.
true
only if the associated asynchronous state is ready.
future_error
if an error condition occurs.
result_not_asynchronous
— if the associated
asynchronous state is shared with an object that computes the result
in the same thread in which wait_for()
is called.
In 30.6.6 [futures.unique_future], paragraph 25ff, wait_until
:
Change:
valid() == true
abs_time
.
true
only if the associated state is ready.
to
valid() == true
abs_time
.
true
only if the associated asynchronous state is ready.
future_error
if an error condition occurs.
result_not_asynchronous
— if the associated
asynchronous state is shared with an object that computes the result
in the same thread in which wait_until()
is called.
In 30.6.7 [future.shared_future], paragraph 1, introduction:
Change:
The class template shared_future
defines a type for
asynchronous return objects which may share their associated state. A
default-constructed shared_future
has no associated
state. A shared_future
object with associated state can
only be created from another shared_future
with
associated state or a future
object with
associated state. Their values or exceptions can be set by use of
a promise
([future.promise])
or packaged_task
([future.task]) object that shares the
same associated state.
to
The class template shared_future
defines a type for
asynchronous return objects which may share their associated
asynchronous state with other asynchronous return objects.
A default-constructed shared_future
has no associated
asynchronous state.
A shared_future
object with associated asynchronous state
state can be created by conversion from a future
object
and share their associated asynchronous state with the original
asynchronous provider of the associated state.
The result (values or exceptions) of shared_future
objects
can be set by calling a respective function on an object that
shares the same associated asynchronous state.
In 30.6.7 [future.shared_future], after paragraph 2, introduction:
Add:
The effect of calling any member function other than
the destructor or the move-assignment operator or
valid()
on a shared_future
for
which valid() == false
is undefined.
In 30.6.7 [future.shared_future], paragraph 4, shared_future()
:
Change:
shared_future
that doesn't
refer to an associated asynchronous state.
to
shared_future
that doesn't
refer to an associated state.
valid() == false
In 30.6.7 [future.shared_future], paragraph 22, wait()
:
Change:
to
valid() == true
In 30.6.7 [future.shared_future], paragraph 23ff, wait_for()
:
Change:
rel_time
has elapsed.
true
only if the associated state is ready.
to
valid() == true
rel_time
has elapsed.
true
only if the associated asynchronous state is ready.
future_error
if an error condition occurs.
result_not_asynchronous
— if the associated
asynchronous state is shared with an object that computes the result
in the same thread in which wait_for()
is called.
In 30.6.7 [future.shared_future], paragraph 25ff, wait_until()
:
Change:
abs_time
.
true
only if the associated state is ready.
to
valid() == true
abs_time
.
true
only if the associated asynchronous state is ready.
future_error
if an error condition occurs.
result_not_asynchronous
— if the associated
asynchronous state is shared with an object that computes the result
in the same thread in which wait_until()
is called.
In 30.6.8 [futures.atomic_future], paragraph 1:
Change:
The class template atomic_future
defines a type for
asynchronous return objects.
These objects can only be created by use of
promise
([future.promise])
or packaged_task
([future.task]) objects.
Their values or exceptions can be set
by use of promise
([future.promise]) objects.
to
The class template atomic_future
defines a type for
asynchronous return objects which may share their associated
asynchronous state with other asynchronous return objects.
A single atomic_future
object may be shared between
different threads.
A default-constructed atomic_future
has no
associated asynchronous state. atomic_future
objects with associated asynchronous state can be created by
conversion from a future
object
and share their associated asynchronous state with the original
asynchronous provider of the associated state.
The result (values or exceptions) of atomic_future
objects
can be set by calling a respective function on an object that
shares the same associated asynchronous state.
In 30.6.8 [futures.atomic_future], paragraph 6, atomic_future(atomic_future<R>&& rhs)
:
Change:
atomic_future(atomic_future&& rhs);
to
atomic_future(future<R>&& rhs);
In 30.6.8 [futures.atomic_future], paragraph 7ff, operator=()
:
Change:
this->valid() == false
rhs
to *this
.
[Note: So *this
refers to the same associated
state as rhs
(if any). --end note]
rhs
and a release operation on the left-hand side.
to
this->valid() == false
rhs
to *this
.
[Note: So *this
refers to the same associated
asynchronous state as rhs
(if any). --end note]
rhs
and a release operation on *this
.
In 30.6.8 [futures.atomic_future], paragraph 17, is_ready()
ff:
Remove:
bool is_ready() const;
valid() == true
true
only if the associated state is ready.
bool has_exception() const;
true
only if the associated state is ready
and the associated state contains an exception.
bool has_value() const;
true
only if the associated state is ready
and the associated state contains a value.
In 30.6.8 [futures.atomic_future], paragraph 22, wait()
:
Change:
to
future_error
if an error condition occurs.
no_state
— if *this
has no
associated asynchronous state.
In 30.6.8 [futures.atomic_future], paragraph 23ff, wait_for
:
Change:
rel_time
has elapsed.
true
only if the associated state is ready.
to
rel_time
has elapsed.
true
only if the associated asynchronous state is ready.
future_error
if an error condition occurs.
result_not_asynchronous
if the associated asynchronous state
is shared with an object that computes the result in the same thread
in which wait_for()
is called.no_state
if *this
has no associated
asynchronous state.
In 30.6.8 [futures.atomic_future], paragraph 25ff, wait_until()
:
Change:
abs_time
.
true
only if the associated state is ready.
to
abs_time
.
true
only if the associated asynchronous state is ready.
future_error
if an error condition occurs.
result_not_asynchronous
if the associated asynchronous state
is shared with an object that computes the result in the same thread
in which wait_until()
is called.no_state
if *this
has no associated
asynchronous state.
In 30.6.9 [futures.async], just after the title:
Add:
async
provides a mechanism to launch a function potentially
in a new thread and provides the result of the function in a
future
object, with which it shares an associated
asynchronous state.
In 30.6.9 [futures.async] synopsis:
Change:
template <class F, class... Args> future<typename F::result_type> async(F&& f, Args&&... args); template <class F, class... Args> future<typename F::result_type> launch policy, async(F&& f, Args&&... args);
to
template <class F, class... Args> future<typename result_of<F(Args...)>::type> async(F&& f, Args&&... args); template <class F, class... Args> future<typename result_of<F(Args...)>::type> async(launch policy, F&& f, Args&&... args);
In 30.6.9 [futures.async], paragraph 2, after the Returns: clause: Add:
wait()
or other functions defined
in terms of wait()
)
on asynchronous return objects that share the associated
asynchronous state created by this async()
call synchronize.
The first of such calls shall invoke the deferred function in the thread
that called the waiting function;
all other calls waiting for the same result shall block
until the deferred function has completed.
The completion of the invocation of the deferred function happens-before
the calls to the waiting functions return.
In 30.6.9 [futures.async], after paragraph 3 (Synchronization):
Add:
If the invocation is not deferred, a call to a waiting function
on asynchronous return objects that share the associated
asynchronous state created by this async()
call
shall block until the associated thread has completed.
In 30.6.9 [futures.async], after paragraph 5:
Add:
decay<F>::type
is std::launch
.
In 30.6.10 [futures.futures_task], synopsis, after definition
of class template packaged_task
:
Add:
template <class R, class... Argtypes> void swap(packaged_task<R(ArgTypes...)>&, packaged_task<R(ArgTypes...)>&)
In 30.6.10 [futures.futures_task], after paragraph 20:
Add:
template <class R, class... Argtypes> void swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y)
x.swap(y)