vmap/libs/signal/isignal.h

167 lines
4.9 KiB
C
Raw Normal View History

2020-11-17 11:16:16 +00:00
#if !defined( INCLUDED_ISIGNAL_H )
#define INCLUDED_ISIGNAL_H
#include "generic/callback.h"
#include "signal/signalfwd.h"
class SignalHandlerResult
{
bool value;
public:
explicit SignalHandlerResult( bool value ) : value( value ){
}
bool operator==( SignalHandlerResult other ) const {
return value == other.value;
}
bool operator!=( SignalHandlerResult other ) const {
return !operator==( other );
}
};
const SignalHandlerResult SIGNAL_CONTINUE_EMISSION = SignalHandlerResult( false );
const SignalHandlerResult SIGNAL_STOP_EMISSION = SignalHandlerResult( true );
template<class Caller, class F>
class SignalHandlerCallerN;
2021-08-04 20:23:18 +00:00
template<class Caller, class R, class ... Ts>
2020-11-17 11:16:16 +00:00
class SignalHandlerCallerN<Caller, R(Ts...)> {
public:
2021-08-04 20:23:18 +00:00
using func = SignalHandlerResult(Ts ...);
2020-11-17 11:16:16 +00:00
2021-08-04 20:23:18 +00:00
static SignalHandlerResult call(Ts... args) {
Caller::call(args ...);
return SIGNAL_CONTINUE_EMISSION;
}
2020-11-17 11:16:16 +00:00
};
template<class Caller>
2021-08-04 20:23:18 +00:00
using SignalHandlerCaller = SignalHandlerCallerN<Caller, get_func<Caller> >;
2020-11-17 11:16:16 +00:00
template<class Caller>
using SignalHandlerCaller1 = SignalHandlerCaller<Caller>;
template<class Caller>
using SignalHandlerCaller2 = SignalHandlerCaller<Caller>;
template<typename Caller>
using SignalHandlerCaller3 = SignalHandlerCaller<Caller>;
template<typename Caller>
using SignalHandlerCaller4 = SignalHandlerCaller<Caller>;
template<typename Other, typename True, typename False, typename Type>
class TypeEqual {
public:
2021-08-04 20:23:18 +00:00
using type = False;
2020-11-17 11:16:16 +00:00
};
template<typename Other, typename True, typename False>
class TypeEqual<Other, True, False, Other> {
public:
2021-08-04 20:23:18 +00:00
using type = True;
2020-11-17 11:16:16 +00:00
};
template<class CB, template<class T> class Wrapper>
class SignalHandlerN : public CB {
public:
2021-08-04 20:23:18 +00:00
template<typename Caller>
SignalHandlerN(const BindFirstOpaque<Caller> &caller)
: CB(BindFirstOpaque<typename TypeEqual<
SignalHandlerResult,
Caller,
Wrapper<Caller>,
get_result_type<Caller>
>::type>(caller.getBound())) {
}
2020-11-17 11:16:16 +00:00
};
class SignalHandler : public SignalHandlerN<Callback<SignalHandlerResult()>, SignalHandlerCaller1> {
2021-08-04 20:23:18 +00:00
using SignalHandlerN<Callback<SignalHandlerResult()>, SignalHandlerCaller1>::SignalHandlerN;
2020-11-17 11:16:16 +00:00
};
template<typename Caller>
inline SignalHandler makeSignalHandler( const BindFirstOpaque<Caller>& caller ){
return SignalHandler( caller );
}
template<typename Caller>
inline SignalHandler makeSignalHandler(const Caller &caller, get_argument<Caller, 0> callee) {
return SignalHandler( BindFirstOpaque<Caller>( callee ) );
}
template<typename FirstArgument>
class SignalHandler1 : public SignalHandlerN<Callback<SignalHandlerResult(FirstArgument)>, SignalHandlerCaller2> {
2021-08-04 20:23:18 +00:00
using SignalHandlerN<Callback<SignalHandlerResult(FirstArgument)>, SignalHandlerCaller2>::SignalHandlerN;
2020-11-17 11:16:16 +00:00
};
template<typename Caller>
2021-08-04 20:23:18 +00:00
inline SignalHandler1<get_argument<Caller, 1> > makeSignalHandler1(const BindFirstOpaque<Caller> &caller) {
return SignalHandler1<get_argument<Caller, 1> >(caller);
2020-11-17 11:16:16 +00:00
}
template<typename Caller>
2021-08-04 20:23:18 +00:00
inline SignalHandler1<get_argument<Caller, 1> >
2020-11-17 11:16:16 +00:00
makeSignalHandler1(const Caller &caller, get_argument<Caller, 0> callee) {
2021-08-04 20:23:18 +00:00
return SignalHandler1<get_argument<Caller, 1> >(BindFirstOpaque<Caller>(callee));
2020-11-17 11:16:16 +00:00
}
template<typename FirstArgument, typename SecondArgument>
class SignalHandler2
2021-08-04 20:23:18 +00:00
: public SignalHandlerN<Callback<SignalHandlerResult(FirstArgument, SecondArgument)>, SignalHandlerCaller3> {
using SignalHandlerN<Callback<SignalHandlerResult(FirstArgument, SecondArgument)>, SignalHandlerCaller3>::SignalHandlerN;
2020-11-17 11:16:16 +00:00
};
template<typename Caller>
inline SignalHandler2<
2021-08-04 20:23:18 +00:00
get_argument<Caller, 1>,
get_argument<Caller, 2>
> makeSignalHandler2(const BindFirstOpaque<Caller> &caller) {
2020-11-17 11:16:16 +00:00
return SignalHandler2<
2021-08-04 20:23:18 +00:00
get_argument<Caller, 1>,
get_argument<Caller, 2>
>( caller );
2020-11-17 11:16:16 +00:00
}
template<typename Caller>
inline SignalHandler2<
2021-08-04 20:23:18 +00:00
get_argument<Caller, 1>,
get_argument<Caller, 2>
> makeSignalHandler2(const Caller &caller, get_argument<Caller, 0> callee) {
2020-11-17 11:16:16 +00:00
return SignalHandler2<
2021-08-04 20:23:18 +00:00
get_argument<Caller, 1>,
get_argument<Caller, 2>
>(BindFirstOpaque<Caller>(callee));
2020-11-17 11:16:16 +00:00
}
template<typename FirstArgument, typename SecondArgument, typename ThirdArgument>
class SignalHandler3
2021-08-04 20:23:18 +00:00
: public SignalHandlerN<Callback<SignalHandlerResult(FirstArgument, SecondArgument, ThirdArgument)>, SignalHandlerCaller4> {
using SignalHandlerN<Callback<SignalHandlerResult(FirstArgument, SecondArgument, ThirdArgument)>, SignalHandlerCaller4>::SignalHandlerN;
2020-11-17 11:16:16 +00:00
};
template<typename Caller>
inline SignalHandler3<
2021-08-04 20:23:18 +00:00
get_argument<Caller, 1>,
get_argument<Caller, 2>,
get_argument<Caller, 3>
> makeSignalHandler3(const BindFirstOpaque<Caller> &caller) {
2020-11-17 11:16:16 +00:00
return SignalHandler3<
2021-08-04 20:23:18 +00:00
get_argument<Caller, 1>,
get_argument<Caller, 2>,
get_argument<Caller, 3>
>( caller );
2020-11-17 11:16:16 +00:00
}
template<typename Caller>
inline SignalHandler3<
2021-08-04 20:23:18 +00:00
get_argument<Caller, 1>,
get_argument<Caller, 2>,
get_argument<Caller, 3>
> makeSignalHandler3(const Caller &caller, get_argument<Caller, 0> callee) {
2020-11-17 11:16:16 +00:00
return SignalHandler3<
2021-08-04 20:23:18 +00:00
get_argument<Caller, 1>,
get_argument<Caller, 2>,
get_argument<Caller, 3>
>(BindFirstOpaque<Caller>(callee));
2020-11-17 11:16:16 +00:00
}
#endif