Boost logo

Boost :

Subject: Re: [boost] review request: addition to type_traits library of has_operator_xxx
From: Jeffrey Lee Hellrung, Jr. (jhellrung_at_[hidden])
Date: 2010-11-29 13:52:20


On 11/29/2010 1:53 AM, Frédéric Bron wrote:
>> To take care of operators involving *only* builtin types, I dispatch to
>> another metafunction, which might be preferable to listing out all the
>> special cases of combinations of builtin types.
>
> Could you give an example? I do not understand clearly what you mean.
> Problem here is that for example (double % double) yields a compile
> time error and that it is not possible to overload operator%(built-in
> type, built-in type).
> So if you have a solution that replaces a long list of template
> specialization by much fewer lines, please propose.

For example:

template<
     class T, class U, class Result,
     bool = boost::is_class< typename boost::remove_reference<T>::type
>::value ||
            boost::is_union< typename boost::remove_reference<T>::type
>::value ||
            boost::is_class< typename boost::remove_reference<U>::type
>::value ||
            boost::is_union< typename boost::remove_reference<U>::type
>::value
>
struct has_operator_random_dispatch;

template< class T, class U, class Result >
struct has_operator_random_dispatch< T, U, Result, true >
{ ...either T or U is of a class/union type, so we can implement as
before... };

template< class T, class U, class Result >
struct has_operator_random_dispatch< T, U, Result, false >
     : builtin_has_operator_random< T, U, Result >
{ };

and then one defines builtin_has_operator_random appropriately. For
example (not 100% sure this is correct...):

template<
     class T, class U, class Result,
     class StrippedT = typename boost::remove_const< typename
boost::remove_reference<T>::type >::type,
     class StrippedU = typename boost::remove_const< typename
boost::remove_reference<U>::type >::type
>
struct builtin_is_comparable
     : boost::mpl::and_<
           boost::is_arithmetic< StrippedT >,
           boost::is_arithmetic< StrippedU >,
           boost::mpl::or_<
               boost::is_void< Result >,
               boost::is_convertible< bool, Result >
>
>
{ };

template< class T, class U, class Result, class V, class W >
struct builtin_is_comparable< T, U, Result, V*, W* >
     : boost::mpl::and_<
           boost::mpl::or_<
               boost::is_convertible< typename boost::remove_cv<V>::type
*, typename boost::remove_cv<W>::type * >,
               boost::is_convertible< typename boost::remove_cv<W>::type
*, typename boost::remove_cv<V>::type * >
>,
           boost::mpl::or_<
               boost::is_void< Result >,
               boost::is_convertible< bool, Result >
>
>
{ };

>> Actually, I'm not entirely
>> sure how you cover builtin types. I see in has_operator_bit_and.hpp that
>> you list combinations of builtin types that *don't* have the bitand operator
>> is this list suppose to be exhaustive?
>
> Yes it is supposed to be exhaustive.

Where do you cover pointer types?

To me, it seems more error prone to try to exhaustively list all the
builtin cases, and I think generally you'll need some more advanced
logic anyway (e.g., as far as I know, 2 pointer types are comparable iff
one is convertible to the other after stripping cv qualifiers of their
pointee). On the other hand, it can be difficult to get the logic right
for a general metafunction covering all combinations of builtin types...

>> I still think one should be able to pass a metafunction to an operator trait
>> to be invoked on the actual result type of the operation, but that's more of
>> a feature request than an implementation comment.
>
> I will first try to comply to all other request, i.e. (i) extension to
> all operators (already done<<,>> and op=),

I don't see operator= in your list of has_operator_*.hpp files... (and
I'm curious how you managed to implement that one!)

> (ii) use existing
> is_convertible<T>.
> Then, maybe you could add your proposal as a later addition.

I found it convenient, in this context, for is_convertible< T, void > to
evaluate to true; I would assume that's why you were using your own
implementation originally.

- Jeff


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