Boost logo

Boost :

Subject: Re: [boost] [type_traits] adding is_less_comparable<T>, etc.
From: Frédéric Bron (frederic.bron_at_[hidden])
Date: 2009-09-01 05:30:01


> I think is_greater_than can be less restrictive than it is.  std::greater() provides an operator that permits comparing unrelated types as T's.  Therefore, I wonder if this would work:
>
>   template <class T, class U = T>
>   struct is_greater_comparable;
>
> Then, is_greater_comparable<int, float> would inherit from true_type.

I have tried to do that but cannot understand why it does not work.
Can you try this example and tell me why it does not give false each
time?

Frédéric

#include <iostream>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/integral_constant.hpp>

namespace boost {
namespace detail {

// This namespace ensures that ADL doesn't mess things up.
namespace is_less_comparable_impl {

// a type returned from comparison operator when no such operator is
found in the
// type's own namespace
struct tag { } ;

// any soaks up implicit conversions and makes the following
// comparison operators less-preferred than any other such operators that
// might be found via ADL.
struct any { template <class T> any(T const&) ; } ;

tag operator<(const any&, const any&) ;

// In case a comparison operator is found that returns void, we'll use
(x comp x),0
tag operator,(tag, int) ;

// two check overloads help us identify which comparison operator was picked

// check(tag) returns a reference to char[2] (sizeof>1)
char (& check(tag))[2] ;

// check(not tag) returns char (sizeof==1)
char check(int) ;

template < typename T, typename U >
struct is_less_comparable_impl {
        static typename boost::remove_cv<T>::type &t ;
        static typename boost::remove_cv<T>::type &u ;
        static const bool value = sizeof(check(((t<u), 0))) == 1 ;
} ;

} // namespace impl
} // namespace detail

template< typename T, typename U=T >
struct is_less_comparable :
boost::integral_constant<bool,(::boost::detail::is_less_comparable_impl::is_less_comparable_impl<T,U>::value)>
{
} ;

} // namespace boost

class NotComparable { } ;

int main() {
        std::cout << std::boolalpha ;
        std::cout << boost::is_less_comparable<double, NotComparable>::value
<< "\t(double<NotComparable)\n" ;
        std::cout << boost::is_less_comparable<NotComparable, double>::value
<< "\t(NotComparable>double)\n" ;
        return 0 ;
}


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