QtGStreamer 1.2.0
Loading...
Searching...
No Matches
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
32namespace QGlib {
33namespace Private {
34
36QTGLIB_EXPORT Value emit(void *instance, const char *signal, Quark detail, const QList<Value> & args);
37
38template <typename Signature>
39struct EmitImpl {};
40
41} //namespace Private
42} //namespace QGlib
43
44
45# if QGLIB_HAVE_CXX0X
46
47namespace QGlib {
48namespace Private {
49
50//BEGIN ******** packArguments ********
51
52inline QList<Value> packArguments()
53{
54 return QList<Value>();
55}
56
57template <typename Arg1, typename... Args>
58QList<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
72template <typename R, typename... Args>
73struct 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
87template <typename... Args>
88struct 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
110template <typename R, typename... Args>
111R emit(void *instance, const char *detailedSignal, const Args & ... args)
112{
113 return Private::EmitImpl<R (Args...)>::emit(instance, detailedSignal, Quark(), args...);
114}
115
116template <typename R, typename... Args>
117R 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
170namespace QGlib {
171namespace 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
186template <typename R QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_PARAMS>
187struct 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
204template <QGLIB_SIGNAL_IMPL_TEMPLATE_PARAMS>
205struct 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
232template <typename R QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_PARAMS>
233R 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
239template <typename R QGLIB_SIGNAL_IMPL_TRAILING_TEMPLATE_PARAMS>
240R 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
Wrapper class for GQuark.
Definition quark.h:43
Wrappers for Glib and GObject classes.
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