Boost logo

Boost :

From: williamkempf_at_[hidden]
Date: 2001-05-08 09:15:06


--- In boost_at_y..., Douglas Gregor <gregod_at_c...> wrote:
> 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