1
2 #if !defined( INCLUDED_ISIGNAL_H )
3 #define INCLUDED_ISIGNAL_H
4
5 #include "generic/callback.h"
6 #include "signal/signalfwd.h"
7
8 class SignalHandlerResult
9 {
10 bool value;
11 public:
SignalHandlerResult(bool value)12 explicit SignalHandlerResult( bool value ) : value( value ){
13 }
14 bool operator==( SignalHandlerResult other ) const {
15 return value == other.value;
16 }
17 bool operator!=( SignalHandlerResult other ) const {
18 return !operator==( other );
19 }
20 };
21
22 const SignalHandlerResult SIGNAL_CONTINUE_EMISSION = SignalHandlerResult( false );
23 const SignalHandlerResult SIGNAL_STOP_EMISSION = SignalHandlerResult( true );
24
25 template<typename Caller>
26 class SignalHandlerCaller1
27 {
28 public:
29 typedef typename Caller::first_argument_type first_argument_type;
30 typedef SignalHandlerResult result_type;
call(first_argument_type a1)31 static result_type call( first_argument_type a1 ){
32 Caller::call( a1 );
33 return SIGNAL_CONTINUE_EMISSION;
34 }
35 };
36
37 template<typename Caller>
38 class SignalHandlerCaller2
39 {
40 public:
41 typedef typename Caller::first_argument_type first_argument_type;
42 typedef typename Caller::second_argument_type second_argument_type;
43 typedef SignalHandlerResult result_type;
call(first_argument_type a1,second_argument_type a2)44 static result_type call( first_argument_type a1, second_argument_type a2 ){
45 Caller::call( a1, a2 );
46 return SIGNAL_CONTINUE_EMISSION;
47 }
48 };
49
50 template<typename Caller>
51 class SignalHandlerCaller3
52 {
53 public:
54 typedef typename Caller::first_argument_type first_argument_type;
55 typedef typename Caller::second_argument_type second_argument_type;
56 typedef typename Caller::third_argument_type third_argument_type;
57 typedef SignalHandlerResult result_type;
call(first_argument_type a1,second_argument_type a2,third_argument_type a3)58 static result_type call( first_argument_type a1, second_argument_type a2, third_argument_type a3 ){
59 Caller::call( a1, a2, a3 );
60 return SIGNAL_CONTINUE_EMISSION;
61 }
62 };
63
64 template<typename Caller>
65 class SignalHandlerCaller4
66 {
67 public:
68 typedef typename Caller::first_argument_type first_argument_type;
69 typedef typename Caller::second_argument_type second_argument_type;
70 typedef typename Caller::third_argument_type third_argument_type;
71 typedef typename Caller::fourth_argument_type fourth_argument_type;
72 typedef SignalHandlerResult result_type;
call(first_argument_type a1,second_argument_type a2,third_argument_type a3,fourth_argument_type a4)73 static result_type call( first_argument_type a1, second_argument_type a2, third_argument_type a3, fourth_argument_type a4 ){
74 Caller::call( a1, a2, a3, a4 );
75 return SIGNAL_CONTINUE_EMISSION;
76 }
77 };
78
79 class SignalHandler : public Callback0<SignalHandlerResult>
80 {
81 public:
82 template<typename Caller>
SignalHandler(const BindFirstOpaque<Caller> & caller)83 SignalHandler( const BindFirstOpaque<Caller>& caller )
84 : Callback0<SignalHandlerResult>( BindFirstOpaque<typename TypeEqual<
85 SignalHandlerResult,
86 Caller,
87 SignalHandlerCaller1<Caller>,
88 typename Caller::result_type
89 >::type>( caller.getBound() ) ){
90 }
91 };
92
93 template<typename Caller>
makeSignalHandler(const BindFirstOpaque<Caller> & caller)94 inline SignalHandler makeSignalHandler( const BindFirstOpaque<Caller>& caller ){
95 return SignalHandler( caller );
96 }
97 template<typename Caller>
makeSignalHandler(const Caller & caller,typename Caller::first_argument_type callee)98 inline SignalHandler makeSignalHandler( const Caller& caller, typename Caller::first_argument_type callee ){
99 return SignalHandler( BindFirstOpaque<Caller>( callee ) );
100 }
101
102
103 template<typename FirstArgument>
104 class SignalHandler1 : public Callback1<FirstArgument, SignalHandlerResult>
105 {
106 public:
107 template<typename Caller>
SignalHandler1(const BindFirstOpaque1<Caller> & caller)108 SignalHandler1( const BindFirstOpaque1<Caller>& caller )
109 : Callback1<FirstArgument, SignalHandlerResult>( BindFirstOpaque1<typename TypeEqual<
110 SignalHandlerResult,
111 Caller,
112 SignalHandlerCaller2<Caller>,
113 typename Caller::result_type
114 >::type>( caller.getBound() ) ){
115 }
116 };
117
118 template<typename Caller>
makeSignalHandler1(const BindFirstOpaque1<Caller> & caller)119 inline SignalHandler1<typename Caller::second_argument_type> makeSignalHandler1( const BindFirstOpaque1<Caller>& caller ){
120 return SignalHandler1<typename Caller::second_argument_type>( caller );
121 }
122 template<typename Caller>
makeSignalHandler1(const Caller & caller,typename Caller::first_argument_type callee)123 inline SignalHandler1<typename Caller::second_argument_type> makeSignalHandler1( const Caller& caller, typename Caller::first_argument_type callee ){
124 return SignalHandler1<typename Caller::second_argument_type>( BindFirstOpaque1<Caller>( callee ) );
125 }
126
127
128 template<typename FirstArgument, typename SecondArgument>
129 class SignalHandler2 : public Callback2<FirstArgument, SecondArgument, SignalHandlerResult>
130 {
131 public:
132 template<typename Caller>
SignalHandler2(const BindFirstOpaque2<Caller> & caller)133 SignalHandler2( const BindFirstOpaque2<Caller>& caller )
134 : Callback2<FirstArgument, SecondArgument, SignalHandlerResult>( BindFirstOpaque2<typename TypeEqual<
135 SignalHandlerResult,
136 Caller,
137 SignalHandlerCaller3<Caller>,
138 typename Caller::result_type
139 >::type>( caller.getBound() ) ){
140 }
141 };
142
143 template<typename Caller>
144 inline SignalHandler2<
145 typename Caller::second_argument_type,
146 typename Caller::third_argument_type
makeSignalHandler2(const BindFirstOpaque2<Caller> & caller)147 > makeSignalHandler2( const BindFirstOpaque2<Caller>& caller ){
148 return SignalHandler2<
149 typename Caller::second_argument_type,
150 typename Caller::third_argument_type
151 >( caller );
152 }
153 template<typename Caller>
154 inline SignalHandler2<
155 typename Caller::second_argument_type,
156 typename Caller::third_argument_type
makeSignalHandler2(const Caller & caller,typename Caller::first_argument_type callee)157 > makeSignalHandler2( const Caller& caller, typename Caller::first_argument_type callee ){
158 return SignalHandler2<
159 typename Caller::second_argument_type,
160 typename Caller::third_argument_type
161 >( BindFirstOpaque2<Caller>( callee ) );
162 }
163
164
165 template<typename FirstArgument, typename SecondArgument, typename ThirdArgument>
166 class SignalHandler3 : public Callback3<FirstArgument, SecondArgument, ThirdArgument, SignalHandlerResult>
167 {
168 public:
169 template<typename Caller>
SignalHandler3(const BindFirstOpaque3<Caller> & caller)170 SignalHandler3( const BindFirstOpaque3<Caller>& caller )
171 : Callback3<FirstArgument, SecondArgument, ThirdArgument, SignalHandlerResult>( BindFirstOpaque3<typename TypeEqual<
172 SignalHandlerResult,
173 Caller,
174 SignalHandlerCaller4<Caller>,
175 typename Caller::result_type
176 >::type>( caller.getBound() ) ){
177 }
178 };
179
180 template<typename Caller>
181 inline SignalHandler3<
182 typename Caller::second_argument_type,
183 typename Caller::third_argument_type,
184 typename Caller::fourth_argument_type
makeSignalHandler3(const BindFirstOpaque3<Caller> & caller)185 > makeSignalHandler3( const BindFirstOpaque3<Caller>& caller ){
186 return SignalHandler3<
187 typename Caller::second_argument_type,
188 typename Caller::third_argument_type,
189 typename Caller::fourth_argument_type
190 >( caller );
191 }
192 template<typename Caller>
193 inline SignalHandler3<
194 typename Caller::second_argument_type,
195 typename Caller::third_argument_type,
196 typename Caller::fourth_argument_type
makeSignalHandler3(const Caller & caller,typename Caller::first_argument_type callee)197 > makeSignalHandler3( const Caller& caller, typename Caller::first_argument_type callee ){
198 return SignalHandler3<
199 typename Caller::second_argument_type,
200 typename Caller::third_argument_type,
201 typename Caller::fourth_argument_type
202 >( BindFirstOpaque3<Caller>( callee ) );
203 }
204
205 #endif
206