|
Boost : |
From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-05-08 08:18:55
On Monday 07 May 2001 08:45 pm, you wrote:
> 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==.
<Doug looks at the mess that is boost::function, shakes his head and grumbles
about virtual function overhead>
> 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
Here's what I've been considering:
function is:
- Assignment from any target function object
- Clearing out the value (assignment from nil)
- Execution of that target function object
- A check to see if it is empty
callback extends function:
- Equality test
signal is a distinct function-like concept:
- support for multiple slots
- notification to slot when it dies
- method of combining multiple return values
slot extends function:
- knowledge of which signals it points to
- notification to those signals when it dies
- picks up notification of signal death
Doug
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk