2 #if !defined( INCLUDED_ISIGNAL_H )
3 #define INCLUDED_ISIGNAL_H
5 #include "generic/callback.h"
6 #include "signal/signalfwd.h"
8 class SignalHandlerResult
12 explicit SignalHandlerResult( bool value ) : value( value ){
14 bool operator==( SignalHandlerResult other ) const {
15 return value == other.value;
17 bool operator!=( SignalHandlerResult other ) const {
18 return !operator==( other );
22 const SignalHandlerResult SIGNAL_CONTINUE_EMISSION = SignalHandlerResult( false );
23 const SignalHandlerResult SIGNAL_STOP_EMISSION = SignalHandlerResult( true );
25 template<class Caller, class F>
26 class SignalHandlerCallerN;
28 template<class Caller, class R, class... Ts>
29 class SignalHandlerCallerN<Caller, R(Ts...)> {
31 using func = SignalHandlerResult(Ts...);
33 static SignalHandlerResult call(Ts... args) {
34 Caller::call(args...);
35 return SIGNAL_CONTINUE_EMISSION;
39 template<class Caller>
40 using SignalHandlerCaller = SignalHandlerCallerN<Caller, get_func<Caller>>;
42 template<class Caller>
43 using SignalHandlerCaller1 = SignalHandlerCaller<Caller>;
45 template<class Caller>
46 using SignalHandlerCaller2 = SignalHandlerCaller<Caller>;
48 template<typename Caller>
49 using SignalHandlerCaller3 = SignalHandlerCaller<Caller>;
51 template<typename Caller>
52 using SignalHandlerCaller4 = SignalHandlerCaller<Caller>;
54 template<typename Other, typename True, typename False, typename Type>
60 template<typename Other, typename True, typename False>
61 class TypeEqual<Other, True, False, Other> {
66 template<class CB, template<class T> class Wrapper>
67 class SignalHandlerN : public CB {
69 template<typename Caller>
70 SignalHandlerN(const BindFirstOpaque<Caller> &caller)
71 : CB(BindFirstOpaque<typename TypeEqual<
75 get_result_type<Caller>
76 >::type>(caller.getBound())) {
80 class SignalHandler : public SignalHandlerN<Callback<SignalHandlerResult()>, SignalHandlerCaller1> {
81 using SignalHandlerN<Callback<SignalHandlerResult()>, SignalHandlerCaller1>::SignalHandlerN;
84 template<typename Caller>
85 inline SignalHandler makeSignalHandler( const BindFirstOpaque<Caller>& caller ){
86 return SignalHandler( caller );
88 template<typename Caller>
89 inline SignalHandler makeSignalHandler(const Caller &caller, get_argument<Caller, 0> callee) {
90 return SignalHandler( BindFirstOpaque<Caller>( callee ) );
93 template<typename FirstArgument>
94 class SignalHandler1 : public SignalHandlerN<Callback<SignalHandlerResult(FirstArgument)>, SignalHandlerCaller2> {
95 using SignalHandlerN<Callback<SignalHandlerResult(FirstArgument)>, SignalHandlerCaller2>::SignalHandlerN;
98 template<typename Caller>
99 inline SignalHandler1<get_argument<Caller, 1>> makeSignalHandler1(const BindFirstOpaque<Caller> &caller) {
100 return SignalHandler1<get_argument<Caller, 1>>(caller);
102 template<typename Caller>
103 inline SignalHandler1<get_argument<Caller, 1>>
104 makeSignalHandler1(const Caller &caller, get_argument<Caller, 0> callee) {
105 return SignalHandler1<get_argument<Caller, 1>>(BindFirstOpaque<Caller>(callee));
108 template<typename FirstArgument, typename SecondArgument>
110 : public SignalHandlerN<Callback<SignalHandlerResult(FirstArgument, SecondArgument)>, SignalHandlerCaller3> {
111 using SignalHandlerN<Callback<SignalHandlerResult(FirstArgument, SecondArgument)>, SignalHandlerCaller3>::SignalHandlerN;
114 template<typename Caller>
115 inline SignalHandler2<
116 get_argument<Caller, 1>,
117 get_argument<Caller, 2>
118 > makeSignalHandler2(const BindFirstOpaque<Caller> &caller) {
119 return SignalHandler2<
120 get_argument<Caller, 1>,
121 get_argument<Caller, 2>
124 template<typename Caller>
125 inline SignalHandler2<
126 get_argument<Caller, 1>,
127 get_argument<Caller, 2>
128 > makeSignalHandler2(const Caller &caller, get_argument<Caller, 0> callee) {
129 return SignalHandler2<
130 get_argument<Caller, 1>,
131 get_argument<Caller, 2>
132 >(BindFirstOpaque<Caller>(callee));
135 template<typename FirstArgument, typename SecondArgument, typename ThirdArgument>
137 : public SignalHandlerN<Callback<SignalHandlerResult(FirstArgument, SecondArgument, ThirdArgument)>, SignalHandlerCaller4> {
138 using SignalHandlerN<Callback<SignalHandlerResult(FirstArgument, SecondArgument, ThirdArgument)>, SignalHandlerCaller4>::SignalHandlerN;
141 template<typename Caller>
142 inline SignalHandler3<
143 get_argument<Caller, 1>,
144 get_argument<Caller, 2>,
145 get_argument<Caller, 3>
146 > makeSignalHandler3(const BindFirstOpaque<Caller> &caller) {
147 return SignalHandler3<
148 get_argument<Caller, 1>,
149 get_argument<Caller, 2>,
150 get_argument<Caller, 3>
153 template<typename Caller>
154 inline SignalHandler3<
155 get_argument<Caller, 1>,
156 get_argument<Caller, 2>,
157 get_argument<Caller, 3>
158 > makeSignalHandler3(const Caller &caller, get_argument<Caller, 0> callee) {
159 return SignalHandler3<
160 get_argument<Caller, 1>,
161 get_argument<Caller, 2>,
162 get_argument<Caller, 3>
163 >(BindFirstOpaque<Caller>(callee));