3 * Author: Lukas Krejci <krejci.l@centrum.cz>, (C) 2008
4 * Copyright: See COPYING file that comes with this distribution
7 #ifndef BOOST_PP_IS_ITERATING
9 #ifndef BEACON_in_queue_invoke_new_H
10 #define BEACON_in_queue_invoke_new_H
12 #include <beacon/config.hpp>
13 #include <beacon/invokable.hpp>
14 #include <beacon/future_event.hpp>
15 #include <beacon/detail/future_event_base.hpp>
16 #include <beacon/reference_countable.hpp>
18 #include <boost/type_traits/function_traits.hpp>
19 #include <boost/type_traits/add_pointer.hpp>
21 //include the preprocessor magic
22 #include <boost/preprocessor/iteration/iterate.hpp>
23 #include <boost/preprocessor/repetition.hpp>
24 #include <boost/preprocessor/punctuation/comma_if.hpp>
25 #include <boost/preprocessor/cat.hpp>
27 #define BOOST_PP_ITERATION_LIMITS (0, BEACON_MAX_ARGS)
28 #define BOOST_PP_FILENAME_1 "beacon/detail/in_queue_invoke.hpp" // this file
38 * Generic base class for the numerous specializations of the in_queue_invoke
39 * class for various template parameters.
41 class in_queue_invoke_base
{
44 typedef intrusive_ptr
<future_event_base
> future_ptr
;
46 in_queue_invoke_base(future_ptr future
) : _future(future
) {}
48 void set_result(void * result
) {
56 //template classes to support different flavours of function
57 //objects invokable in the event_queue.
59 template<typename Function
, typename Signature
>
60 class in_queue_invoke
;
62 template<typename Function
, typename Signature
>
63 class in_queue_invoke_no_future
;
65 template<typename Function
, typename Signature
>
66 class in_queue_wrapper_future_pointer
;
68 template<typename Function
, typename Signature
>
69 class in_queue_wrapper_no_future
;
71 #include BOOST_PP_ITERATE()
77 #endif //BEACON_in_queue_invoke_new_H
79 #else // BOOST_PP_IS_ITERATING
81 #define n BOOST_PP_ITERATION()
83 #define CONSTRUCTOR_ARG_INIT(z, n, unused) \
84 BOOST_PP_CAT(_arg, n)(BOOST_PP_CAT(arg, n))
86 #define MEMBER_VAR_DEF(z, n, unused) \
87 BOOST_PP_CAT(T, n) BOOST_PP_CAT(_arg, n);
89 template<typename Function
,
92 BOOST_PP_ENUM_PARAMS(n
, typename T
)>
93 class in_queue_invoke
<Function
, R (*)(BOOST_PP_ENUM_PARAMS(n
, T
))> :
94 public beacon::invokable
, public in_queue_invoke_base
{
98 explicit in_queue_invoke(
99 BOOST_PP_ENUM_BINARY_PARAMS(n
, T
, arg
)
102 intrusive_ptr
<future_event_base
> future
,
103 invokable::token_ptr token
)
106 in_queue_invoke_base(future
),
109 BOOST_PP_ENUM(n
, CONSTRUCTOR_ARG_INIT
, ~) {}
112 R result
= (*_f
)(BOOST_PP_ENUM_PARAMS(n
, _arg
));
113 set_result(static_cast<void *>(&result
));
118 BOOST_PP_REPEAT(n
, MEMBER_VAR_DEF
, ~)
121 template<typename Function
123 BOOST_PP_ENUM_PARAMS(n
, typename T
)>
124 class in_queue_invoke
<Function
, void (*)(BOOST_PP_ENUM_PARAMS(n
, T
))> :
125 public beacon::invokable
, public in_queue_invoke_base
{
129 explicit in_queue_invoke(
130 BOOST_PP_ENUM_BINARY_PARAMS(n
, T
, arg
)
133 intrusive_ptr
<future_event_base
> future
,
134 invokable::token_ptr token
)
137 in_queue_invoke_base(future
),
140 BOOST_PP_ENUM(n
, CONSTRUCTOR_ARG_INIT
, arg
) {}
143 (*_f
)(BOOST_PP_ENUM_PARAMS(n
, _arg
));
150 BOOST_PP_REPEAT(n
, MEMBER_VAR_DEF
, ~)
153 template<typename Function
,
156 BOOST_PP_ENUM_PARAMS(n
, typename T
)>
157 class in_queue_invoke_no_future
<Function
, R (*)(BOOST_PP_ENUM_PARAMS(n
, T
))> :
158 public beacon::invokable
{
161 explicit in_queue_invoke_no_future(
162 BOOST_PP_ENUM_BINARY_PARAMS(n
, T
, arg
)
165 invokable::token_ptr token
)
170 BOOST_PP_ENUM(n
, CONSTRUCTOR_ARG_INIT
, arg
) {}
173 (*_f
)(BOOST_PP_ENUM_PARAMS(n
, _arg
));
178 BOOST_PP_REPEAT(n
, MEMBER_VAR_DEF
, ~)
182 template<typename Function
,
185 BOOST_PP_ENUM_PARAMS(n
, typename T
)>
186 class in_queue_wrapper_future_pointer
<Function
, R (*)(BOOST_PP_ENUM_PARAMS(n
, T
))> {
188 typedef R (* Signature
)(BOOST_PP_ENUM_PARAMS(n
, T
));
189 typedef intrusive_ptr
<future
<R
> > result_type
;
192 explicit in_queue_wrapper_future_pointer(event_queue
& queue
, Function
const * f
, invokable::token_ptr token
) :
193 _queue(queue
), _f(f
), _token(token
) {}
195 result_type
operator()(BOOST_PP_ENUM_BINARY_PARAMS(n
, T
, arg
)) {
196 intrusive_ptr
<future_event_base
> fut(new future_event
<R
>);
198 this->_queue
.enqueue(new in_queue_invoke
<Function
, Signature
>(
199 BOOST_PP_ENUM_PARAMS(n
, arg
)
203 return result_type(reinterpret_cast<future_event
<R
> *>(fut
.get()));
207 event_queue
& _queue
;
209 invokable::token_ptr _token
;
212 template<typename Function
,
215 BOOST_PP_ENUM_PARAMS(n
, typename T
)>
216 class in_queue_wrapper_no_future
<Function
, R (*)(BOOST_PP_ENUM_PARAMS(n
, T
))> {
218 typedef R (* Signature
)(BOOST_PP_ENUM_PARAMS(n
, T
));
221 explicit in_queue_wrapper_no_future(event_queue
& queue
, Function
const * f
, invokable::token_ptr token
) :
222 _queue(queue
), _f(f
), _token(token
) {}
224 void operator()(BOOST_PP_ENUM_BINARY_PARAMS(n
, T
, arg
)) {
225 this->_queue
.enqueue(
226 new in_queue_invoke_no_future
<Function
, Signature
>(
227 BOOST_PP_ENUM_PARAMS(n
, arg
)
233 event_queue
& _queue
;
235 invokable::token_ptr _token
;
239 #undef CONSTRUCTOR_ARG_INIT
240 #undef MEMBER_VAR_DEF
242 #endif //BOOST_PP_IS_ITERATING