|
Boost : |
From: Jesse Jones (jesjones_at_[hidden])
Date: 2001-05-07 19:45:39
I've been experimenting with adding support for comparisons to my
callback proposal from last year. The overall design is quite a bit
simpler than Gregor's code, but it has the same sort of problems if
you try to add operator==.
What I did was create two classes: boost::function which behaves more
or less like Gregor's class and boost::callback which is the same,
but adds operator==. The key difference between the two is that
callback passes true to the meta-function that generates the concrete
functor objects (I'd upload the code, but Yahoo groups is down):
template <typename RETURN_TYPE,
typename ARG1 = details::unused_arg,
typename ARG2 = details::unused_arg>
class callback {
public:
public:
template <typename FUNCTOR>
callback(FUNCTOR functor) :
mFunctor(new typename details::
generate_functor<FUNCTOR, RETURN_TYPE, ARG1, ARG2, true>::
RET(functor)) {}
private:
Functor* mFunctor;
};
The meta-function looks like this:
template <typename FUNCTOR,
typename RETURN_TYPE,
typename ARG1,
typename ARG2,
bool useCompare>
struct generate_functor {
enum {selector = is_used<ARG1>::RET +
is_used<ARG2>::RET +
3*useCompare};
typedef call_functor0<FUNCTOR, RETURN_TYPE,
DummyCompare<FUNCTOR> > f0;
typedef call_functor1<FUNCTOR, RETURN_TYPE, ARG1,
DummyCompare<FUNCTOR> > f1;
typedef call_functor2<FUNCTOR, RETURN_TYPE, ARG1, ARG2,
DummyCompare<FUNCTOR> > f2;
typedef call_functor0<FUNCTOR, RETURN_TYPE,
CompareFunctor<FUNCTOR> > f0c;
typedef call_functor1<FUNCTOR, RETURN_TYPE, ARG1,
CompareFunctor<FUNCTOR> > f1c;
typedef call_functor2<FUNCTOR, RETURN_TYPE, ARG1, ARG2,
CompareFunctor<FUNCTOR> > f2c;
typedef typename SWITCH<(selector),
CASE<0, f0,
CASE<1, f1,
CASE<2, f2,
CASE<3, f0c,
CASE<4, f1c,
CASE<5, f2c> > > > > > >::RET RET;
};
The functors used by callback and function have equal methods that
look like this:
template <typename FUNCTOR,
typename RETURN_TYPE,
typename COMPARE>
class call_functor0 : public base_call_functor0<RETURN_TYPE> {
public:
virtual bool equal(const base_call_functor& rhs) const
{
const call_functor0* temp = dynamic_cast<const call_functor0*>(&rhs);
return temp != nil && COMPARE::equal(mFunctor, temp->mFunctor);
}
private:
FUNCTOR mFunctor;
};
The comparisons are handled by the following structs:
template <typename FUNCTOR>
struct CompareFunctor {
static bool equal(const FUNCTOR& lhs, const FUNCTOR& rhs)
{return lhs == rhs;}
};
template <typename FUNCTOR>
struct DummyCompare {
static bool equal(const FUNCTOR&, const FUNCTOR&)
{assert(false); return false;}
};
This seems like a fairly good solution to me and I'm pretty sure
something like it could be made to work with Gregor's code...
-- Jesse
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk