#include <iostream>
#include <vector>
#include <tuple>
const static auto null = nullptr;
template<typename TFuncSignature>
class Callback;
template<typename R, typename ...A>
class Callback<R (A...)> {
public:
const static size_t Arity = sizeof...(A);
typedef R (*TFunc)(void*, A...);
Callback() : obj(0), func(0) {}
Callback(void* o, TFunc f) : obj(o), func(f) {}
R operator()(A... a) const {
return (*func)(obj, a);
}
typedef void* Callback::*SafeBoolType;
operator SafeBoolType () const {
return func != 0? &Callback::obj : 0;
}
bool operator! () const {
return func == 0;
}
bool operator== ( const Callback<R (A...)>& right ) const {
return obj == right.obj && func == right.func;
}
bool operator!= ( const Callback<R (A...)>& right ) const {
return obj != right.obj || func != right.func;
}
private:
void* obj;
TFunc func;
};
namespace IntStatic {
void VoidTest ( ) { std::cout << "INTO THE VOID" << std::endl; }
void IntTest ( int num) { std::cout << "Got myself a " << num << " !" << std::endl; }
void IntTest2 ( int num) { std::cout << "Now _I_ Got myself a " << num << " !" << std::endl; }
}
struct Int {
void Test ( int num) { std::cout << num << " on the inside of a class... ?" << std::endl; }
void Test2 ( int num) { std::cout << num << " on the inside of a struct, yo !" << std::endl; }
static void Test3 ( int snum) { std::cout << snum << " on the inside of a STATIC method?!" << std::endl; }
};
template<typename R, typename... A>
struct DeduceStaticCallbackTag {
/* SO THIS IS WHERE THE PROBLEM IS, FUCK YOU VARIADIC TEMPLATES */
// Not really fuck you, I need you. IT'S JUST A COMMENT YOU CAN'T TAKE ME SERIOUSLY
// *Ahem.* In either case, `A ...` is an invalid expansion, I.E. it's not allowed
// Is there anyway we can get a variadic function signature out and expanded?
// If not, then there's no way to do this. D:
template< R (* Func)( A ... ) >
static R Wrapper(void*, A... a) {
return (*Func)( a... );
}
/*template<R (*Func)( A... )>
inline static Callback<R (A...)> Bind( ) {
return Callback<R (A...)>( 0, &DeduceStaticCallbackTag::Wrapper<Func> );
}*/
};
// Save this for when we figure variadic templates out truly
/*template<typename R, typename... A>
DeduceStaticCallbackTag<R, A...> DeduceStaticCallback(R (*)(A...)) {
return DeduceStaticCallbackTag<R, A...>();
}*/
int main(int argc, char* argv[]) {
Callback<void(int)> m( 0, &DeduceStaticCallbackTag<void, int>::Wrapper<&IntStatic::IntTest> );
//DeduceStaticCallback( &IntStatic::IntTest2 ).Bind<&IntStatic::IntTest2>( );
/*Event<int> intev;
Int i;
intev.Add<Int, &Int::Test>(i);
intev.Add<&IntStatic::IntTest>();
intev.Add<&IntStatic::IntTest2>();
//intev.Add( Int::Test3 );
intev(20);
intev.Remove<&IntStatic::IntTest>();
intev.Remove<&IntStatic::IntTest>();
intev.Remove<Int, &Int::Test>(i);
//intev.Remove( Int::Test3 );
//intev.Remove( i, &Int::Test );
intev(20);
*/
return 0;
}