C++0x brain damage
Автор: nsf
Мне правда жаль будущее поколение молодых мозго***в. Решил я как-то значицо написать супер крутой коллбэк в стиле С++0x, да не сдавался до конца..
Автор: nsf
Мне правда жаль будущее поколение молодых мозго***в. Решил я как-то значицо написать супер крутой коллбэк в стиле С++0x, да не сдавался до конца..
#include <stdio.h> #include <functional> //------------------------------------------------------------------------- // Our main callback class, can be binded to function or member function // of a particular class easily(?) //------------------------------------------------------------------------- template <typename Ret, typename ...Args> struct funcptr_def { typedef Ret (*type)( Args...); }; template <typename Signature> struct callback; template <typename Ret, typename ...Args> struct callback<Ret( Args...)> { typedef typename funcptr_def<Ret, Args..., void*>::type function_ptr_type; function_ptr_type fptr; void *data; void bind( function_ptr_type fptr, void *data = 0) { this->fptr = fptr; this->data = data; } Ret call( Args ...args) { return ( *fptr)( std::forward<Args>( args)..., data); } }; //------------------------------------------------------------------------- // Helper binder //------------------------------------------------------------------------- template <int ...> struct int_tuple {}; template <int I, typename IntTuple, typename ...Types> struct make_indices_impl; template <int I, int ...Indices, typename T, typename ...Types> struct make_indices_impl<I, int_tuple<Indices...>, T, Types...> { typedef typename make_indices_impl<I+1, int_tuple<Indices..., I>, Types...>::type type; }; template <int I, int ...Indices> struct make_indices_impl<I, int_tuple<Indices...>> { typedef int_tuple<Indices...> type; }; template <typename ...Types> struct make_indices : make_indices_impl<0, int_tuple<>, Types...> {}; //------------------------------------------------------------------------- template <typename T> void *get_void_ptr( T &&arg) { return arg; } template <typename T, typename ...Args> void *get_void_ptr( T &&arg, Args &&...args) { return get_void_ptr( std::forward<Args>( args)...); } //------------------------------------------------------------------------- template <typename Ret> struct callback_helper_impl { template <typename T, typename MemberFunctionPtr, typename ...Args, int ...Indices> static Ret callback_run( T *object, MemberFunctionPtr m, const std::tuple<Args&...>& args, int_tuple<Indices...>) { return ( object->*m)( std::get<Indices>( args)...); } }; template <typename Signature, typename MemberSignature, MemberSignature FunctionPtr> struct callback_helper; template <typename Ret, typename ...Args, typename T, typename ...MemArgs, Ret( T::*MemberFunction)( MemArgs...)> struct callback_helper<Ret( Args...), decltype( MemberFunction), MemberFunction> { typedef typename make_indices<MemArgs...>::type indices; static Ret function( Args ...args) { T *object = ( T*)get_void_ptr( args...); return callback_helper_impl<Ret>::callback_run( object, MemberFunction, std::tie( args...), indices( )); } }; // for convenience (orly?!!?111 omgwtfbbq) #define WRAP_METHOD( f) decltype( f), f //------------------------------------------------------------------------- // Example class //------------------------------------------------------------------------- struct dog_t { void bark( int a, int b) { printf( "bark! %d %d\n", a, b); } }; //------------------------------------------------------------------------- // Example function //------------------------------------------------------------------------- void say_hello( int a, int b, void *notused) { printf( "Hello! %d %d\n", a, b); } int main( int argc, char **argv) { dog_t dog; callback<void ( int, int)> cb; int i = 1; // function cb.bind( say_hello); cb.call( i, 2); // member function cb.bind( callback_helper<void ( int, int, void*), WRAP_METHOD( &dog_t::bark)>::function, &dog); cb.call( i, 2); return 0; }
5 июня 2010