[/
  (C) Copyright 2008-9 Anthony Williams.
  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE_1_0.txt or copy at
  http://www.boost.org/LICENSE_1_0.txt).
]

[section:reference Futures Reference]

[section:future_state `state` enum]

    namespace future_state
    {
        enum state {uninitialized, waiting, ready};
    }

[endsect]

[section:unique_future `unique_future` class template]

    template <typename R>
    class unique_future
    {
        unique_future(unique_future & rhs);// = delete;
        unique_future& operator=(unique_future& rhs);// = delete;

    public:
        typedef future_state::state state;

        unique_future();
        ~unique_future();

        // move support
        unique_future(unique_future && other);
        unique_future& operator=(unique_future && other);

        void swap(unique_future& other);

        // retrieving the value
        R&& get();        

        // functions to check state
        state get_state() const;
        bool is_ready() const;        
        bool has_exception() const;        
        bool has_value() const;        

        // waiting for the result to be ready
        void wait() const;        
        template<typename Duration>
        bool timed_wait(Duration const& rel_time) const;
        bool timed_wait_until(boost::system_time const& abs_time) const;
    };

[section:default_constructor Default Constructor]

    unique_future();

[variablelist

[[Effects:] [Constructs an uninitialized future.]]

[[Postconditions:] [[unique_future_is_ready_link `this->is_ready`] returns `false`. [unique_future_get_state_link
`this->get_state()`] returns __uninitialized__.]]

[[Throws:] [Nothing.]]

]

[endsect]

[section:destructor Destructor]

    ~unique_future();

[variablelist

[[Effects:] [Destroys `*this`.]]

[[Throws:] [Nothing.]]

]

[endsect]

[section:move_constructor Move Constructor]

    unique_future(unique_future && other);

[variablelist

[[Effects:] [Constructs a new future, and transfers ownership of the asynchronous result associated with `other` to `*this`.]]

[[Postconditions:] [[unique_future_get_state_link `this->get_state()`] returns the value of `other->get_state()` prior to the
call. `other->get_state()` returns __uninitialized__. If `other` was associated with an asynchronous result, that result is now
associated with `*this`. `other` is not associated with any asynchronous result.]]

[[Throws:] [Nothing.]]

[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]]

]

[endsect]

[section:move_assignment Move Assignment Operator]

    unique_future& operator=(unique_future && other);

[variablelist

[[Effects:] [Transfers ownership of the asynchronous result associated with `other` to `*this`.]]

[[Postconditions:] [[unique_future_get_state_link `this->get_state()`] returns the value of `other->get_state()` prior to the
call. `other->get_state()` returns __uninitialized__. If `other` was associated with an asynchronous result, that result is now
associated with `*this`. `other` is not associated with any asynchronous result. If `*this` was associated with an asynchronous
result prior to the call, that result no longer has an associated __unique_future__ instance.]]

[[Throws:] [Nothing.]]

[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]]

]

[endsect]

[section:swap Member function `swap()`]

    void swap(unique_future & other);

[variablelist

[[Effects:] [Swaps ownership of the asynchronous results associated with `other` and `*this`.]]

[[Postconditions:] [[unique_future_get_state_link `this->get_state()`] returns the value of `other->get_state()` prior to the
call. `other->get_state()` returns the value of `this->get_state()` prior to the call. If `other` was associated with an
asynchronous result, that result is now associated with `*this`, otherwise `*this` has no associated result. If `*this` was
associated with an asynchronous result, that result is now associated with `other`, otherwise `other` has no associated result.]]

[[Throws:] [Nothing.]]

]

[endsect]


[section:get Member function `get()`]

    R&& get();
    R& unique_future<R&>::get();
    void unique_future<void>::get();

[variablelist

[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready as-if by a call to
__unique_future_wait__, and retrieves the result (whether that is a value or an exception).]]

[[Returns:] [If the result type `R` is a reference, returns the stored reference. If `R` is `void`, there is no return
value. Otherwise, returns an rvalue-reference to the value stored in the asynchronous result.]]

[[Postconditions:] [[unique_future_is_ready_link `this->is_ready()`] returns `true`. [unique_future_get_state_link
`this->get_state()`] returns __ready__.]]

[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception stored in the
asynchronous result in place of a value.]]

