]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright (C) 2013 Vicente J. Botet Escriba |
2 | // | |
3 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
4 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
5 | // | |
92f5a8d4 | 6 | // 2013,2018 Vicente J. Botet Escriba |
7c673cae FG |
7 | // Adapt to boost from CCIA C++11 implementation |
8 | // Make use of Boost.Move | |
9 | ||
10 | #ifndef BOOST_THREAD_DETAIL_NULLARY_FUNCTION_HPP | |
11 | #define BOOST_THREAD_DETAIL_NULLARY_FUNCTION_HPP | |
12 | ||
13 | #include <boost/config.hpp> | |
14 | #include <boost/thread/detail/memory.hpp> | |
15 | #include <boost/thread/detail/move.hpp> | |
16 | #include <boost/thread/csbl/memory/shared_ptr.hpp> | |
17 | #include <boost/type_traits/decay.hpp> | |
92f5a8d4 | 18 | #include <boost/type_traits/is_same.hpp> |
7c673cae FG |
19 | |
20 | namespace boost | |
21 | { | |
22 | namespace detail | |
23 | { | |
24 | ||
25 | template <typename F> | |
26 | class nullary_function; | |
27 | template <> | |
28 | class nullary_function<void()> | |
29 | { | |
30 | struct impl_base | |
31 | { | |
32 | virtual void call()=0; | |
33 | virtual ~impl_base() | |
34 | { | |
35 | } | |
36 | }; | |
37 | csbl::shared_ptr<impl_base> impl; | |
38 | template <typename F> | |
39 | struct impl_type: impl_base | |
40 | { | |
41 | F f; | |
42 | #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES | |
43 | impl_type(F &f_) | |
44 | : f(f_) | |
45 | {} | |
46 | #endif | |
47 | impl_type(BOOST_THREAD_RV_REF(F) f_) | |
48 | : f(boost::move(f_)) | |
49 | {} | |
50 | ||
51 | void call() | |
52 | { | |
53 | f(); | |
54 | } | |
55 | }; | |
56 | struct impl_type_ptr: impl_base | |
57 | { | |
58 | void (*f)(); | |
59 | impl_type_ptr(void (*f_)()) | |
60 | : f(f_) | |
61 | {} | |
62 | void call() | |
63 | { | |
64 | f(); | |
65 | } | |
66 | }; | |
67 | public: | |
68 | BOOST_THREAD_COPYABLE_AND_MOVABLE(nullary_function) | |
69 | ||
70 | explicit nullary_function(void (*f)()): | |
71 | impl(new impl_type_ptr(f)) | |
72 | {} | |
73 | ||
74 | #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES | |
75 | template<typename F> | |
92f5a8d4 TL |
76 | explicit nullary_function(F& f |
77 | , typename disable_if<is_same<typename decay<F>::type, nullary_function>, int* >::type=0 | |
78 | ): | |
7c673cae FG |
79 | impl(new impl_type<F>(f)) |
80 | {} | |
81 | #endif | |
82 | template<typename F> | |
92f5a8d4 TL |
83 | nullary_function(BOOST_THREAD_RV_REF(F) f |
84 | , typename disable_if<is_same<typename decay<F>::type, nullary_function>, int* >::type=0 | |
85 | ): | |
7c673cae FG |
86 | impl(new impl_type<typename decay<F>::type>(thread_detail::decay_copy(boost::forward<F>(f)))) |
87 | {} | |
88 | ||
89 | nullary_function() | |
90 | : impl() | |
91 | { | |
92 | } | |
93 | nullary_function(nullary_function const& other) BOOST_NOEXCEPT : | |
94 | impl(other.impl) | |
95 | { | |
96 | } | |
97 | nullary_function(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT : | |
98 | #if defined BOOST_NO_CXX11_SMART_PTR | |
99 | impl(BOOST_THREAD_RV(other).impl) | |
100 | { | |
101 | BOOST_THREAD_RV(other).impl.reset(); | |
102 | } | |
103 | #else | |
104 | impl(boost::move(other.impl)) | |
105 | { | |
106 | } | |
107 | #endif | |
108 | ~nullary_function() | |
109 | { | |
110 | } | |
111 | ||
112 | nullary_function& operator=(BOOST_THREAD_COPY_ASSIGN_REF(nullary_function) other) BOOST_NOEXCEPT | |
113 | { | |
114 | impl=other.impl; | |
115 | return *this; | |
116 | } | |
117 | nullary_function& operator=(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT | |
118 | { | |
119 | #if defined BOOST_NO_CXX11_SMART_PTR | |
120 | impl=BOOST_THREAD_RV(other).impl; | |
121 | BOOST_THREAD_RV(other).impl.reset(); | |
122 | #else | |
123 | impl = boost::move(other.impl); | |
124 | #endif | |
125 | return *this; | |
126 | } | |
127 | ||
128 | ||
129 | void operator()() | |
130 | { if (impl) impl->call();} | |
131 | ||
132 | }; | |
133 | ||
134 | template <typename R> | |
135 | class nullary_function<R()> | |
136 | { | |
137 | struct impl_base | |
138 | { | |
139 | virtual R call()=0; | |
140 | virtual ~impl_base() | |
141 | { | |
142 | } | |
143 | }; | |
144 | csbl::shared_ptr<impl_base> impl; | |
145 | template <typename F> | |
146 | struct impl_type: impl_base | |
147 | { | |
148 | F f; | |
149 | #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES | |
150 | impl_type(F &f_) | |
151 | : f(f_) | |
152 | {} | |
153 | #endif | |
154 | impl_type(BOOST_THREAD_RV_REF(F) f_) | |
155 | : f(boost::move(f_)) | |
156 | {} | |
157 | ||
158 | R call() | |
159 | { | |
160 | return f(); | |
161 | } | |
162 | }; | |
163 | struct impl_type_ptr: impl_base | |
164 | { | |
165 | R (*f)(); | |
166 | impl_type_ptr(R (*f_)()) | |
167 | : f(f_) | |
168 | {} | |
169 | ||
170 | R call() | |
171 | { | |
172 | return f(); | |
173 | } | |
174 | }; | |
175 | public: | |
176 | BOOST_THREAD_COPYABLE_AND_MOVABLE(nullary_function) | |
177 | ||
178 | nullary_function(R (*f)()): | |
179 | impl(new impl_type_ptr(f)) | |
180 | {} | |
181 | #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES | |
182 | template<typename F> | |
183 | nullary_function(F& f): | |
184 | impl(new impl_type<F>(f)) | |
185 | {} | |
186 | #endif | |
187 | template<typename F> | |
188 | nullary_function(BOOST_THREAD_RV_REF(F) f): | |
189 | impl(new impl_type<typename decay<F>::type>(thread_detail::decay_copy(boost::forward<F>(f)))) | |
190 | {} | |
191 | ||
192 | nullary_function(nullary_function const& other) BOOST_NOEXCEPT : | |
193 | impl(other.impl) | |
194 | { | |
195 | } | |
196 | nullary_function(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT : | |
197 | #if defined BOOST_NO_CXX11_SMART_PTR | |
198 | impl(BOOST_THREAD_RV(other).impl) | |
199 | { | |
200 | BOOST_THREAD_RV(other).impl.reset(); | |
201 | } | |
202 | #else | |
203 | impl(boost::move(other.impl)) | |
204 | { | |
205 | } | |
206 | #endif | |
207 | nullary_function() | |
208 | : impl() | |
209 | { | |
210 | } | |
211 | ~nullary_function() | |
212 | { | |
213 | } | |
214 | ||
215 | nullary_function& operator=(BOOST_THREAD_COPY_ASSIGN_REF(nullary_function) other) BOOST_NOEXCEPT | |
216 | { | |
217 | impl=other.impl; | |
218 | return *this; | |
219 | } | |
220 | nullary_function& operator=(BOOST_THREAD_RV_REF(nullary_function) other) BOOST_NOEXCEPT | |
221 | { | |
222 | #if defined BOOST_NO_CXX11_SMART_PTR | |
223 | impl=BOOST_THREAD_RV(other).impl; | |
224 | BOOST_THREAD_RV(other).impl.reset(); | |
225 | #else | |
226 | impl = boost::move(other.impl); | |
227 | #endif | |
228 | return *this; | |
229 | } | |
230 | ||
231 | R operator()() | |
232 | { if (impl) return impl->call(); else return R();} | |
233 | ||
234 | }; | |
235 | } | |
236 | BOOST_THREAD_DCL_MOVABLE_BEG(F) detail::nullary_function<F> BOOST_THREAD_DCL_MOVABLE_END | |
237 | } | |
238 | ||
239 | #endif // header |