From: TimePath Date: Sun, 31 Dec 2017 05:58:54 +0000 (+1100) Subject: Embrace variadic templates X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=3df6d45c403dbfbb0c772e8fc7a661a52c1d3244;p=xonotic%2Fnetradiant.git Embrace variadic templates --- diff --git a/libs/generic/callback.h b/libs/generic/callback.h index 2ce007fc..ef74e0cc 100644 --- a/libs/generic/callback.h +++ b/libs/generic/callback.h @@ -89,104 +89,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,38 +120,79 @@ inline bool operator<( const CallbackBase& self, const CallbackBase +class BindFirstOpaqueN; + +template +class BindFirstOpaqueN { + FirstBound firstBound; +public: + explicit BindFirstOpaqueN(FirstBound firstBound) : firstBound(firstBound) { + } + + R operator()(Ts... args) const { + return Caller::call(firstBound, args...); + } + + FirstBound getBound() const { + return firstBound; + } + + static R thunk(void *environment, Ts... args) { + return Caller::call(ConvertFromOpaque::apply(environment), args...); + } + + void *getEnvironment() const { + return convertToOpaque(firstBound); + } +}; + +template +using BindFirstOpaque = BindFirstOpaqueN; + +template +class CallbackN; + +template +class CallbackN : public CallbackBase { + using Base = CallbackBase; + + static R nullThunk(void *, Ts...) { + } + +public: + using func = R(Ts...); + + CallbackN() : Base(0, nullThunk) { + } + + template + CallbackN(const BindFirstOpaque &caller) : Base(caller.getEnvironment(), BindFirstOpaque::thunk) { + } + + CallbackN(void *environment, typename Base::Thunk function) : Base(environment, function) { + } + + R operator()(Ts... args) const { + return Base::getThunk()(Base::getEnvironment(), args...); + } +}; /// \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 Callback0 : public CallbackN { public: -typedef Result result_type; - -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() ); -} + using CallbackN::CallbackN; }; template -inline Callback0 makeCallback0( const Caller& caller, typename Caller::first_argument_type callee ){ - return Callback0( BindFirstOpaque( callee ) ); +inline Callback0> makeCallback0(const Caller &caller, get_argument callee) { + return Callback0>(BindFirstOpaque(callee)); } template -inline Callback0 makeStatelessCallback0( const Caller& caller ){ +inline Callback0> makeStatelessCallback0(const Caller &caller) { return makeCallback0( Caller0To1(), 0 ); } @@ -260,35 +203,19 @@ typedef Callback0 Callback; /// \brief Combines a void pointer with a pointer to a function which operates on a void pointer and one other argument. /// /// 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 ){ -} - +template +class Callback1 : public CallbackN { public: -typedef FirstArgument first_argument_type; -typedef Result result_type; - -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 ); -} + using CallbackN::CallbackN; }; template -inline Callback1 makeCallback1( const Caller& caller, typename Caller::first_argument_type callee ){ - return Callback1( BindFirstOpaque1( callee ) ); +inline Callback1, get_result_type> +makeCallback1(const Caller &caller, get_argument callee) { + return Callback1, get_result_type>(BindFirstOpaque(callee)); } template -inline Callback1 makeStatelessCallback1( const Caller& caller ){ +inline Callback1, get_result_type> makeStatelessCallback1(const Caller &caller) { return makeCallback1( Caller1To2(), 0 ); } @@ -296,47 +223,29 @@ inline Callback1 -class Callback2 : public CallbackBase -{ -typedef CallbackBase Base; -static Result nullThunk( void*, FirstArgument, SecondArgument ){ -} - +class Callback2 : public CallbackN { public: -typedef FirstArgument first_argument_type; -typedef SecondArgument second_argument_type; -typedef Result result_type; - -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 ); -} + using CallbackN::CallbackN; }; 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 ){ + get_argument, + get_argument, + get_result_type +> makeCallback2(const Caller &caller, get_argument callee) { return Callback2< - typename Caller::second_argument_type, - typename Caller::third_argument_type, - typename Caller::result_type - >( BindFirstOpaque2( callee ) ); + get_argument, + get_argument, + get_result_type + >(BindFirstOpaque(callee)); } template inline Callback2< - typename Caller::first_argument_type, - typename Caller::second_argument_type, - typename Caller::result_type - > makeStatelessCallback2( const Caller& caller ){ + get_argument, + get_argument, + get_result_type +> makeStatelessCallback2(const Caller &caller) { return makeCallback2( Caller2To3(), 0 ); } @@ -344,51 +253,32 @@ inline Callback2< /// \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 ){ -} - +class Callback3 : public CallbackN { public: -typedef FirstArgument first_argument_type; -typedef SecondArgument second_argument_type; -typedef ThirdArgument third_argument_type; -typedef Result result_type; - -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 ); -} + using CallbackN::CallbackN; }; 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 ){ + get_argument, + get_argument, + get_argument, + get_result_type +> makeCallback3(const Caller &caller, get_argument callee) { return Callback3< - typename Caller::second_argument_type, - typename Caller::third_argument_type, - typename Caller::fourth_argument_type, - typename Caller::result_type - >( BindFirstOpaque3( callee ) ); + get_argument, + get_argument, + get_argument, + get_result_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 ){ + get_argument, + get_argument, + get_argument, + get_result_type +> makeStatelessCallback3(const Caller &caller) { return makeCallback3( Caller3To4(), 0 ); } @@ -398,141 +288,79 @@ inline Callback3< /// \dontinclude generic/callback.cpp /// \skipline MemberCaller example /// \until end example -template -class MemberCaller : public BindFirstOpaque< Member > -{ -public: -MemberCaller( Environment& environment ) : BindFirstOpaque< Member >( environment ){ -} -}; +template +using MemberCaller = BindFirstOpaque>; /// \brief Forms a Callback from a const Environment reference and a const Environment member-function. /// /// \dontinclude generic/callback.cpp /// \skipline MemberCaller example /// \until end example -template -class ConstMemberCaller : public BindFirstOpaque< ConstMember > -{ -public: -ConstMemberCaller( const Environment& environment ) : BindFirstOpaque< ConstMember >( environment ){ -} -}; +template +using ConstMemberCaller = BindFirstOpaque>; /// \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 ){ -} -}; +template +using MemberCaller1 = BindFirstOpaque>; /// \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 +using ConstMemberCaller1 = BindFirstOpaque>; /// \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 /// \until end example -template -class ReferenceCaller : public BindFirstOpaque< Function1 > -{ -public: -ReferenceCaller( Environment& environment ) : BindFirstOpaque< Function1 >( environment ){ -} -}; +template +using ReferenceCaller = BindFirstOpaque>; /// \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 /// \until end example -template -class ConstReferenceCaller : public BindFirstOpaque< Function1 > -{ -public: -ConstReferenceCaller( const Environment& environment ) : BindFirstOpaque< Function1 >( environment ){ -} -}; +template +using ConstReferenceCaller = BindFirstOpaque>; /// \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 ){ -} -}; +template +using ReferenceCaller1 = BindFirstOpaque>; /// \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 +using ConstReferenceCaller1 = BindFirstOpaque>; /// \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 +using PointerCaller = BindFirstOpaque>; /// \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 > -{ -public: -ConstPointerCaller( const Environment* environment ) : BindFirstOpaque< Function1 >( environment ){ -} -}; +template +using ConstPointerCaller = BindFirstOpaque>; /// \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 ){ -} -}; +template +using PointerCaller1 = BindFirstOpaque>; /// \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 ){ -} -}; +template +using ConstPointerCaller1 = BindFirstOpaque>; /// \brief Forms a Callback from a free function which takes no arguments. -template -class FreeCaller : public BindFirstOpaque< Caller0To1< Function0 > > -{ +template +class FreeCaller : public BindFirstOpaque>> { public: -FreeCaller() : BindFirstOpaque< Caller0To1< Function0 > >( 0 ){ -} + FreeCaller() : BindFirstOpaque>>(0) { + } }; /// \brief Forms a Callback from a free function which takes a single argument. -template -class FreeCaller1 : public BindFirstOpaque1< Caller1To2< Function1 > > -{ +template +class FreeCaller1 : public BindFirstOpaque>> { public: -FreeCaller1() : BindFirstOpaque1< Caller1To2< Function1 > >( 0 ){ -} + FreeCaller1() : BindFirstOpaque>>(0) { + } }; @@ -556,8 +384,8 @@ inline Callback makeCallback( const Functor& 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; +inline Callback1> makeCallback1(Functor &functor) { + typedef get_argument FirstArgument; return Callback1( MemberCaller1( functor ) ); } @@ -565,8 +393,8 @@ inline Callback1 makeCallback1( 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; +inline Callback1> makeCallback1(const Functor &functor) { + typedef get_argument FirstArgument; return Callback1( ConstMemberCaller1( functor ) ); } diff --git a/libs/generic/functional.h b/libs/generic/functional.h index 940d4e7f..7d76a8b0 100644 --- a/libs/generic/functional.h +++ b/libs/generic/functional.h @@ -1,289 +1,202 @@ - #if !defined( INCLUDED_FUNCTIONAL_H ) #define INCLUDED_FUNCTIONAL_H -template -class Member -{ -public: -typedef Object& first_argument_type; -typedef R result_type; -static result_type call( first_argument_type object ){ - return ( object.*member )(); -} -}; +#include -template -class ConstMember -{ -public: -typedef const Object& first_argument_type; -typedef R result_type; -static result_type call( first_argument_type object ){ - return ( object.*member )(); -} -}; +namespace detail { + template + struct Fn; -template -class Member1 -{ -public: -typedef Object& first_argument_type; -typedef A1 second_argument_type; -typedef R result_type; -static result_type call( first_argument_type object, second_argument_type a1 ){ - return ( object.*member )( a1 ); -} -}; + template + struct Fn { + using result_type = R; -template -class ConstMember1 -{ -public: -typedef const Object& first_argument_type; -typedef A1 second_argument_type; -typedef R result_type; -static result_type call( first_argument_type object, second_argument_type a1 ){ - return ( object.*member )( a1 ); + template + using get = typename std::tuple_element>::type; + }; } -}; -template -class Member2 -{ -public: -typedef Object& first_argument_type; -typedef A2 second_argument_type; -typedef A3 third_argument_type; -typedef R result_type; -static result_type call( first_argument_type object, second_argument_type a2, third_argument_type a3 ){ - return ( object.*member )( a2, a3 ); -} -}; +template +using get_result_type = typename detail::Fn::result_type; -template -class ConstMember2 -{ -public: -typedef const Object& first_argument_type; -typedef A2 second_argument_type; -typedef A3 third_argument_type; -typedef R result_type; -static result_type call( first_argument_type object, second_argument_type a2, third_argument_type a3 ){ - return ( object.*member )( a2, a3 ); -} -}; +template +using get_argument = typename detail::Fn::template get; -template -class Member3 -{ -public: -typedef Object& first_argument_type; -typedef A2 second_argument_type; -typedef A3 third_argument_type; -typedef A4 fourth_argument_type; -typedef R result_type; -static result_type call( first_argument_type object, second_argument_type a2, third_argument_type a3, fourth_argument_type a4 ){ - return ( object.*member )( a2, a3, a4 ); -} -}; +template +class MemberN; -template -class ConstMember3 -{ +template +class MemberN { public: -typedef const Object& first_argument_type; -typedef A2 second_argument_type; -typedef A3 third_argument_type; -typedef A4 fourth_argument_type; -typedef R result_type; -static result_type call( first_argument_type object, second_argument_type a2, third_argument_type a3, fourth_argument_type a4 ){ - return ( object.*member )( a2, a3, a4 ); -} -}; + template + class instance { + public: + using func = R(Object &, Ts...); -template -class Function0 -{ -public: -typedef R result_type; -static result_type call(){ - return (func)( ); -} + static R call(Object &object, Ts... args) { + return (object.*f)(args...); + } + }; }; -template -class Function1 -{ -public: -typedef A1 first_argument_type; -typedef R result_type; -static result_type call( first_argument_type a1 ){ - return (func)( a1 ); -} -}; +template +class ConstMemberN; -template -class Function2 -{ +template +class ConstMemberN { public: -typedef A1 first_argument_type; -typedef A2 second_argument_type; -typedef R result_type; -static result_type call( first_argument_type a1, second_argument_type a2 ){ - return (func)( a1, a2 ); -} -}; + template + class instance { + public: + using func = R(const Object &, Ts...); -template -class Function3 -{ -public: -typedef A1 first_argument_type; -typedef A2 second_argument_type; -typedef A3 third_argument_type; -typedef R result_type; -static result_type call( first_argument_type a1, second_argument_type a2, third_argument_type a3 ){ - return (func)( a1, a2, a3 ); -} + static R call(const Object &object, Ts... args) { + return (object.*f)(args...); + } + }; }; -template -class Function4 -{ -public: -typedef A1 first_argument_type; -typedef A2 second_argument_type; -typedef A3 third_argument_type; -typedef A4 fourth_argument_type; -typedef R result_type; -static result_type call( first_argument_type a1, second_argument_type a2, third_argument_type a3, fourth_argument_type a4 ){ - return (func)( a1, a2, a3, a4 ); -} -}; +template +class FunctionN; -template -class Caller0To1 -{ +template +class FunctionN { public: -typedef FirstArgument first_argument_type; -typedef typename Caller::result_type result_type; -static result_type call( first_argument_type ){ - return Caller::call(); -} -}; + template + class instance { + public: + using func = R(Ts...); -template -class Caller1To2 -{ -public: -typedef FirstArgument first_argument_type; -typedef typename Caller::first_argument_type second_argument_type; -typedef typename Caller::result_type result_type; -static result_type call( first_argument_type, second_argument_type a2 ){ - return Caller::call( a2 ); -} + static R call(Ts... args) { + return (f)(args...); + } + }; }; -template -class Caller2To3 -{ -public: -typedef FirstArgument first_argument_type; -typedef typename Caller::first_argument_type second_argument_type; -typedef typename Caller::second_argument_type third_argument_type; -typedef typename Caller::result_type result_type; -static result_type call( first_argument_type, second_argument_type a2, third_argument_type a3 ){ - return Caller::call( a2, a3 ); -} -}; +template +class CallerShiftFirst; -template -class Caller3To4 -{ +template +class CallerShiftFirst { public: -typedef FirstArgument first_argument_type; -typedef typename Caller::first_argument_type second_argument_type; -typedef typename Caller::second_argument_type third_argument_type; -typedef typename Caller::third_argument_type fourth_argument_type; -typedef typename Caller::result_type result_type; -static result_type call( first_argument_type, second_argument_type a2, third_argument_type a3, fourth_argument_type a4 ){ - return Caller::call( a2, a3, a4 ); -} -}; + using func = R(FirstArgument, Ts...); -template -class FunctorInvoke -{ -public: -typedef typename Functor::result_type result_type; -inline result_type operator()( Functor functor ){ - return functor(); -} + static R call(FirstArgument, Ts... args) { + return Caller::call(args...); + } }; -template -class Functor1Invoke -{ -typename Functor::first_argument_type a1; -public: -typedef typename Functor::first_argument_type first_argument_type; -typedef typename Functor::result_type result_type; -Functor1Invoke( first_argument_type a1 ) : a1( a1 ){ -} -inline result_type operator()( Functor functor ){ - return functor( a1 ); -} -}; +template +class FunctorNInvoke; -template -class Functor2Invoke -{ -typename Functor::first_argument_type a1; -typename Functor::second_argument_type a2; -public: -typedef typename Functor::first_argument_type first_argument_type; -typedef typename Functor::second_argument_type second_argument_type; -typedef typename Functor::result_type result_type; -Functor2Invoke( first_argument_type a1, second_argument_type a2 ) - : a1( a1 ), a2( a2 ){ -} -inline result_type operator()( Functor functor ){ - return functor( a1, a2 ); -} -}; +namespace detail { + template + struct seq { + }; -template -class Functor3Invoke -{ -typename Functor::first_argument_type a1; -typename Functor::second_argument_type a2; -typename Functor::third_argument_type a3; -public: -typedef typename Functor::first_argument_type first_argument_type; -typedef typename Functor::second_argument_type second_argument_type; -typedef typename Functor::third_argument_type third_argument_type; -typedef typename Functor::result_type result_type; -Functor3Invoke( first_argument_type a1, second_argument_type a2, third_argument_type a3 ) - : a1( a1 ), a2( a2 ), a3( a3 ){ -} -inline result_type operator()( Functor functor ){ - return functor( a1, a2, a3 ); + template + struct gens : gens { + }; + + template + struct gens<0, S...> { + using type = seq; + }; + + template + using seq_new = typename gens::type; } -}; -template -class TypeEqual -{ -public: -typedef False type; -}; -template -class TypeEqual -{ +template +class FunctorNInvoke { + std::tuple args; + + template + struct caller; + + template + struct caller> { + static inline R call(FunctorNInvoke *self, Functor functor) { + (void) self; + return functor(std::get(self->args)...); + } + }; + public: -typedef True type; + FunctorNInvoke(Ts... args) : args(args...) { + } + + inline R operator()(Functor functor) { + return caller>::call(this, functor); + } }; +template +using FunctorInvoke = FunctorNInvoke; + +template +using Member = typename MemberN::template instance; + +template +using ConstMember = typename ConstMemberN::template instance; + +template +using Member1 = typename MemberN::template instance; + +template +using ConstMember1 = typename ConstMemberN::template instance; + +template +using Member2 = typename MemberN::template instance; + +template +using ConstMember2 = typename ConstMemberN::template instance; + +template +using Member3 = typename MemberN::template instance; + +template +using ConstMember3 = typename ConstMemberN::template instance; + +template +using Function0 = typename FunctionN::template instance; + +template +using Function1 = typename FunctionN::template instance; + +template +using Function2 = typename FunctionN::template instance; + +template +using Function3 = typename FunctionN::template instance; + +template +using Function4 = typename FunctionN::template instance; + +template +using Caller0To1 = CallerShiftFirst( + FirstArgument +)>; + +template +using Caller1To2 = CallerShiftFirst( + FirstArgument, + get_argument +)>; + +template +using Caller2To3 = CallerShiftFirst( + FirstArgument, + get_argument, + get_argument +)>; + +template +using Caller3To4 = CallerShiftFirst( + FirstArgument, + get_argument, + get_argument, + get_argument +)>; #endif diff --git a/libs/signal/isignal.h b/libs/signal/isignal.h index b6342190..c447d71b 100644 --- a/libs/signal/isignal.h +++ b/libs/signal/isignal.h @@ -22,72 +22,63 @@ bool operator!=( SignalHandlerResult other ) const { const SignalHandlerResult SIGNAL_CONTINUE_EMISSION = SignalHandlerResult( false ); const SignalHandlerResult SIGNAL_STOP_EMISSION = SignalHandlerResult( true ); -template -class SignalHandlerCaller1 -{ +template +class SignalHandlerCallerN; + +template +class SignalHandlerCallerN { public: -typedef typename Caller::first_argument_type first_argument_type; -typedef SignalHandlerResult result_type; -static result_type call( first_argument_type a1 ){ - Caller::call( a1 ); - return SIGNAL_CONTINUE_EMISSION; -} + using func = SignalHandlerResult(Ts...); + + static SignalHandlerResult call(Ts... args) { + Caller::call(args...); + return SIGNAL_CONTINUE_EMISSION; + } }; +template +using SignalHandlerCaller = SignalHandlerCallerN; + +template +using SignalHandlerCaller1 = SignalHandlerCaller; + +template +using SignalHandlerCaller2 = SignalHandlerCaller; + template -class SignalHandlerCaller2 -{ -public: -typedef typename Caller::first_argument_type first_argument_type; -typedef typename Caller::second_argument_type second_argument_type; -typedef SignalHandlerResult result_type; -static result_type call( first_argument_type a1, second_argument_type a2 ){ - Caller::call( a1, a2 ); - return SIGNAL_CONTINUE_EMISSION; -} -}; +using SignalHandlerCaller3 = SignalHandlerCaller; template -class SignalHandlerCaller3 -{ +using SignalHandlerCaller4 = SignalHandlerCaller; + +template +class TypeEqual { public: -typedef typename Caller::first_argument_type first_argument_type; -typedef typename Caller::second_argument_type second_argument_type; -typedef typename Caller::third_argument_type third_argument_type; -typedef SignalHandlerResult result_type; -static result_type call( first_argument_type a1, second_argument_type a2, third_argument_type a3 ){ - Caller::call( a1, a2, a3 ); - return SIGNAL_CONTINUE_EMISSION; -} + using type = False; }; -template -class SignalHandlerCaller4 -{ +template +class TypeEqual { public: -typedef typename Caller::first_argument_type first_argument_type; -typedef typename Caller::second_argument_type second_argument_type; -typedef typename Caller::third_argument_type third_argument_type; -typedef typename Caller::fourth_argument_type fourth_argument_type; -typedef SignalHandlerResult result_type; -static result_type call( first_argument_type a1, second_argument_type a2, third_argument_type a3, fourth_argument_type a4 ){ - Caller::call( a1, a2, a3, a4 ); - return SIGNAL_CONTINUE_EMISSION; -} + using type = True; }; -class SignalHandler : public Callback0 -{ +template class Wrapper> +class SignalHandlerN : public CB { public: -template -SignalHandler( const BindFirstOpaque& caller ) - : Callback0( BindFirstOpaque, - typename Caller::result_type - >::type>( caller.getBound() ) ){ -} + template + SignalHandlerN(const BindFirstOpaque &caller) + : CB(BindFirstOpaque, + get_result_type + >::type>(caller.getBound())) { + } +}; + +class SignalHandler : public SignalHandlerN, SignalHandlerCaller1> { + using SignalHandlerN, SignalHandlerCaller1>::SignalHandlerN; }; template @@ -95,111 +86,81 @@ inline SignalHandler makeSignalHandler( const BindFirstOpaque& caller ){ return SignalHandler( caller ); } template -inline SignalHandler makeSignalHandler( const Caller& caller, typename Caller::first_argument_type callee ){ +inline SignalHandler makeSignalHandler(const Caller &caller, get_argument callee) { return SignalHandler( BindFirstOpaque( callee ) ); } - template -class SignalHandler1 : public Callback1 -{ -public: -template -SignalHandler1( const BindFirstOpaque1& caller ) - : Callback1( BindFirstOpaque1, - typename Caller::result_type - >::type>( caller.getBound() ) ){ -} +class SignalHandler1 : public SignalHandlerN, SignalHandlerCaller2> { + using SignalHandlerN, SignalHandlerCaller2>::SignalHandlerN; }; template -inline SignalHandler1 makeSignalHandler1( const BindFirstOpaque1& caller ){ - return SignalHandler1( caller ); +inline SignalHandler1> makeSignalHandler1(const BindFirstOpaque &caller) { + return SignalHandler1>(caller); } template -inline SignalHandler1 makeSignalHandler1( const Caller& caller, typename Caller::first_argument_type callee ){ - return SignalHandler1( BindFirstOpaque1( callee ) ); +inline SignalHandler1> +makeSignalHandler1(const Caller &caller, get_argument callee) { + return SignalHandler1>(BindFirstOpaque(callee)); } - template -class SignalHandler2 : public Callback2 -{ -public: -template -SignalHandler2( const BindFirstOpaque2& caller ) - : Callback2( BindFirstOpaque2, - typename Caller::result_type - >::type>( caller.getBound() ) ){ -} +class SignalHandler2 + : public SignalHandlerN, SignalHandlerCaller3> { + using SignalHandlerN, SignalHandlerCaller3>::SignalHandlerN; }; template inline SignalHandler2< - typename Caller::second_argument_type, - typename Caller::third_argument_type - > makeSignalHandler2( const BindFirstOpaque2& caller ){ + get_argument, + get_argument +> makeSignalHandler2(const BindFirstOpaque &caller) { return SignalHandler2< - typename Caller::second_argument_type, - typename Caller::third_argument_type + get_argument, + get_argument >( caller ); } template inline SignalHandler2< - typename Caller::second_argument_type, - typename Caller::third_argument_type - > makeSignalHandler2( const Caller& caller, typename Caller::first_argument_type callee ){ + get_argument, + get_argument +> makeSignalHandler2(const Caller &caller, get_argument callee) { return SignalHandler2< - typename Caller::second_argument_type, - typename Caller::third_argument_type - >( BindFirstOpaque2( callee ) ); + get_argument, + get_argument + >(BindFirstOpaque(callee)); } - template -class SignalHandler3 : public Callback3 -{ -public: -template -SignalHandler3( const BindFirstOpaque3& caller ) - : Callback3( BindFirstOpaque3, - typename Caller::result_type - >::type>( caller.getBound() ) ){ -} +class SignalHandler3 + : public SignalHandlerN, SignalHandlerCaller4> { + using SignalHandlerN, SignalHandlerCaller4>::SignalHandlerN; }; template inline SignalHandler3< - typename Caller::second_argument_type, - typename Caller::third_argument_type, - typename Caller::fourth_argument_type - > makeSignalHandler3( const BindFirstOpaque3& caller ){ + get_argument, + get_argument, + get_argument +> makeSignalHandler3(const BindFirstOpaque &caller) { return SignalHandler3< - typename Caller::second_argument_type, - typename Caller::third_argument_type, - typename Caller::fourth_argument_type + get_argument, + get_argument, + get_argument >( caller ); } template inline SignalHandler3< - typename Caller::second_argument_type, - typename Caller::third_argument_type, - typename Caller::fourth_argument_type - > makeSignalHandler3( const Caller& caller, typename Caller::first_argument_type callee ){ + get_argument, + get_argument, + get_argument +> makeSignalHandler3(const Caller &caller, get_argument callee) { return SignalHandler3< - typename Caller::second_argument_type, - typename Caller::third_argument_type, - typename Caller::fourth_argument_type - >( BindFirstOpaque3( callee ) ); + get_argument, + get_argument, + get_argument + >(BindFirstOpaque(callee)); } #endif diff --git a/libs/signal/signal.h b/libs/signal/signal.h index f435f027..3d4c0397 100644 --- a/libs/signal/signal.h +++ b/libs/signal/signal.h @@ -315,7 +315,7 @@ class Signal1 : public SignalBase< SignalHandler1 > typedef SignalBase< SignalHandler1 > Base; public: void operator()( FirstArgument a1 ) const { - invokeSignalHandlers( Base::begin(), Base::end(), Functor1Invoke( a1 ) ); + invokeSignalHandlers( Base::begin(), Base::end(), FunctorInvoke( a1 ) ); } }; @@ -325,7 +325,7 @@ class Signal2 : public SignalBase< SignalHandler2 typedef SignalBase< SignalHandler2 > Base; public: void operator()( FirstArgument a1, SecondArgument a2 ) const { - invokeSignalHandlers( Base::begin(), Base::end(), Functor2Invoke( a1, a2 ) ); + invokeSignalHandlers( Base::begin(), Base::end(), FunctorInvoke( a1, a2 ) ); } }; @@ -335,7 +335,7 @@ class Signal3 : public SignalBase< SignalHandler3 > Base; public: void operator()( FirstArgument a1, SecondArgument a2, ThirdArgument a3 ) const { - invokeSignalHandlers( Base::begin(), Base::end(), Functor3Invoke( a1, a2, a3 ) ); + invokeSignalHandlers( Base::begin(), Base::end(), FunctorInvoke( a1, a2, a3 ) ); } }; diff --git a/libs/stringio.h b/libs/stringio.h index ac680259..ef808599 100644 --- a/libs/stringio.h +++ b/libs/stringio.h @@ -397,12 +397,12 @@ typedef ConstReferenceCaller1 BoolToS template inline StringImportCallback makeBoolStringImportCallback( const Caller& caller ){ - return StringImportCallback( caller.getEnvironment(), ImportConvert1::thunk ); + return StringImportCallback( caller.getEnvironment(), ImportConvert1, Caller, BoolFromString>::thunk ); } template inline StringExportCallback makeBoolStringExportCallback( const Caller& caller ){ - return StringExportCallback( caller.getEnvironment(), ImportConvert1::thunk ); + return StringExportCallback( caller.getEnvironment(), ImportConvert1, Caller, BoolToString>::thunk ); } @@ -427,12 +427,12 @@ typedef ConstReferenceCaller1 IntToStri template inline StringImportCallback makeIntStringImportCallback( const Caller& caller ){ - return StringImportCallback( caller.getEnvironment(), ImportConvert1::thunk ); + return StringImportCallback( caller.getEnvironment(), ImportConvert1, Caller, IntFromString>::thunk ); } template inline StringExportCallback makeIntStringExportCallback( const Caller& caller ){ - return StringExportCallback( caller.getEnvironment(), ImportConvert1::thunk ); + return StringExportCallback( caller.getEnvironment(), ImportConvert1, Caller, IntToString>::thunk ); } @@ -458,12 +458,12 @@ typedef ConstReferenceCaller1 template inline StringImportCallback makeSizeStringImportCallback( const Caller& caller ){ - return StringImportCallback( caller.getEnvironment(), ImportConvert1::thunk ); + return StringImportCallback( caller.getEnvironment(), ImportConvert1, Caller, SizeFromString>::thunk ); } template inline StringExportCallback makeSizeStringExportCallback( const Caller& caller ){ - return StringExportCallback( caller.getEnvironment(), ImportConvert1::thunk ); + return StringExportCallback( caller.getEnvironment(), ImportConvert1, Caller, SizeToString>::thunk ); } #endif diff --git a/radiant/csg.cpp b/radiant/csg.cpp index 5676401e..2538359f 100644 --- a/radiant/csg.cpp +++ b/radiant/csg.cpp @@ -166,11 +166,9 @@ class Dereference { const Functor& functor; public: -typedef typename RemoveReference::type* first_argument_type; -typedef typename Functor::result_type result_type; Dereference( const Functor& functor ) : functor( functor ){ } -result_type operator()( first_argument_type firstArgument ) const { +get_result_type operator()( typename RemoveReference>::type *firstArgument ) const { return functor( *firstArgument ); } }; @@ -192,15 +190,13 @@ Face* Brush_findIf( const Brush& brush, const Predicate& predicate ){ template class BindArguments1 { -typedef typename Caller::second_argument_type FirstBound; +typedef get_argument FirstBound; FirstBound firstBound; public: -typedef typename Caller::result_type result_type; -typedef typename Caller::first_argument_type first_argument_type; BindArguments1( FirstBound firstBound ) : firstBound( firstBound ){ } -result_type operator()( first_argument_type firstArgument ) const { +get_result_type operator()( get_argument firstArgument ) const { return Caller::call( firstArgument, firstBound ); } }; @@ -208,17 +204,15 @@ result_type operator()( first_argument_type firstArgument ) const { template class BindArguments2 { -typedef typename Caller::second_argument_type FirstBound; -typedef typename Caller::third_argument_type SecondBound; +typedef get_argument FirstBound; +typedef get_argument SecondBound; FirstBound firstBound; SecondBound secondBound; public: -typedef typename Caller::result_type result_type; -typedef typename Caller::first_argument_type first_argument_type; BindArguments2( FirstBound firstBound, SecondBound secondBound ) : firstBound( firstBound ), secondBound( secondBound ){ } -result_type operator()( first_argument_type firstArgument ) const { +get_result_type operator()( get_argument firstArgument ) const { return Caller::call( firstArgument, firstBound, secondBound ); } }; diff --git a/radiant/dialog.h b/radiant/dialog.h index b862daa0..13ff605c 100644 --- a/radiant/dialog.h +++ b/radiant/dialog.h @@ -25,13 +25,11 @@ #include #include +#include "generic/callback.h" #include "gtkutil/dialog.h" #include "generic/callback.h" #include "string/string.h" -template -class ReferenceCaller1; - inline void BoolImport( bool& self, bool value ){ self = value; } diff --git a/radiant/renderstate.cpp b/radiant/renderstate.cpp index 0c274918..b906f2cd 100644 --- a/radiant/renderstate.cpp +++ b/radiant/renderstate.cpp @@ -908,7 +908,7 @@ OpenGLStateBucket& m_bucket; const OpenGLRenderable& m_renderable; const Matrix4& m_modelview; public: -typedef const RendererLight& first_argument_type; +using func = void(const RendererLight&); OpenGLStateBucketAdd( OpenGLStateBucket& bucket, const OpenGLRenderable& renderable, const Matrix4& modelview ) : m_bucket( bucket ), m_renderable( renderable ), m_modelview( modelview ){ @@ -922,7 +922,7 @@ class CountLights { std::size_t m_count; public: -typedef RendererLight& first_argument_type; +using func = void(RendererLight&); CountLights() : m_count( 0 ){ } diff --git a/radiant/selection.cpp b/radiant/selection.cpp index e04fd91c..830937e7 100644 --- a/radiant/selection.cpp +++ b/radiant/selection.cpp @@ -1982,7 +1982,7 @@ void TestQuadStrip( const VertexPointer& vertices, const IndexPointer& indices, class SelectionCounter { public: -typedef const Selectable& first_argument_type; +using func = void(const Selectable &); SelectionCounter( const SelectionChangeCallback& onchanged ) : m_count( 0 ), m_onchanged( onchanged ){ diff --git a/radiant/texwindow.cpp b/radiant/texwindow.cpp index 8e2ed430..639dd498 100644 --- a/radiant/texwindow.cpp +++ b/radiant/texwindow.cpp @@ -756,7 +756,7 @@ class TextureCategoryLoadShader const char* m_directory; std::size_t& m_count; public: -typedef const char* first_argument_type; +using func = void(const char *); TextureCategoryLoadShader( const char* directory, std::size_t& count ) : m_directory( directory ), m_count( count ){