[/
          Copyright Oliver Kowalke 2013.
 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
]

[#class_packaged_task]
[section:packaged_task Template `packaged_task<>`]

A __packaged_task__ wraps a callable target that returns a value so that the
return value can be computed asynchronously.

Conventional usage of `packaged_task<>` is like this:

# Instantiate `packaged_task<>` with template arguments matching the signature
  of the callable. Pass the callable to the [link packaged_task_packaged_task
  constructor].
# Call [member_link packaged_task..get_future] and capture the returned
  [template_link future] instance.
# Launch a [class_link fiber] to run the new `packaged_task<>`, passing any
  arguments required by the original callable.
# Call [member_link fiber..detach] on the newly-launched `fiber`.
# At some later point, retrieve the result from the `future<>`.

This is, in fact, pretty much what [ns_function_link fibers..async]
encapsulates.

        #include <boost/fiber/future/packaged_task.hpp>

        namespace boost {
        namespace fibers {

        template< class R, typename ... Args >
        class packaged_task< R( Args ... ) > {
        public:
            packaged_task() noexcept;

            template< typename Fn >
            explicit packaged_task( Fn &&);

            template< typename Fn, typename __Allocator__ >
            packaged_task( __allocator_arg_t__, Allocator const&, Fn &&);

            packaged_task( packaged_task &&) noexcept;

            packaged_task & operator=( packaged_task &&) noexcept;

            packaged_task( packaged_task const&) = delete;

            packaged_task & operator=( packaged_task const&) = delete;

            ~packaged_task();

            void swap( packaged_task &) noexcept;

            bool valid() const noexcept;

            future< R > get_future();

            void operator()( Args ...);

            void reset();
        };

        template< typename Signature >
        void swap( packaged_task< Signature > &, packaged_task< Signature > &) noexcept;

        }}

[heading Default constructor `packaged_task()`]

        packaged_task() noexcept;

[variablelist
[[Effects:] [Constructs an object of class `packaged_task` with no [link
shared_state shared state].]]
[[Throws:] [Nothing.]]
]

[#packaged_task_packaged_task]
[heading Templated constructor `packaged_task()`]

        template< typename Fn >
        explicit packaged_task( Fn && fn);

        template< typename Fn, typename __Allocator__ >
        packaged_task( __allocator_arg_t__, Allocator const& alloc, Fn && fn);

[variablelist
[[Effects:] [Constructs an object of class `packaged_task` with a [link
shared_state shared state] and copies or moves the callable target `fn` to
internal storage.]]
[[Throws:] [Exceptions caused by memory allocation.]]
[[Note:] [The signature of `Fn` should have a return type convertible to `R`.]]
[[See also:] [__allocator_arg_t__]]
]

[heading Move constructor]

        packaged_task( packaged_task && other) noexcept;

[variablelist
[[Effects:] [Creates a packaged_task by moving the [link shared_state shared
state] from `other`.]]
[[Postcondition:] [`other` contains no valid shared state.]]
[[Throws:] [Nothing.]]
]

[heading Destructor]

        ~packaged_task();

[variablelist
[[Effects:] [Destroys `*this` and abandons the [link shared_state shared
state] if shared state is ready; otherwise stores __future_error__ with error
condition __broken_promise__ as if by [member_link promise..set_exception]:
the shared state is set ready.]]
]

[operator_heading packaged_task..operator_assign..operator=]

        packaged_task & operator=( packaged_task && other) noexcept;

[variablelist
[[Effects:] [Transfers the ownership of [link shared_state shared state] to
`*this`.]]
[[Postcondition:] [`other` contains no valid shared state.]]
[[Throws:] [Nothing.]]
]

[member_heading packaged_task..swap]

        void swap( packaged_task & other) noexcept;

[variablelist
[[Effects:] [Swaps the [link shared_state shared state] between other and
`*this`.]]
[[Throws:] [Nothing.]]
]

[member_heading packaged_task..valid]

        bool valid() const noexcept;

[variablelist
[[Effects:] [Returns `true` if `*this` contains a [link shared_state shared
state].]]
[[Throws:] [Nothing.]]
]

[member_heading packaged_task..get_future]

        future< R > get_future();

[variablelist
[[Returns:] [A __future__ with the same [link shared_state shared state].]]
[[Throws:] [__future_error__ with __already_retrieved__ or __no_state__.]]
]

[operator_heading packaged_task..operator_apply..operator()]

        void operator()( Args && ... args);

[variablelist
[[Effects:] [Invokes the stored callable target. Any exception thrown by the
callable target `fn` is stored in the [link shared_state shared state] as if
by [member_link promise..set_exception]. Otherwise, the value returned by `fn`
is stored in the shared state as if by [member_link promise..set_value].]]
[[Throws:] [__future_error__ with __no_state__.]]
]

[member_heading packaged_task..reset]

        void reset();

[variablelist
[[Effects:] [Resets the [link shared_state shared state] and abandons the
result of previous executions. A new shared state is constructed.]]
[[Throws:] [__future_error__ with __no_state__.]]
]

[function_heading_for swap..packaged_task]

    template< typename Signature >
    void swap( packaged_task< Signature > & l, packaged_task< Signature > & r) noexcept;

[variablelist
[[Effects:] [Same as `l.swap( r)`.]]
]

[endsect]
