QtGStreamer  1.2.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
emitimpl.h
1 /*
2  Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
3  Copyright (C) 2010 Collabora Ltd.
4  @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
5 
6  This library is free software; you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published
8  by the Free Software Foundation; either version 2.1 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #if !defined(BOOST_PP_IS_ITERATING) || !BOOST_PP_IS_ITERATING
20 
21 # ifndef IN_QGLIB_SIGNAL_H
22 # error "This file must not be included directly"
23 # endif
24 
25 # include "value.h"
26 # include "quark.h"
27 # include <QtCore/QList>
28 # include <QtCore/QDebug>
29 # include <stdexcept>
30 
31 
32 namespace QGlib {
33 namespace Private {
34 
36 QTGLIB_EXPORT Value emit(void *instance, const char *signal, Quark detail, const QList<Value> & args);
37 
38 template <typename Signature>
39 struct EmitImpl {};
40 
41 } //namespace Private
42 } //namespace QGlib
43 
44 
45 # if QGLIB_HAVE_CXX0X
46 
47 namespace QGlib {
48 namespace Private {
49 
50 //BEGIN ******** packArguments ********
51 
52 inline QList<Value> packArguments()
53 {
54  return QList<Value>();
55 }
56 
57 template <typename Arg1, typename... Args>
58 QList<Value> packArguments(const Arg1 & a1, const Args & ... args)
59 {
60  QList<Value> && result = packArguments(args...);
61  Value v;
62  v.init<Arg1>();
63  ValueImpl<Arg1>::set(v, a1);
64  //prepend, since we are packing from the last to the first argument
65  result.prepend(v);
66  return result;
67 }
68 
69 //END ******** packArguments ********
70 //BEGIN ******** EmitImpl ********
71 
72 template <typename R, typename... Args>
73 struct EmitImpl<R (Args...)>
74 {
75  static inline R emit(void *instance, const char *signal, Quark detail, const Args & ... args)
76  {
77  try {
78  Value && returnValue = Private::emit(instance, signal, detail, packArguments(args...));
79  return ValueImpl<R>::get(returnValue);
80  } catch(const std::exception & e) {
81  qCritical() << "Error during emission of signal" << signal << ":" << e.what();
82  return R();
83  }
84  }
85 };
86 
87 template <typename... Args>
88 struct EmitImpl<void (Args...)>
89 {
90  static inline void emit(void *instance, const char *signal, Quark detail, const Args & ... args)
91  {
92  try {
93  Value && returnValue = Private::emit(instance, signal, detail, packArguments(args...));
94 
95  if (returnValue.isValid()) {
96  qWarning() << "Ignoring return value from emission of signal" << signal;
97  }
98  } catch(const std::exception & e) {
99  qCritical() << "Error during emission of signal" << signal << ":" << e.what();
100  }
101  }
102 };
103 
104 //END ******** EmitImpl ********
105 
106 } //namespace Private
107 
108 //BEGIN ******** QGlib::emit ********
109 
110 template <typename R, typename... Args>
111 R emit(void *instance, const char *detailedSignal, const Args & ... args)
112 {
113  return Private::EmitImpl<R (Args...)>::emit(instance, detailedSignal, Quark(), args...);
114 }
115 
116 template <typename R, typename... Args>
117 R emitWithDetail(void *instance, const char *signal, Quark detail, const Args & ... args)
118 {
119  return Private::EmitImpl<R (Args...)>::emit(instance, signal, detail, args...);
120 }
121 
122 //END ******** QGlib::emit ********
123 
124 } //namespace QGlib
125 
126 # else //QGLIB_HAVE_CXX0X
127 
128 # include <boost/preprocessor.hpp>
129 
130 // include the second part of this file as many times as QGLIB_SIGNAL_MAX_ARGS specifies
131 # define BOOST_PP_ITERATION_PARAMS_1 (3,(0, QGLIB_SIGNAL_MAX_ARGS, "QGlib/emitimpl.h"))
132 # include BOOST_PP_ITERATE()
133 # undef BOOST_PP_ITERATION_PARAMS_1
134 
135 # endif //QGLIB_HAVE_CXX0X
136 
137 
138 #else // !defined(BOOST_PP_IS_ITERATING) || !BOOST_PP_IS_ITERATING
139 
140 /*
141  This part is included from BOOST_PP_ITERATE(). It defines specializations of struct EmitImpl
142  with different number of arguments as well as the multiple implementations of the non-variadic
143  QGlib::emit. This part is included multiple times (QGLIB_SIGNAL_MAX_ARGS defines how many),
144  and each time it defines those classes and functions with different number of arguments.
145  The concept is based on the implementation of boost::function.
146 */
147 
148 # define QGLIB_SIGNAL_IMPL_NUM_ARGS \
149  BOOST_PP_ITERATION()
150 
151 # define QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_PARAMS \
152  BOOST_PP_ENUM_TRAILING_PARAMS(QGLIB_SIGNAL_IMPL_NUM_ARGS, typename A)
153 
154 # define QGLIB_SIGNAL_IMPL_TEMPLATE_PARAMS \
155  BOOST_PP_ENUM_PARAMS(QGLIB_SIGNAL_IMPL_NUM_ARGS, typename A)
156 
157 # define QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_ARGS \
158  BOOST_PP_ENUM_TRAILING_PARAMS(QGLIB_SIGNAL_IMPL_NUM_ARGS, A)
159 
160 # define QGLIB_SIGNAL_IMPL_TEMPLATE_ARGS \
161  BOOST_PP_ENUM_PARAMS(QGLIB_SIGNAL_IMPL_NUM_ARGS, A)
162 
163 # define QGLIB_SIGNAL_IMPL_FUNCTION_PARAMS \
164  BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(QGLIB_SIGNAL_IMPL_NUM_ARGS, const A, & a)
165 
166 # define QGLIB_SIGNAL_IMPL_FUNCTION_ARGS \
167  BOOST_PP_ENUM_TRAILING_PARAMS(QGLIB_SIGNAL_IMPL_NUM_ARGS, a)
168 
169 
170 namespace QGlib {
171 namespace Private {
172 
173 //BEGIN ******** boostpp EmitImpl ********
174 
175 # define QGLIB_SIGNAL_IMPL_PACK_ARGS_STEP(z, n, list) \
176  { \
177  Value v; \
178  v.init<A##n>(); \
179  ValueImpl<A##n>::set(v, a##n); \
180  list.append(v); \
181  }
182 
183 # define QGLIB_SIGNAL_IMPL_PACK_ARGS(list) \
184  BOOST_PP_REPEAT(QGLIB_SIGNAL_IMPL_NUM_ARGS, QGLIB_SIGNAL_IMPL_PACK_ARGS_STEP, list)
185 
186 template <typename R QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_PARAMS>
187 struct EmitImpl<R (QGLIB_SIGNAL_IMPL_TEMPLATE_ARGS)>
188 {
189  static inline R emit(void *instance, const char *signal, Quark detail
190  QGLIB_SIGNAL_IMPL_FUNCTION_PARAMS)
191  {
192  try {
193  QList<Value> values;
194  QGLIB_SIGNAL_IMPL_PACK_ARGS(values)
195  Value returnValue = Private::emit(instance, signal, detail, values);
196  return ValueImpl<R>::get(returnValue);
197  } catch(const std::exception & e) {
198  qCritical() << "Error during emission of signal" << signal << ":" << e.what();
199  return R();
200  }
201  }
202 };
203 
204 template <QGLIB_SIGNAL_IMPL_TEMPLATE_PARAMS>
205 struct EmitImpl<void (QGLIB_SIGNAL_IMPL_TEMPLATE_ARGS)>
206 {
207  static inline void emit(void *instance, const char *signal, Quark detail
208  QGLIB_SIGNAL_IMPL_FUNCTION_PARAMS)
209  {
210  try {
211  QList<Value> values;
212  QGLIB_SIGNAL_IMPL_PACK_ARGS(values)
213  Value returnValue = Private::emit(instance, signal, detail, values);
214  if (returnValue.isValid()) {
215  qWarning() << "Ignoring return value from emission of signal" << signal;
216  }
217  } catch(const std::exception & e) {
218  qCritical() << "Error during emission of signal" << signal << ":" << e.what();
219  }
220  }
221 };
222 
223 # undef QGLIB_SIGNAL_IMPL_PACK_ARGS
224 # undef QGLIB_SIGNAL_IMPL_PACK_ARGS_STEP
225 
226 //END ******** boostpp EmitImpl ********
227 
228 } //namespace Private
229 
230 //BEGIN ******** boostpp QGlib::emit ********
231 
232 template <typename R QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_PARAMS>
233 R emit(void *instance, const char *detailedSignal QGLIB_SIGNAL_IMPL_FUNCTION_PARAMS)
234 {
235  return Private::EmitImpl<R (QGLIB_SIGNAL_IMPL_TEMPLATE_ARGS)>
236  ::emit(instance, detailedSignal, Quark() QGLIB_SIGNAL_IMPL_FUNCTION_ARGS);
237 }
238 
239 template <typename R QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_PARAMS>
240 R emitWithDetail(void *instance, const char *signal, Quark detail QGLIB_SIGNAL_IMPL_FUNCTION_PARAMS)
241 {
242  return Private::EmitImpl<R (QGLIB_SIGNAL_IMPL_TEMPLATE_ARGS)>
243  ::emit(instance, signal, detail QGLIB_SIGNAL_IMPL_FUNCTION_ARGS);
244 }
245 
246 //END ******** boostpp QGlib::emit ********
247 
248 } //namespace QGlib
249 
250 # undef QGLIB_SIGNAL_IMPL_FUNCTION_ARGS
251 # undef QGLIB_SIGNAL_IMPL_FUNCTION_PARAMS
252 # undef QGLIB_SIGNAL_IMPL_TEMPLATE_ARGS
253 # undef QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_ARGS
254 # undef QGLIB_SIGNAL_IMPL_TEMPLATE_PARAMS
255 # undef QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_PARAMS
256 # undef QGLIB_SIGNAL_IMPL_NUM_ARGS
257 
258 #endif // !defined(BOOST_PP_IS_ITERATING) || !BOOST_PP_IS_ITERATING
R emitWithDetail(void *instance, const char *signal, Quark detail, const Args &...args)
Definition: emitimpl.h:117
R emit(void *instance, const char *detailedSignal, const Args &...args)
Definition: emitimpl.h:111
Wrapper class for GQuark.
Definition: quark.h:42