Boost logo

Boost :

From: Alexander Nasonov (alnsn_at_[hidden])
Date: 2002-10-18 03:52:59


Douglas Gregor wrote:
> boost::call seems a little unwieldy, and I'm wondering what we can do
> about that. It would be nice if, along with the prefabricated operation
> mixins, we could provide the actual operator and function overloads for
> appropriately-constructed dynamic_any's. For instance, say we have
> dynamic_any_less from the example. Then we'd really like this to work:
>
> dynamic_any<mpl::list<dynamic_any_less> > a1, a2;
> if (a1 < a2) {
> // ...
> }

Now there is only one way to do so. This one:

  dynamic_any<mpl::list<dynamic_any_less> > a1, a2;
  if(boost::call(dynamic_any_less(), a1, a2)) {
    // ...
  }

boost::call throws bad_call if a1 and a2 hold values of different types or
are empty. So, attempt to compare two empty dynamic_any values should fail:

  dynamic_any<mpl::list<dynamic_any_less> > a1, a2;
  if (a1 < a2) { // throws bad_call!
    // ...
  }

Is this what a user expected from less comparison? I'm not sure.

>
> But, we don't want something like this to work:
>
> dynamic_any<mpl::list<something_that_isn't_less> > a3, a4;
> if (a3 < a4) { // should be an error
> // ...
> }
>
> For binary functions, at least, something like this wouldn't be very hard
> to implement. A general scheme is:
>
> template<typename OperationList>
> bool operator<(const dynamic_any<OperationList>& x,
> const dynamic_any<
> typename select_type<
> (element_in_list<dynamic_any_less,
> OperationList>::value),
> OperationList,
> void>::type>& y);
>
> i.e., given objects a1 and a2 of type dynamic_any<T>, operator<(a1, a2)
> only unifies if T (the list of supported operations) contains
> dynamic_any_less. The unary function analogue to this would probably need
> to use the has_member idiom.
>

I can go further because boost::call can be used for two dynamic_any values
with different OperationList:

  template<typename OperationList1, typename OperationList2>
  bool operator<(
    const dynamic_any<OperationList1>& x,
    const dynamic_any<OperationList2>& y)
{
  BOOST_STATIC_ASSERT(
    (element_in_list<dynamic_any_less, OperationList1>::value));
  BOOST_STATIC_ASSERT(
    (element_in_list<dynamic_any_less, OperationList2>::value));
  return call(dynamic_any_less(), x, y);
}

BOOST_STATIC_ASSERT's are presented here only to demonstrate the idea. This
kind of check is already implemented inside boost::call.

Best regards,
Alexander Nasonov
mailbox: alnsn
server: mail.ru


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