[[Notes:] [`get()` is an ['interruption point].]]

]

[endsect]

[section:wait Member function `wait()`]

    void wait();

[variablelist

[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready. If the result is not ready on
entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]]

[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
['wait callback] if such a callback is called.]]

[[Postconditions:] [[unique_future_is_ready_link `this->is_ready()`] returns `true`. [unique_future_get_state_link
`this->get_state()`] returns __ready__.]]

[[Notes:] [`wait()` is an ['interruption point].]]

]

[endsect]

[section:timed_wait_duration Member function `timed_wait()`]

    template<typename Duration>
    bool timed_wait(Duration const& wait_duration);

[variablelist

[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time specified by
`wait_duration` has elapsed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is
invoked prior to waiting.]]

[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has
elapsed, `false` otherwise.]]

[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
['wait callback] if such a callback is called.]]

[[Postconditions:] [If this call returned `true`, then [unique_future_is_ready_link `this->is_ready()`] returns `true` and
[unique_future_get_state_link `this->get_state()`] returns __ready__.]]

[[Notes:] [`timed_wait()` is an ['interruption point]. `Duration` must be a type that meets the Boost.DateTime time duration requirements.]]

]

[endsect]

[section:timed_wait_absolute Member function `timed_wait()`]

    bool timed_wait(boost::system_time const& wait_timeout);

[variablelist

[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time point specified by
`wait_timeout` has passed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is invoked
prior to waiting.]]

[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has
passed, `false` otherwise.]]

[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
['wait callback] if such a callback is called.]]

[[Postconditions:] [If this call returned `true`, then [unique_future_is_ready_link `this->is_ready()`] returns `true` and
[unique_future_get_state_link `this->get_state()`] returns __ready__.]]

[[Notes:] [`timed_wait()` is an ['interruption point].]]

]

[endsect]


[section:is_ready Member function `is_ready()`]

    bool is_ready();

[variablelist

[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set.]]

[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready for retrieval, `false`
otherwise.]]

[[Throws:] [Nothing.]]

]

[endsect]

[section:has_value Member function `has_value()`]

    bool has_value();

[variablelist

[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with a value rather than an exception.]]

[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a
stored value, `false` otherwise.]]

[[Throws:] [Nothing.]]

]

[endsect]

[section:has_exception Member function `has_exception()`]

    bool has_exception();

[variablelist

[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with an exception rather than a value.]]

[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a
stored exception, `false` otherwise.]]

[[Throws:] [Nothing.]]

]

[endsect]

[section:get_state Member function `get_state()`]

    future_state::state get_state();

[variablelist

[[Effects:] [Determine the state of the asynchronous result associated with `*this`, if any.]]

[[Returns:] [__uninitialized__ if `*this` is not associated with an asynchronous result. __ready__ if the asynchronous result
associated with `*this` is ready for retrieval, __waiting__ otherwise.]]

[[Throws:] [Nothing.]]

]

[endsect]


[endsect]

[section:shared_future `shared_future` class template]

    template <typename R>
    class shared_future
    {
    public:
        typedef future_state::state state;

        shared_future();
        ~shared_future();

        // copy support
        shared_future(shared_future const& other);
        shared_future& operator=(shared_future const& other);

        // move support
        shared_future(shared_future && other);
        shared_future(unique_future<R> && other);
        shared_future& operator=(shared_future && other);
        shared_future& operator=(unique_future<R> && other);

        void swap(shared_future& other);

        // retrieving the value
        R get();
        
        // functions to check state, and wait for ready
        state get_state() const;
        bool is_ready() const;
        bool has_exception() const;
        bool has_value() const;

        // waiting for the result to be ready
        void wait() const;        
        template<typename Duration>
        bool timed_wait(Duration const& rel_time) const;
        bool timed_wait_until(boost::system_time const& abs_time) const;        
    };

[section:default_constructor Default Constructor]

    shared_future();

[variablelist

[[Effects:] [Constructs an uninitialized future.]]

[[Postconditions:] [[shared_future_is_ready_link `this->is_ready`] returns `false`. [shared_future_get_state_link
`this->get_state()`] returns __uninitialized__.]]

[[Throws:] [Nothing.]]

]

[endsect]

[section:get Member function `get()`]

    const R& get();

[variablelist

[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready as-if by a call to
__shared_future_wait__, and returns a `const` reference to the result.]]

[[Returns:] [If the result type `R` is a reference, returns the stored reference. If `R` is `void`, there is no return
value. Otherwise, returns a `const` reference to the value stored in the asynchronous result.]]

[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the
result associated with `*this` is not ready at the point of the call, and the current thread is interrupted.]]

[[Notes:] [`get()` is an ['interruption point].]]

]

[endsect]

[section:wait Member function `wait()`]

    void wait();

[variablelist

[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready. If the result is not ready on
entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]]

[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
['wait callback] if such a callback is called.]]

[[Postconditions:] [[shared_future_is_ready_link `this->is_ready()`] returns `true`. [shared_future_get_state_link
`this->get_state()`] returns __ready__.]]

[[Notes:] [`wait()` is an ['interruption point].]]

]

[endsect]

[section:timed_wait_duration Member function `timed_wait()`]

    template<typename Duration>
    bool timed_wait(Duration const& wait_duration);

[variablelist

[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time specified by
`wait_duration` has elapsed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is
invoked prior to waiting.]]

[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has
elapsed, `false` otherwise.]]

[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
['wait callback] if such a callback is called.]]

[[Postconditions:] [If this call returned `true`, then [shared_future_is_ready_link `this->is_ready()`] returns `true` and
[shared_future_get_state_link `this->get_state()`] returns __ready__.]]

[[Notes:] [`timed_wait()` is an ['interruption point]. `Duration` must be a type that meets the Boost.DateTime time duration requirements.]]

]

[endsect]

[section:timed_wait_absolute Member function `timed_wait()`]

    bool timed_wait(boost::system_time const& wait_timeout);

[variablelist

[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time point specified by
`wait_timeout` has passed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is invoked
prior to waiting.]]

[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready before the specified time has
passed, `false` otherwise.]]

[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
['wait callback] if such a callback is called.]]

[[Postconditions:] [If this call returned `true`, then [shared_future_is_ready_link `this->is_ready()`] returns `true` and
[shared_future_get_state_link `this->get_state()`] returns __ready__.]]

[[Notes:] [`timed_wait()` is an ['interruption point].]]

]

[endsect]

[section:is_ready Member function `is_ready()`]

    bool is_ready();

[variablelist

[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set.]]

[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready for retrieval, `false`
otherwise.]]

[[Throws:] [Nothing.]]

]

[endsect]

[section:has_value Member function `has_value()`]

    bool has_value();

[variablelist

[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with a value rather than an exception.]]

[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a
stored value, `false` otherwise.]]

[[Throws:] [Nothing.]]

]

[endsect]

[section:has_exception Member function `has_exception()`]

    bool has_exception();

[variablelist

[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with an exception rather than a value.]]

[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a
stored exception, `false` otherwise.]]

[[Throws:] [Nothing.]]

]

[endsect]

[section:get_state Member function `get_state()`]

    future_state::state get_state();

[variablelist

[[Effects:] [Determine the state of the asynchronous result associated with `*this`, if any.]]

[[Returns:] [__uninitialized__ if `*this` is not associated with an asynchronous result. __ready__ if the asynchronous result
associated with `*this` is ready for retrieval, __waiting__ otherwise.]]

[[Throws:] [Nothing.]]

]

[endsect]


[endsect]

[section:promise `promise` class template]

    template <typename R>
    class promise
    {
        promise(promise & rhs);// = delete;
        promise & operator=(promise & rhs);// = delete;
    public:
        // template <class Allocator> explicit promise(Allocator a);

        promise();
        ~promise();

        // Move support
        promise(promise && rhs);
        promise & operator=(promise&& rhs);
        
        void swap(promise& other);
        // Result retrieval
        unique_future<R> get_future();

        // Set the value
        void set_value(R& r);
        void set_value(R&& r);
        void set_exception(boost::exception_ptr e);

        template<typename F>
        void set_wait_callback(F f);        
    };

[section:default_constructor Default Constructor]

    promise();

[variablelist

[[Effects:] [Constructs a new __promise__ with no associated result.]]

[[Throws:] [Nothing.]]

]

[endsect]

[section:move_constructor Move Constructor]

    promise(promise && other);

[variablelist

[[Effects:] [Constructs a new __promise__, and transfers ownership of the result associated with `other` to `*this`, leaving `other`
with no associated result.]]

[[Throws:] [Nothing.]]

[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]]

]

[endsect]

[section:move_assignment Move Assignment Operator]

    promise& operator=(promise && other);

[variablelist

[[Effects:] [Transfers ownership of the result associated with `other` to `*this`, leaving `other` with no associated result. If there
was already a result associated with `*this`, and that result was not ['ready], sets any futures associated with that result to
['ready] with a __broken_promise__ exception as the result. ]]

[[Throws:] [Nothing.]]

[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]]

]

[endsect]

[section:destructor Destructor]

    ~promise();

[variablelist

[[Effects:] [Destroys `*this`. If there was a result associated with `*this`, and that result is not ['ready], sets any futures
associated with that task to ['ready] with a __broken_promise__ exception as the result.]]

[[Throws:] [Nothing.]]

]

[endsect]

[section:get_future Member Function `get_future()`]

    unique_future<R> get_future();

[variablelist

[[Effects:] [If `*this` was not associated with a result, allocate storage for a new asynchronous result and associate it with
`*this`. Returns a __unique_future__ associated with the result associated with `*this`. ]]

[[Throws:] [__future_already_retrieved__ if the future associated with the task has already been retrieved. `std::bad_alloc` if any
memory necessary could not be allocated.]]

]

[endsect]

[section:set_value Member Function `set_value()`]

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

[variablelist

[[Effects:] [If `*this` was not associated with a result, allocate storage for a new asynchronous result and associate it with
`*this`. Store the value `r` in the asynchronous result associated with `*this`. Any threads blocked waiting for the asynchronous
result are woken.]]

[[Postconditions:] [All futures waiting on the asynchronous result are ['ready] and __unique_future_has_value__ or
__shared_future_has_value__ for those futures shall return `true`.]]

[[Throws:] [__promise_already_satisfied__ if the result associated with `*this` is already ['ready]. `std::bad_alloc` if the memory
required for storage of the result cannot be allocated. Any exception thrown by the copy or move-constructor of `R`.]]

]

[endsect]

[section:set_exception Member Function `set_exception()`]

    void set_exception(boost::exception_ptr e);

[variablelist

[[Effects:] [If `*this` was not associated with a result, allocate storage for a new asynchronous result and associate it with
`*this`. Store the exception `e` in the asynchronous result associated with `*this`. Any threads blocked waiting for the asynchronous
result are woken.]]

[[Postconditions:] [All futures waiting on the asynchronous result are ['ready] and __unique_future_has_exception__ or
__shared_future_has_exception__ for those futures shall return `true`.]]

[[Throws:] [__promise_already_satisfied__ if the result associated with `*this` is already ['ready]. `std::bad_alloc` if the memory
required for storage of the result cannot be allocated.]]

]

[endsect]

[section:set_wait_callback Member Function `set_wait_callback()`]

    template<typename F>
    void set_wait_callback(F f);

[variablelist

[[Preconditions:] [The expression `f(t)` where `t` is a lvalue of type __packaged_task__ shall be well-formed. Invoking a copy of
`f` shall have the same effect as invoking `f`]]

[[Effects:] [Store a copy of `f` with the asynchronous result associated with `*this` as a ['wait callback]. This will replace any
existing wait callback store alongside that result. If a thread subsequently calls one of the wait functions on a __unique_future__
or __shared_future__ associated with this result, and the result is not ['ready], `f(*this)` shall be invoked.]]

[[Throws:] [`std::bad_alloc` if memory cannot be allocated for the required storage.]]

]

[endsect]

[endsect]

[section:packaged_task `packaged_task` class template]

    template<typename R>
    class packaged_task
    {
        packaged_task(packaged_task&);// = delete;
        packaged_task& operator=(packaged_task&);// = delete;
        
    public:
        // construction and destruction
        template <class F>
        explicit packaged_task(F const& f);

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

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

        ~packaged_task()
        {}

        // move support
        packaged_task(packaged_task&& other);
        packaged_task& operator=(packaged_task&& other);

        void swap(packaged_task& other);
        // result retrieval
        unique_future<R> get_future();        

        // execution
        void operator()();

        template<typename F>
        void set_wait_callback(F f);        
    };

[section:task_constructor Task Constructor]

    template<typename F>
    packaged_task(F const &f);

    packaged_task(R(*f)());

    template<typename F>
    packaged_task(F&&f);

[variablelist

[[Preconditions:] [`f()` is a valid expression with a return type convertible to `R`. Invoking a copy of `f` shall behave the same
as invoking `f`.]]

[[Effects:] [Constructs a new __packaged_task__ with a copy of `f` stored as the associated task.]]

[[Throws:] [Any exceptions thrown by the copy (or move) constructor of `f`. `std::bad_alloc` if memory for the internal data
structures could not be allocated.]]

]

[endsect]

[section:move_constructor Move Constructor]

    packaged_task(packaged_task && other);

[variablelist

[[Effects:] [Constructs a new __packaged_task__, and transfers ownership of the task associated with `other` to `*this`, leaving `other`
with no associated task.]]

[[Throws:] [Nothing.]]

[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]]

]

[endsect]

[section:move_assignment Move Assignment Operator]

    packaged_task& operator=(packaged_task && other);

[variablelist

[[Effects:] [Transfers ownership of the task associated with `other` to `*this`, leaving `other` with no associated task. If there
was already a task associated with `*this`, and that task has not been invoked, sets any futures associated with that task to
['ready] with a __broken_promise__ exception as the result. ]]

[[Throws:] [Nothing.]]

[[Notes:] [If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.]]

]

[endsect]

[section:destructor Destructor]

    ~packaged_task();

[variablelist

[[Effects:] [Destroys `*this`. If there was a task associated with `*this`, and that task has not been invoked, sets any futures
associated with that task to ['ready] with a __broken_promise__ exception as the result.]]

[[Throws:] [Nothing.]]

]

[endsect]

[section:get_future Member Function `get_future()`]

    unique_future<R> get_future();

[variablelist

[[Effects:] [Returns a __unique_future__ associated with the result of the task associated with `*this`. ]]

[[Throws:] [__task_moved__ if ownership of the task associated with `*this` has been moved to another instance of
__packaged_task__. __future_already_retrieved__ if the future associated with the task has already been retrieved.]]

]

[endsect]

[section:call_operator Member Function `operator()()`]

    void operator()();

[variablelist

[[Effects:] [Invoke the task associated with `*this` and store the result in the corresponding future. If the task returns normally,
the return value is stored as the asynchronous result, otherwise the exception thrown is stored. Any threads blocked waiting for the
asynchronous result associated with this task are woken.]]

[[Postconditions:] [All futures waiting on the asynchronous result are ['ready]]]

[[Throws:] [__task_moved__ if ownership of the task associated with `*this` has been moved to another instance of
__packaged_task__. __task_already_started__ if the task has already been invoked.]]

]

[endsect]

[section:set_wait_callback Member Function `set_wait_callback()`]

    template<typename F>
    void set_wait_callback(F f);

[variablelist

[[Preconditions:] [The expression `f(t)` where `t` is a lvalue of type __packaged_task__ shall be well-formed. Invoking a copy of
`f` shall have the same effect as invoking `f`]]

[[Effects:] [Store a copy of `f` with the task associated with `*this` as a ['wait callback]. This will replace any existing wait
callback store alongside that task. If a thread subsequently calls one of the wait functions on a __unique_future__ or
__shared_future__ associated with this task, and the result of the task is not ['ready], `f(*this)` shall be invoked.]]

[[Throws:] [__task_moved__ if ownership of the task associated with `*this` has been moved to another instance of
__packaged_task__.]]

]

[endsect]


[endsect]

[section:wait_for_any Non-member function `wait_for_any()`]

    template<typename Iterator>
    Iterator wait_for_any(Iterator begin,Iterator end);

    template<typename F1,typename F2>
    unsigned wait_for_any(F1& f1,F2& f2);

    template<typename F1,typename F2,typename F3>
    unsigned wait_for_any(F1& f1,F2& f2,F3& f3);

    template<typename F1,typename F2,typename F3,typename F4>
    unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4);

    template<typename F1,typename F2,typename F3,typename F4,typename F5>
    unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5);

[variablelist

[[Preconditions:] [The types `Fn` shall be specializations of
__unique_future__ or __shared_future__, and `Iterator` shall be a
forward iterator with a `value_type` which is a specialization of
__unique_future__ or __shared_future__.]]

[[Effects:] [Waits until at least one of the specified futures is ['ready].]]

[[Returns:] [The range-based overload returns an `Iterator` identifying the first future in the range that was detected as
['ready]. The remaining overloads return the zero-based index of the first future that was detected as ['ready] (first parameter =>
0, second parameter => 1, etc.).]]

[[Throws:] [__thread_interrupted__ if the current thread is interrupted. Any exception thrown by the ['wait callback] associated
with any of the futures being waited for.  `std::bad_alloc` if memory could not be allocated for the internal wait structures.]]

[[Notes:] [`wait_for_any()` is an ['interruption point].]]

]


[endsect]

[section:wait_for_all Non-member function `wait_for_all()`]

    template<typename Iterator>
    void wait_for_all(Iterator begin,Iterator end);

    template<typename F1,typename F2>
    void wait_for_all(F1& f1,F2& f2);

    template<typename F1,typename F2,typename F3>
    void wait_for_all(F1& f1,F2& f2,F3& f3);

    template<typename F1,typename F2,typename F3,typename F4>
    void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4);

    template<typename F1,typename F2,typename F3,typename F4,typename F5>
    void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5);

[variablelist

[[Preconditions:] [The types `Fn` shall be specializations of
__unique_future__ or __shared_future__, and `Iterator` shall be a
forward iterator with a `value_type` which is a specialization of
__unique_future__ or __shared_future__.]]

[[Effects:] [Waits until all of the specified futures are ['ready].]]

[[Throws:] [Any exceptions thrown by a call to `wait()` on the specified futures.]]

[[Notes:] [`wait_for_all()` is an ['interruption point].]]

]


[endsect]


[endsect]
