#ifndef BOOST_TT_IS_COMPARABLE_HPP_INCLUDED #define BOOST_TT_IS_COMPARABLE_HPP_INCLUDED #include #include namespace boost { namespace detail { // This namespace ensures that ADL doesn't mess things up. namespace is_comparable { // 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 any(T const&) ; } ; tag operator< (const any&, const any&) ; tag operator<=(const any&, const any&) ; tag operator> (const any&, const any&) ; tag operator>=(const any&, const any&) ; tag operator==(const any&, const any&) ; 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) template char check(T const&) ; template struct is_comparable_base_impl { static typename boost::remove_cv::type &x ; } ; template struct is_less_comparable_impl : is_comparable_base_impl { static const bool value = sizeof( check( (is_comparable_base_impl::x < is_comparable_base_impl::x, 0) ) ) == 1 ; } ; template struct is_less_equal_comparable_impl : is_comparable_base_impl { static const bool value = sizeof( check( (is_comparable_base_impl::x <= is_comparable_base_impl::x, 0) ) ) == 1 ; } ; template struct is_greater_comparable_impl : is_comparable_base_impl { static const bool value = sizeof( check( (is_comparable_base_impl::x > is_comparable_base_impl::x, 0) ) ) == 1 ; } ; template struct is_greater_equal_comparable_impl : is_comparable_base_impl { static const bool value = sizeof( check( (is_comparable_base_impl::x >= is_comparable_base_impl::x, 0) ) ) == 1 ; } ; template struct is_equal_to_comparable_impl : is_comparable_base_impl { static const bool value = sizeof( check( (is_comparable_base_impl::x == is_comparable_base_impl::x, 0) ) ) == 1 ; } ; template struct is_not_equal_to_comparable_impl : is_comparable_base_impl { static const bool value = sizeof( check( (is_comparable_base_impl::x != is_comparable_base_impl::x, 0) ) ) == 1 ; } ; } // namespace is_comparable } // namespace detail template struct is_less_comparable : boost::integral_constant::value> { } ; template struct is_less_equal_comparable : boost::integral_constant::value> { } ; template struct is_greater_comparable : boost::integral_constant::value> { } ; template struct is_greater_equal_comparable : boost::integral_constant::value> { } ; template struct is_equal_to_comparable : boost::integral_constant::value> { } ; template struct is_not_equal_to_comparable : boost::integral_constant::value> { } ; } // namespace boost #endif