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