williamr@2: /* boost random/detail/signed_unsigned_compare.hpp header file williamr@2: * williamr@2: * Copyright Jens Maurer 2000-2001 williamr@2: * Distributed under the Boost Software License, Version 1.0. (See williamr@2: * accompanying file LICENSE_1_0.txt or copy at williamr@2: * http://www.boost.org/LICENSE_1_0.txt) williamr@2: * williamr@2: * See http://www.boost.org for most recent version including documentation. williamr@2: * williamr@2: * Revision history williamr@2: */ williamr@2: williamr@2: williamr@2: #ifndef BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_COMPARE williamr@2: #define BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_COMPARE williamr@2: williamr@2: #include williamr@2: williamr@2: namespace boost { williamr@2: namespace random { williamr@2: williamr@2: /* williamr@2: * Correctly compare two numbers whose types possibly differ in signedness. williamr@2: * See boost::numeric_cast<> for the general idea. williamr@2: * Most "if" statements involve only compile-time constants, so the williamr@2: * optimizing compiler can do its job easily. williamr@2: * williamr@2: * With most compilers, the straightforward implementation produces a williamr@2: * bunch of (legitimate) warnings. Some template magic helps, though. williamr@2: */ williamr@2: williamr@2: namespace detail { williamr@2: template williamr@2: struct do_compare williamr@2: { }; williamr@2: williamr@2: template<> williamr@2: struct do_compare williamr@2: { williamr@2: // cast to the larger type is automatic with built-in types williamr@2: template williamr@2: static bool equal(T1 x, T2 y) { return x == y; } williamr@2: template williamr@2: static bool lessthan(T1 x, T2 y) { return x < y; } williamr@2: }; williamr@2: williamr@2: template<> williamr@2: struct do_compare : do_compare williamr@2: { }; williamr@2: williamr@2: template<> williamr@2: struct do_compare williamr@2: { williamr@2: template williamr@2: static bool equal(T1 x, T2 y) { return x >= 0 && static_cast(x) == y; } williamr@2: template williamr@2: static bool lessthan(T1 x, T2 y) { return x < 0 || static_cast(x) < y; } williamr@2: }; williamr@2: williamr@2: template<> williamr@2: struct do_compare williamr@2: { williamr@2: template williamr@2: static bool equal(T1 x, T2 y) { return y >= 0 && x == static_cast(y); } williamr@2: template williamr@2: static bool lessthan(T1 x, T2 y) { return y >= 0 && x < static_cast(y); } williamr@2: }; williamr@2: williamr@2: } // namespace detail williamr@2: williamr@2: williamr@2: template williamr@2: int equal_signed_unsigned(T1 x, T2 y) williamr@2: { williamr@2: typedef std::numeric_limits x_traits; williamr@2: typedef std::numeric_limits y_traits; williamr@2: return detail::do_compare::equal(x, y); williamr@2: } williamr@2: williamr@2: template williamr@2: int lessthan_signed_unsigned(T1 x, T2 y) williamr@2: { williamr@2: typedef std::numeric_limits x_traits; williamr@2: typedef std::numeric_limits y_traits; williamr@2: return detail::do_compare::lessthan(x, y); williamr@2: } williamr@2: williamr@2: } // namespace random williamr@2: } // namespace boost williamr@2: williamr@2: #endif // BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_COMPARE