I was on #osdev earlier today when I was talking to someone... I can't remember. Anyway, we talked about C++ delegate support.
This way a single class that could bind to different function pointers and/or member function pointers (ala C# delegate). And perhaps an event class could be built on top allowing for intelligent C# events in C++ for user-land GUI programming (maybe?). Regardless I want - at least - fast delegates to be used as callbacks device drivers or other such areas of the OS.
There is a boost::function somewhere (which uses virtual memory mapping) but we're osdevers and we need something with as close to zero-overhead (tm) as possible.
DISCLAIMER: This code is a WIP and suggestions are more than welcome (in fact please give me suggestions to improve it )
Code: Select all
template <typename TResult>
class Delegate
{
public:
// [TODO] Some nice constructor so we can go Delegate(func) as an argument to a function
// I suppose we could make the Bind functions static... but it's not very clean
template <TResult (*TMethod)()>
void Bind()
{
m_Object = 0;
m_Invoker = &Invoker<TMethod>;
}
template <typename TObject, TResult (TObject::*TMethod)()>
void Bind(TObject *object)
{
m_Object = object;
m_Invoker = &Invoker<TObject, TMethod>;
}
TResult Invoke()
{
return m_Invoker(m_Object);
}
private:
void *m_Object;
TResult (*m_Invoker)(void*);
template <TResult (*TMethod)()>
static TResult Invoker(void*)
{
return (TMethod)();
}
template <typename TObject, TResult (TObject::*TMethod)()>
static TResult Invoker(void *object)
{
TObject *p = static_cast<TObject*>(object);
return (p->*TMethod)();
}
};
Code: Select all
class Foo
{
public:
void Bar() { printf('B'); }
};
void Foo_Bar() { printf('A'); }
void Do()
{
Delegate temp;
temp.Bind<&Foo_Bar>();
temp.Invoke(); // Prints 'A' to the screen
Foo foo; // need an instance of the class
temp.Bind<Foo, &Foo::Bar>(&foo);
temp.Invoke(); // Prints 'B' to the screen
}
The code works as it is and compiles the latest version of G++. I know it only has a return type and no parameters but that's something I'm waiting to put in until I figure out an elegant constructor for these delegates.
As it is right now, I can' t figure out how to pass these efficiently as a function argument. Any suggestions?
[EDIT] Oops Typo on the Invoke function. Should be good now.