Saturday, May 04, 2013

And here is the same thing using variadic template arguments, a new feature of C++11:



template class base_t
{
public:
virtual R operator()(Args... p) { return R(); }
};

template class stub_t : public base_t
{
T* _obj;
union
{
R (T::*_ptr)(Args...);
R (T::*_ptr_c)(Args...) const;
};

public:
stub_t(T* obj, R (T::*ptr)(Args...))
: _obj(obj), _ptr(ptr)
{
}
stub_t(T* obj, R (T::*ptr)(Args...) const)
: _obj(obj), _ptr_c(ptr)
{
}
R operator()(Args... p)
{
return (_obj->*_ptr)(p...);
}
};

template class signal_t
{
R(*_ptr)(Args...);
base_t* _stub;

public:
signal_t() : _ptr(nullptr), _stub(nullptr)
{
}
void connect(R(*ptr)(Args... args))
{
_ptr = ptr;
};

template void connect(T& obj, R(T::*ptr)(Args...))
{
_stub = new stub_t(&obj, ptr);
}
template void connect(T* obj, R(T::*ptr)(Args...) )
{
_stub = new stub_t(obj, ptr);
}
template void connect(T& obj, R(T::*ptr)(Args...) const)
{
_stub = new stub_t(&obj, ptr);
}
template void connect(T* obj, R(T::*ptr)(Args...) const)
{
_stub = new stub_t(obj, ptr);
}

R operator()(Args... p)
{
if(_ptr)
return _ptr(p...);
else if(_stub)
return (*_stub)(p...);
else
return R();
}
};


Saves a few hundred lines of code, as well as reducing the number of places bugs can crop up.

0 Comments:

Post a Comment

<< Home