renamed from beacon to beacons, bumped version to 0.1.1 for that.
[beacon-ss.git] / src / beacons / detail / in_queue_invoke.hpp
blob5b014f493210e392fdcc9e00bd5a2ac9662dc367
1 /**
2 * beacon
3 * Author: Lukas Krejci <krejci.l@centrum.cz>, (C) 2008
4 * Copyright: See COPYING file that comes with this distribution
5 */
7 #ifndef BOOST_PP_IS_ITERATING
9 #ifndef BEACONS_in_queue_invoke_new_H
10 #define BEACONS_in_queue_invoke_new_H
12 #include <beacons/config.hpp>
13 #include <beacons/invokable.hpp>
14 #include <beacons/future_event.hpp>
15 #include <beacons/detail/future_event_base.hpp>
16 #include <beacons/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, BEACONS_MAX_ARGS)
28 #define BOOST_PP_FILENAME_1 "beacons/detail/in_queue_invoke.hpp" // this file
30 namespace beacons {
32 //forward decl
33 class event_queue;
35 namespace detail {
37 /**
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 {
42 protected:
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) {
49 _future->set(result);
52 private:
53 future_ptr _future;
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()
73 } //namespace detail
75 } //namespace beacons
77 #endif //BEACONS_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,
90 typename R
91 BOOST_PP_COMMA_IF(n)
92 BOOST_PP_ENUM_PARAMS(n, typename T)>
93 class in_queue_invoke<Function, R (*)(BOOST_PP_ENUM_PARAMS(n, T))> :
94 public beacons::invokable, public in_queue_invoke_base {
96 public:
98 explicit in_queue_invoke(
99 BOOST_PP_ENUM_BINARY_PARAMS(n, T, arg)
100 BOOST_PP_COMMA_IF(n)
101 Function const * f,
102 intrusive_ptr<future_event_base> future,
103 invokable::token_ptr token)
105 invokable(token),
106 in_queue_invoke_base(future),
107 _f(f)
108 BOOST_PP_COMMA_IF(n)
109 BOOST_PP_ENUM(n, CONSTRUCTOR_ARG_INIT, ~) {}
111 void invoke() {
112 R result = (*_f)(BOOST_PP_ENUM_PARAMS(n, _arg));
113 set_result(static_cast<void *>(&result));
116 private:
117 Function const * _f;
118 BOOST_PP_REPEAT(n, MEMBER_VAR_DEF, ~)
121 template<typename Function
122 BOOST_PP_COMMA_IF(n)
123 BOOST_PP_ENUM_PARAMS(n, typename T)>
124 class in_queue_invoke<Function, void (*)(BOOST_PP_ENUM_PARAMS(n, T))> :
125 public beacons::invokable, public in_queue_invoke_base {
127 public:
129 explicit in_queue_invoke(
130 BOOST_PP_ENUM_BINARY_PARAMS(n, T, arg)
131 BOOST_PP_COMMA_IF(n)
132 Function const * f,
133 intrusive_ptr<future_event_base> future,
134 invokable::token_ptr token)
136 invokable(token),
137 in_queue_invoke_base(future),
138 _f(f)
139 BOOST_PP_COMMA_IF(n)
140 BOOST_PP_ENUM(n, CONSTRUCTOR_ARG_INIT, arg) {}
142 void invoke() {
143 (*_f)(BOOST_PP_ENUM_PARAMS(n, _arg));
144 void * res = 0;
145 set_result(res);
148 private:
149 Function const * _f;
150 BOOST_PP_REPEAT(n, MEMBER_VAR_DEF, ~)
153 template<typename Function,
154 typename R
155 BOOST_PP_COMMA_IF(n)
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 beacons::invokable {
160 public:
161 explicit in_queue_invoke_no_future(
162 BOOST_PP_ENUM_BINARY_PARAMS(n, T, arg)
163 BOOST_PP_COMMA_IF(n)
164 Function const * f,
165 invokable::token_ptr token)
167 invokable(token),
168 _f(f)
169 BOOST_PP_COMMA_IF(n)
170 BOOST_PP_ENUM(n, CONSTRUCTOR_ARG_INIT, arg) {}
172 void invoke() {
173 (*_f)(BOOST_PP_ENUM_PARAMS(n, _arg));
176 private:
177 Function const * _f;
178 BOOST_PP_REPEAT(n, MEMBER_VAR_DEF, ~)
182 template<typename Function,
183 typename R
184 BOOST_PP_COMMA_IF(n)
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;
190 public:
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)
200 BOOST_PP_COMMA_IF(n)
201 _f, fut, _token));
203 return result_type(reinterpret_cast<future_event<R> *>(fut.get()));
206 private:
207 event_queue & _queue;
208 Function const * _f;
209 invokable::token_ptr _token;
212 template<typename Function,
213 typename R
214 BOOST_PP_COMMA_IF(n)
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));
219 public:
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)
228 BOOST_PP_COMMA_IF(n)
229 _f, _token));
232 private:
233 event_queue & _queue;
234 Function const * _f;
235 invokable::token_ptr _token;
238 #undef n
239 #undef CONSTRUCTOR_ARG_INIT
240 #undef MEMBER_VAR_DEF
242 #endif //BOOST_PP_IS_ITERATING