2 // Copyright Oliver Kowalke 2013.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
7 #ifndef BOOST_FIBERS_DETAIL_TASK_OBJECT_H
8 #define BOOST_FIBERS_DETAIL_TASK_OBJECT_H
14 #include <boost/config.hpp>
15 #include <boost/context/detail/apply.hpp>
17 #include <boost/fiber/detail/config.hpp>
18 #include <boost/fiber/future/detail/task_base.hpp>
20 #ifdef BOOST_HAS_ABI_HEADERS
21 # include BOOST_ABI_PREFIX
28 template< typename Fn, typename Allocator, typename R, typename ... Args >
29 class task_object : public task_base< R, Args ... > {
31 typedef task_base< R, Args ... > base_t;
34 typedef typename std::allocator_traits< Allocator >::template rebind_alloc<
38 task_object( allocator_t const& alloc, Fn const& fn) :
44 task_object( allocator_t const& alloc, Fn && fn) :
46 fn_( std::move( fn) ),
50 void run( Args && ... args) override final {
53 boost::context::detail::apply(
54 fn_, std::make_tuple( std::forward< Args >( args) ... ) ) );
56 this->set_exception( std::current_exception() );
60 typename base_t::ptr_t reset() override final {
61 typedef std::allocator_traits< allocator_t > traits_t;
63 typename traits_t::pointer ptr{ traits_t::allocate( alloc_, 1) };
65 traits_t::construct( alloc_, ptr, alloc_, std::move( fn_) );
67 traits_t::deallocate( alloc_, ptr, 1);
70 return { convert( ptr) };
74 void deallocate_future() noexcept override final {
75 destroy_( alloc_, this);
82 static void destroy_( allocator_t const& alloc, task_object * p) noexcept {
83 allocator_t a{ alloc };
89 template< typename Fn, typename Allocator, typename ... Args >
90 class task_object< Fn, Allocator, void, Args ... > : public task_base< void, Args ... > {
92 typedef task_base< void, Args ... > base_t;
95 typedef typename Allocator::template rebind<
96 task_object< Fn, Allocator, void, Args ... >
99 task_object( allocator_t const& alloc, Fn const& fn) :
105 task_object( allocator_t const& alloc, Fn && fn) :
107 fn_( std::move( fn) ),
111 void run( Args && ... args) override final {
113 boost::context::detail::apply(
114 fn_, std::make_tuple( std::forward< Args >( args) ... ) );
117 this->set_exception( std::current_exception() );
121 typename base_t::ptr_t reset() override final {
122 typedef std::allocator_traits< allocator_t > traits_t;
124 typename traits_t::pointer ptr{ traits_t::allocate( alloc_, 1) };
126 traits_t::construct( alloc_, ptr, alloc_, std::move( fn_) );
128 traits_t::deallocate( alloc_, ptr, 1);
131 return { convert( ptr) };
135 void deallocate_future() noexcept override final {
136 destroy_( alloc_, this);
143 static void destroy_( allocator_t const& alloc, task_object * p) noexcept {
144 allocator_t a{ alloc };
152 #ifdef BOOST_HAS_ABI_HEADERS
153 # include BOOST_ABI_SUFFIX
156 #endif // BOOST_FIBERS_DETAIL_TASK_OBJECT_H