]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fiber/include/boost/fiber/future/detail/task_object.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / fiber / include / boost / fiber / future / detail / task_object.hpp
1
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)
6
7 #ifndef BOOST_FIBERS_DETAIL_TASK_OBJECT_H
8 #define BOOST_FIBERS_DETAIL_TASK_OBJECT_H
9
10 #include <exception>
11 #include <memory>
12 #include <utility>
13
14 #include <boost/config.hpp>
15 #include <boost/context/detail/apply.hpp>
16
17 #include <boost/fiber/detail/config.hpp>
18 #include <boost/fiber/future/detail/task_base.hpp>
19
20 #ifdef BOOST_HAS_ABI_HEADERS
21 # include BOOST_ABI_PREFIX
22 #endif
23
24 namespace boost {
25 namespace fibers {
26 namespace detail {
27
28 template< typename Fn, typename Allocator, typename R, typename ... Args >
29 class task_object : public task_base< R, Args ... > {
30 private:
31 typedef task_base< R, Args ... > base_t;
32
33 public:
34 typedef typename std::allocator_traits< Allocator >::template rebind_alloc<
35 task_object
36 > allocator_t;
37
38 task_object( allocator_t const& alloc, Fn const& fn) :
39 base_t(),
40 fn_( fn),
41 alloc_( alloc) {
42 }
43
44 task_object( allocator_t const& alloc, Fn && fn) :
45 base_t(),
46 fn_( std::move( fn) ),
47 alloc_( alloc) {
48 }
49
50 void run( Args && ... args) override final {
51 try {
52 this->set_value(
53 boost::context::detail::apply(
54 fn_, std::make_tuple( std::forward< Args >( args) ... ) ) );
55 } catch (...) {
56 this->set_exception( std::current_exception() );
57 }
58 }
59
60 typename base_t::ptr_t reset() override final {
61 typedef std::allocator_traits< allocator_t > traits_t;
62
63 typename traits_t::pointer ptr{ traits_t::allocate( alloc_, 1) };
64 try {
65 traits_t::construct( alloc_, ptr, alloc_, std::move( fn_) );
66 } catch (...) {
67 traits_t::deallocate( alloc_, ptr, 1);
68 throw;
69 }
70 return { convert( ptr) };
71 }
72
73 protected:
74 void deallocate_future() noexcept override final {
75 destroy_( alloc_, this);
76 }
77
78 private:
79 Fn fn_;
80 allocator_t alloc_;
81
82 static void destroy_( allocator_t const& alloc, task_object * p) noexcept {
83 allocator_t a{ alloc };
84 a.destroy( p);
85 a.deallocate( p, 1);
86 }
87 };
88
89 template< typename Fn, typename Allocator, typename ... Args >
90 class task_object< Fn, Allocator, void, Args ... > : public task_base< void, Args ... > {
91 private:
92 typedef task_base< void, Args ... > base_t;
93
94 public:
95 typedef typename Allocator::template rebind<
96 task_object< Fn, Allocator, void, Args ... >
97 >::other allocator_t;
98
99 task_object( allocator_t const& alloc, Fn const& fn) :
100 base_t(),
101 fn_( fn),
102 alloc_( alloc) {
103 }
104
105 task_object( allocator_t const& alloc, Fn && fn) :
106 base_t(),
107 fn_( std::move( fn) ),
108 alloc_( alloc) {
109 }
110
111 void run( Args && ... args) override final {
112 try {
113 boost::context::detail::apply(
114 fn_, std::make_tuple( std::forward< Args >( args) ... ) );
115 this->set_value();
116 } catch (...) {
117 this->set_exception( std::current_exception() );
118 }
119 }
120
121 typename base_t::ptr_t reset() override final {
122 typedef std::allocator_traits< allocator_t > traits_t;
123
124 typename traits_t::pointer ptr{ traits_t::allocate( alloc_, 1) };
125 try {
126 traits_t::construct( alloc_, ptr, alloc_, std::move( fn_) );
127 } catch (...) {
128 traits_t::deallocate( alloc_, ptr, 1);
129 throw;
130 }
131 return { convert( ptr) };
132 }
133
134 protected:
135 void deallocate_future() noexcept override final {
136 destroy_( alloc_, this);
137 }
138
139 private:
140 Fn fn_;
141 allocator_t alloc_;
142
143 static void destroy_( allocator_t const& alloc, task_object * p) noexcept {
144 allocator_t a{ alloc };
145 a.destroy( p);
146 a.deallocate( p, 1);
147 }
148 };
149
150 }}}
151
152 #ifdef BOOST_HAS_ABI_HEADERS
153 # include BOOST_ABI_SUFFIX
154 #endif
155
156 #endif // BOOST_FIBERS_DETAIL_TASK_OBJECT_H