X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=libs%2Fgeneric%2Fcallback.h;h=9a1c9b1718aa262dbb0a2ae706cbecddceb69168;hb=18d60f90d7603cb420150739251cf98519c57406;hp=2ce007fcb2780fbedfdb4b2adee11567f509786d;hpb=dac8329952745dbb494bad1c301e44bab05ec0db;p=xonotic%2Fnetradiant.git diff --git a/libs/generic/callback.h b/libs/generic/callback.h index 2ce007fc..9a1c9b17 100644 --- a/libs/generic/callback.h +++ b/libs/generic/callback.h @@ -27,7 +27,6 @@ #include #include "functional.h" -#include "callbackfwd.h" template inline void* convertToOpaque( Type* t ){ @@ -89,104 +88,6 @@ static const Type* apply( void* p ){ } }; -template -class BindFirstOpaque -{ -typedef typename Caller::first_argument_type FirstBound; -FirstBound firstBound; -public: -typedef typename Caller::result_type result_type; -explicit BindFirstOpaque( FirstBound firstBound ) : firstBound( firstBound ){ -} -result_type operator()() const { - return Caller::call( firstBound ); -} -FirstBound getBound() const { - return firstBound; -} -static result_type thunk( void* environment ){ - return Caller::call( ConvertFromOpaque::apply( environment ) ); -} -void* getEnvironment() const { - return convertToOpaque( firstBound ); -} -}; - -template -class BindFirstOpaque1 -{ -typedef typename Caller::first_argument_type FirstBound; -FirstBound firstBound; -public: -typedef typename Caller::second_argument_type first_argument_type; -typedef typename Caller::result_type result_type; -explicit BindFirstOpaque1( FirstBound firstBound ) : firstBound( firstBound ){ -} -result_type operator()( first_argument_type a1 ) const { - return Caller::call( firstBound, a1 ); -} -FirstBound getBound() const { - return firstBound; -} -static result_type thunk( void* environment, first_argument_type a1 ){ - return Caller::call( ConvertFromOpaque::apply( environment ), a1 ); -} -void* getEnvironment() const { - return convertToOpaque( firstBound ); -} -}; - -template -class BindFirstOpaque2 -{ -typedef typename Caller::first_argument_type FirstBound; -FirstBound firstBound; -public: -typedef typename Caller::second_argument_type first_argument_type; -typedef typename Caller::third_argument_type second_argument_type; -typedef typename Caller::result_type result_type; -explicit BindFirstOpaque2( FirstBound firstBound ) : firstBound( firstBound ){ -} -result_type operator()( first_argument_type a1, second_argument_type a2 ) const { - return Caller::call( firstBound, a1, a2 ); -} -FirstBound getBound() const { - return firstBound; -} -static result_type thunk( void* environment, first_argument_type a1, second_argument_type a2 ){ - return Caller::call( ConvertFromOpaque::apply( environment ), a1, a2 ); -} -void* getEnvironment() const { - return convertToOpaque( firstBound ); -} -}; - -template -class BindFirstOpaque3 -{ -typedef typename Caller::first_argument_type FirstBound; -FirstBound firstBound; -public: -typedef typename Caller::second_argument_type first_argument_type; -typedef typename Caller::third_argument_type second_argument_type; -typedef typename Caller::fourth_argument_type third_argument_type; -typedef typename Caller::result_type result_type; -explicit BindFirstOpaque3( FirstBound firstBound ) : firstBound( firstBound ){ -} -result_type operator()( first_argument_type a1, second_argument_type a2, third_argument_type a3 ) const { - return Caller::call( firstBound, a1, a2, a3 ); -} -FirstBound getBound() const { - return firstBound; -} -static result_type thunk( void* environment, first_argument_type a1, second_argument_type a2, third_argument_type a3 ){ - return Caller::call( ConvertFromOpaque::apply( environment ), a1, a2, a3 ); -} -void* getEnvironment() const { - return convertToOpaque( firstBound ); -} -}; - template class CallbackBase { @@ -218,373 +119,185 @@ inline bool operator<( const CallbackBase& self, const CallbackBase +class BindFirstOpaqueN; -/// \brief Combines a void pointer with a pointer to a function which operates on a void pointer. -/// -/// Use with the callback constructors MemberCaller, ConstMemberCaller, ReferenceCaller, ConstReferenceCaller, PointerCaller, ConstPointerCaller and FreeCaller. -template -class Callback0 : public CallbackBase -{ -typedef CallbackBase Base; -static Result nullThunk( void* ){ -} - +template +class BindFirstOpaqueN { + FirstBound firstBound; public: -typedef Result result_type; + explicit BindFirstOpaqueN(FirstBound firstBound) : firstBound(firstBound) { + } -Callback0() : Base( 0, nullThunk ){ -} -template -Callback0( const BindFirstOpaque& caller ) : Base( caller.getEnvironment(), BindFirstOpaque::thunk ){ -} -Callback0( void* environment, typename Base::Thunk function ) : Base( environment, function ){ -} -result_type operator()() const { - return Base::getThunk() ( Base::getEnvironment() ); -} -}; + R operator()(Ts... args) const { + return Caller::call(firstBound, args...); + } -template -inline Callback0 makeCallback0( const Caller& caller, typename Caller::first_argument_type callee ){ - return Callback0( BindFirstOpaque( callee ) ); -} -template -inline Callback0 makeStatelessCallback0( const Caller& caller ){ - return makeCallback0( Caller0To1(), 0 ); -} + FirstBound getBound() const { + return firstBound; + } -typedef Callback0 Callback; + static R thunk(void *environment, Ts... args) { + return Caller::call(ConvertFromOpaque::apply(environment), args...); + } + void *getEnvironment() const { + return convertToOpaque(firstBound); + } +}; +template +using BindFirstOpaque = BindFirstOpaqueN>; -/// \brief Combines a void pointer with a pointer to a function which operates on a void pointer and one other argument. +/// \brief Combines a void pointer with a pointer to a function which operates on a void pointer. /// -/// Use with the callback constructors MemberCaller1, ConstMemberCaller1, ReferenceCaller1, ConstReferenceCaller1, PointerCaller1, ConstPointerCaller1 and FreeCaller1. -template -class Callback1 : public CallbackBase -{ -typedef CallbackBase Base; -static Result nullThunk( void*, FirstArgument ){ -} +/// Use with the callback constructors MemberCaller0, ConstMemberCaller0, ReferenceCaller0, ConstReferenceCaller0, PointerCaller0, ConstPointerCaller0 and FreeCaller0. +template +class Callback; -public: -typedef FirstArgument first_argument_type; -typedef Result result_type; +template +class Callback : public CallbackBase { + using Base = CallbackBase; -Callback1() : Base( 0, nullThunk ){ -} -template -Callback1( const BindFirstOpaque1& caller ) : Base( caller.getEnvironment(), BindFirstOpaque1::thunk ){ -} -Callback1( void* environment, typename Base::Thunk function ) : Base( environment, function ){ -} -result_type operator()( FirstArgument firstArgument ) const { - return Base::getThunk() ( Base::getEnvironment(), firstArgument ); -} -}; + static R nullThunk(void *, Ts...) { + } -template -inline Callback1 makeCallback1( const Caller& caller, typename Caller::first_argument_type callee ){ - return Callback1( BindFirstOpaque1( callee ) ); -} -template -inline Callback1 makeStatelessCallback1( const Caller& caller ){ - return makeCallback1( Caller1To2(), 0 ); -} +public: + using func = R(Ts...); + Callback() : Base(0, nullThunk) { + } -/// \brief Combines a void pointer with a pointer to a function which operates on a void pointer and two other arguments. -/// -template -class Callback2 : public CallbackBase -{ -typedef CallbackBase Base; -static Result nullThunk( void*, FirstArgument, SecondArgument ){ -} + template + Callback(const BindFirstOpaque &caller) : Base(caller.getEnvironment(), BindFirstOpaque::thunk) { + } -public: -typedef FirstArgument first_argument_type; -typedef SecondArgument second_argument_type; -typedef Result result_type; + Callback(void *environment, typename Base::Thunk function) : Base(environment, function) { + } -Callback2() : Base( 0, nullThunk ){ -} -template -Callback2( const BindFirstOpaque2& caller ) : Base( caller.getEnvironment(), BindFirstOpaque2::thunk ){ -} -Callback2( void* environment, typename Base::Thunk function ) : Base( environment, function ){ -} -result_type operator()( FirstArgument firstArgument, SecondArgument secondArgument ) const { - return Base::getThunk() ( Base::getEnvironment(), firstArgument, secondArgument ); -} + R operator()(Ts... args) const { + return Base::getThunk()(Base::getEnvironment(), args...); + } }; -template -inline Callback2< - typename Caller::second_argument_type, - typename Caller::third_argument_type, - typename Caller::result_type - > makeCallback2( const Caller& caller, typename Caller::first_argument_type callee ){ - return Callback2< - typename Caller::second_argument_type, - typename Caller::third_argument_type, - typename Caller::result_type - >( BindFirstOpaque2( callee ) ); -} -template -inline Callback2< - typename Caller::first_argument_type, - typename Caller::second_argument_type, - typename Caller::result_type - > makeStatelessCallback2( const Caller& caller ){ - return makeCallback2( Caller2To3(), 0 ); -} +namespace detail { + template + struct Arglist; + template + struct Arglist { + using type = R(Head, Ts...); -/// \brief Combines a void pointer with a pointer to a function which operates on a void pointer and three other arguments. -/// -template -class Callback3 : public CallbackBase -{ -typedef CallbackBase Base; -static Result nullThunk( void*, FirstArgument, SecondArgument, ThirdArgument ){ -} + template + using unshift = Arglist; -public: -typedef FirstArgument first_argument_type; -typedef SecondArgument second_argument_type; -typedef ThirdArgument third_argument_type; -typedef Result result_type; + using shift = Arglist; + }; -Callback3() : Base( 0, nullThunk ){ -} -template -Callback3( const BindFirstOpaque3& caller ) : Base( caller.getEnvironment(), BindFirstOpaque3::thunk ){ -} -Callback3( void* environment, typename Base::Thunk function ) : Base( environment, function ){ -} -result_type operator()( FirstArgument firstArgument, SecondArgument secondArgument, ThirdArgument thirdArgument ) const { - return Base::getThunk() ( Base::getEnvironment(), firstArgument, secondArgument, thirdArgument ); + template + struct Arglist { + using type = R(Ts...); + + template + using unshift = Arglist; + }; } -}; template -inline Callback3< - typename Caller::second_argument_type, - typename Caller::third_argument_type, - typename Caller::fourth_argument_type, - typename Caller::result_type - > makeCallback3( const Caller& caller, typename Caller::first_argument_type callee ){ - return Callback3< - typename Caller::second_argument_type, - typename Caller::third_argument_type, - typename Caller::fourth_argument_type, - typename Caller::result_type - >( BindFirstOpaque3( callee ) ); +inline Callback>::shift::type> makeCallback(const Caller &caller, get_argument callee) { + return Callback>::shift::type>(BindFirstOpaque(callee)); } + template -inline Callback3< - typename Caller::first_argument_type, - typename Caller::second_argument_type, - typename Caller::third_argument_type, - typename Caller::result_type - > makeStatelessCallback3( const Caller& caller ){ - return makeCallback3( Caller3To4(), 0 ); +inline Callback> makeStatelessCallback(const Caller &caller) { + return makeCallback(CallerShiftFirst>::template unshift::type>(), nullptr); } - /// \brief Forms a Callback from a non-const Environment reference and a non-const Environment member-function. /// /// \dontinclude generic/callback.cpp -/// \skipline MemberCaller example +/// \skipline MemberCaller0 example /// \until end example -template -class MemberCaller : public BindFirstOpaque< Member > -{ -public: -MemberCaller( Environment& environment ) : BindFirstOpaque< Member >( environment ){ -} -}; + +template member> +using MemberCaller = BindFirstOpaque::template instance>; /// \brief Forms a Callback from a const Environment reference and a const Environment member-function. /// /// \dontinclude generic/callback.cpp -/// \skipline MemberCaller example +/// \skipline MemberCaller0 example /// \until end example -template -class ConstMemberCaller : public BindFirstOpaque< ConstMember > -{ -public: -ConstMemberCaller( const Environment& environment ) : BindFirstOpaque< ConstMember >( environment ){ -} -}; - -/// \brief Forms a Callback from a non-const Environment reference and a const Environment member-function which takes one argument. -template -class MemberCaller1 : public BindFirstOpaque1< Member1 > -{ -public: -MemberCaller1( Environment& environment ) : BindFirstOpaque1< Member1 >( environment ){ -} -}; - -/// \brief Forms a Callback from a const Environment reference and a const Environment member-function which takes one argument. -template -class ConstMemberCaller1 : public BindFirstOpaque1< ConstMember1 > -{ -public: -ConstMemberCaller1( const Environment& environment ) : BindFirstOpaque1< ConstMember1 >( environment ){ -} -}; +template member> +using ConstMemberCaller = BindFirstOpaque::template instance>; /// \brief Forms a Callback from a non-const Environment reference and a free function which operates on a non-const Environment reference. /// /// \dontinclude generic/callback.cpp -/// \skipline ReferenceCaller example +/// \skipline ReferenceCaller0 example /// \until end example -template -class ReferenceCaller : public BindFirstOpaque< Function1 > -{ -public: -ReferenceCaller( Environment& environment ) : BindFirstOpaque< Function1 >( environment ){ -} -}; +template::template unshift::type *func> +using ReferenceCaller = BindFirstOpaque::template unshift::type>::template instance>; /// \brief Forms a Callback from a const Environment reference and a free function which operates on a const Environment reference. /// /// \dontinclude generic/callback.cpp -/// \skipline ReferenceCaller example +/// \skipline ReferenceCaller0 example /// \until end example -template -class ConstReferenceCaller : public BindFirstOpaque< Function1 > -{ -public: -ConstReferenceCaller( const Environment& environment ) : BindFirstOpaque< Function1 >( environment ){ -} -}; - -/// \brief Forms a Callback from a non-const Environment reference and a free function which operates on a non-const Environment reference and one other argument. -template -class ReferenceCaller1 : public BindFirstOpaque1< Function2 > -{ -public: -ReferenceCaller1( Environment& environment ) : BindFirstOpaque1< Function2 >( environment ){ -} -}; - -/// \brief Forms a Callback from a const Environment reference and a free function which operates on a const Environment reference and one other argument. -template -class ConstReferenceCaller1 : public BindFirstOpaque1< Function2 > -{ -public: -ConstReferenceCaller1( const Environment& environment ) : BindFirstOpaque1< Function2 >( environment ){ -} -}; +template::template unshift::type *func> +using ConstReferenceCaller = BindFirstOpaque::template unshift::type>::template instance>; /// \brief Forms a Callback from a non-const Environment pointer and a free function which operates on a non-const Environment pointer. -template -class PointerCaller : public BindFirstOpaque< Function1 > -{ -public: -PointerCaller( Environment* environment ) : BindFirstOpaque< Function1 >( environment ){ -} -}; +template::template unshift::type *func> +using PointerCaller = BindFirstOpaque::template unshift::type>::template instance>; /// \brief Forms a Callback from a const Environment pointer and a free function which operates on a const Environment pointer. -template -class ConstPointerCaller : public BindFirstOpaque< Function1 > -{ +template::template unshift::type *func> +using ConstPointerCaller = BindFirstOpaque::template unshift::type>::template instance>; + +/// \brief Forms a Callback from a free function +template +class FreeCaller : public BindFirstOpaque::template instance, + typename detail::Arglist::template unshift::type +>> { public: -ConstPointerCaller( const Environment* environment ) : BindFirstOpaque< Function1 >( environment ){ -} -}; - -/// \brief Forms a Callback from a non-const Environment pointer and a free function which operates on a non-const Environment pointer and one other argument. -template -class PointerCaller1 : public BindFirstOpaque1< Function2 > -{ -public: -PointerCaller1( Environment* environment ) : BindFirstOpaque1< Function2 >( environment ){ -} -}; - -/// \brief Forms a Callback from a const Environment pointer and a free function which operates on a const Environment pointer and one other argument. -template -class ConstPointerCaller1 : public BindFirstOpaque1< Function2 > -{ -public: -ConstPointerCaller1( const Environment* environment ) : BindFirstOpaque1< Function2 >( environment ){ -} + FreeCaller() + : BindFirstOpaque::template instance, + typename detail::Arglist::template unshift::type + >>(nullptr) { + } }; -/// \brief Forms a Callback from a free function which takes no arguments. -template -class FreeCaller : public BindFirstOpaque< Caller0To1< Function0 > > -{ -public: -FreeCaller() : BindFirstOpaque< Caller0To1< Function0 > >( 0 ){ -} -}; - -/// \brief Forms a Callback from a free function which takes a single argument. -template -class FreeCaller1 : public BindFirstOpaque1< Caller1To2< Function1 > > -{ -public: -FreeCaller1() : BindFirstOpaque1< Caller1To2< Function1 > >( 0 ){ -} -}; - - -/// \brief Constructs a Callback from a non-const \p functor with zero arguments. -/// -/// \param Functor Must define \c operator()(). -template -inline Callback makeCallback( Functor& functor ){ - return Callback( MemberCaller( functor ) ); -} - -/// \brief Constructs a Callback from a const \p functor with zero arguments. -/// -/// \param Functor Must define const \c operator()(). -template -inline Callback makeCallback( const Functor& functor ){ - return Callback( ConstMemberCaller( functor ) ); -} - -/// \brief Constructs a Callback1 from a non-const \p functor with one argument. +/// \brief Constructs a Callback1 from a non-const \p functor /// /// \param Functor Must define \c first_argument_type and \c operator()(first_argument_type). template -inline Callback1 makeCallback1( Functor& functor ){ - typedef typename Functor::first_argument_type FirstArgument; - return Callback1( MemberCaller1( functor ) ); +inline Callback> makeCallback(Functor &functor) { + return Callback>(MemberCaller, &Functor::operator()>(functor)); } -/// \brief Constructs a Callback1 from a const \p functor with one argument. +/// \brief Constructs a Callback1 from a const \p functor /// /// \param Functor Must define \c first_argument_type and const \c operator()(first_argument_type). template -inline Callback1 makeCallback1( const Functor& functor ){ - typedef typename Functor::first_argument_type FirstArgument; - return Callback1( ConstMemberCaller1( functor ) ); +inline Callback> makeCallback(const Functor &functor) { + return Callback>(ConstMemberCaller, &Functor::operator()>(functor)); } +using BoolImportCallback = Callback; +using BoolExportCallback = Callback; -typedef Callback1 BoolImportCallback; -typedef Callback1 BoolExportCallback; - -typedef Callback1 IntImportCallback; -typedef Callback1 IntExportCallback; - -typedef Callback1 FloatImportCallback; -typedef Callback1 FloatExportCallback; +using IntImportCallback = Callback; +using IntExportCallback = Callback; -typedef Callback1 StringImportCallback; -typedef Callback1 StringExportCallback; +using FloatImportCallback = Callback; +using FloatExportCallback = Callback; -typedef Callback1 SizeImportCallback; -typedef Callback1 SizeExportCallback; +using StringImportCallback = Callback; +using StringExportCallback = Callback; +using SizeImportCallback = Callback; +using SizeExportCallback = Callback; #endif