Boost logo

Boost :

From: Alexander Nasonov (alnsn-mycop_at_[hidden])
Date: 2003-10-10 03:30:51


Current call/call_ex/no_call solution isn't satisfactory to me especially
for multiple dispatch. I'm thinking about new schema based on nested
*definition* class template.
Often it's enough to list several arguments combinations plus catch-all
function. It could be enough to have only one *definition* in this case.
One call operator for every individual combination plus catch-all call
operator:

struct Intersection
  : function<Intersection, void (anyT const&, anyT const&)>
{
  struct definition
  {
    void operator(Intersection const& self,
                  Triangle const&, Circle const&) const;

    void operator(Intersection const& self,
                  Triangle const&, Triangle const&) const;

    // catch-all
    template<class L>
    void operator(Intersection const& self,
                  any<L> const&, any<L> const&) const;

    // list them all
    typedef mpl::list<
      void (Triangle const&, Circle const&),
      void (Triangle const&, Triangle const&),
      void (anyT const&, anyT const&)
> implements;
  };
};

This solution is good enough for many hierarchies where multiple dispatch is
required but it's not good enough for dynamic_any in general. For example,
the schema above won't work in case of *less* operation.
My proposal is to define *definition* as a class template: definition<T>
should stand for the definition with T as a base.
For example, *less" can be implemented as follow:

struct less
  : function<less, bool (anyT const&, anyT const&)>
{
  template<class T>
  struct definition
  {
    typedef mpl::list<bool (T const&, T const&)> implements;

    bool operator(less const&, T const& a, T const& b) const
    {
      return std::less<T>()(a, b);
    }
  };

  // in case definition above doesn't implement
  // comparison for a given argument types:
  template<>
  struct definition<anyT>
  {
    typedef mpl::list<bool (anyT const&, anyT const&)> implements;

    template<class L>
    bool operator(less const&, any<L> const& a, any<L> const& b) const
    {
       return a.type().before(b.type());
    }
  };
};

I don't have enough time to think further about design and implementation. I
don't know neither how to distinguish between exact type match and a match
with derived-to-base conversion (exact matching is assumed in example of
less) nor how to implement lookup algorithm for selecting a best match. I
feel it's possible, though.

What other people think?

-- 
Alexander Nasonov
Remove minus and all between minus and at from my e-mail for timely response

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk