
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