williamr@2
|
1 |
/* boost random/detail/signed_unsigned_compare.hpp header file
|
williamr@2
|
2 |
*
|
williamr@2
|
3 |
* Copyright Jens Maurer 2000-2001
|
williamr@2
|
4 |
* Distributed under the Boost Software License, Version 1.0. (See
|
williamr@2
|
5 |
* accompanying file LICENSE_1_0.txt or copy at
|
williamr@2
|
6 |
* http://www.boost.org/LICENSE_1_0.txt)
|
williamr@2
|
7 |
*
|
williamr@2
|
8 |
* See http://www.boost.org for most recent version including documentation.
|
williamr@2
|
9 |
*
|
williamr@2
|
10 |
* Revision history
|
williamr@2
|
11 |
*/
|
williamr@2
|
12 |
|
williamr@2
|
13 |
|
williamr@2
|
14 |
#ifndef BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_COMPARE
|
williamr@2
|
15 |
#define BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_COMPARE
|
williamr@2
|
16 |
|
williamr@2
|
17 |
#include <boost/limits.hpp>
|
williamr@2
|
18 |
|
williamr@2
|
19 |
namespace boost {
|
williamr@2
|
20 |
namespace random {
|
williamr@2
|
21 |
|
williamr@2
|
22 |
/*
|
williamr@2
|
23 |
* Correctly compare two numbers whose types possibly differ in signedness.
|
williamr@2
|
24 |
* See boost::numeric_cast<> for the general idea.
|
williamr@2
|
25 |
* Most "if" statements involve only compile-time constants, so the
|
williamr@2
|
26 |
* optimizing compiler can do its job easily.
|
williamr@2
|
27 |
*
|
williamr@2
|
28 |
* With most compilers, the straightforward implementation produces a
|
williamr@2
|
29 |
* bunch of (legitimate) warnings. Some template magic helps, though.
|
williamr@2
|
30 |
*/
|
williamr@2
|
31 |
|
williamr@2
|
32 |
namespace detail {
|
williamr@2
|
33 |
template<bool signed1, bool signed2>
|
williamr@2
|
34 |
struct do_compare
|
williamr@2
|
35 |
{ };
|
williamr@2
|
36 |
|
williamr@2
|
37 |
template<>
|
williamr@2
|
38 |
struct do_compare<false, false>
|
williamr@2
|
39 |
{
|
williamr@2
|
40 |
// cast to the larger type is automatic with built-in types
|
williamr@2
|
41 |
template<class T1, class T2>
|
williamr@2
|
42 |
static bool equal(T1 x, T2 y) { return x == y; }
|
williamr@2
|
43 |
template<class T1, class T2>
|
williamr@2
|
44 |
static bool lessthan(T1 x, T2 y) { return x < y; }
|
williamr@2
|
45 |
};
|
williamr@2
|
46 |
|
williamr@2
|
47 |
template<>
|
williamr@2
|
48 |
struct do_compare<true, true> : do_compare<false, false>
|
williamr@2
|
49 |
{ };
|
williamr@2
|
50 |
|
williamr@2
|
51 |
template<>
|
williamr@2
|
52 |
struct do_compare<true, false>
|
williamr@2
|
53 |
{
|
williamr@2
|
54 |
template<class T1, class T2>
|
williamr@2
|
55 |
static bool equal(T1 x, T2 y) { return x >= 0 && static_cast<T2>(x) == y; }
|
williamr@2
|
56 |
template<class T1, class T2>
|
williamr@2
|
57 |
static bool lessthan(T1 x, T2 y) { return x < 0 || static_cast<T2>(x) < y; }
|
williamr@2
|
58 |
};
|
williamr@2
|
59 |
|
williamr@2
|
60 |
template<>
|
williamr@2
|
61 |
struct do_compare<false, true>
|
williamr@2
|
62 |
{
|
williamr@2
|
63 |
template<class T1, class T2>
|
williamr@2
|
64 |
static bool equal(T1 x, T2 y) { return y >= 0 && x == static_cast<T1>(y); }
|
williamr@2
|
65 |
template<class T1, class T2>
|
williamr@2
|
66 |
static bool lessthan(T1 x, T2 y) { return y >= 0 && x < static_cast<T1>(y); }
|
williamr@2
|
67 |
};
|
williamr@2
|
68 |
|
williamr@2
|
69 |
} // namespace detail
|
williamr@2
|
70 |
|
williamr@2
|
71 |
|
williamr@2
|
72 |
template<class T1, class T2>
|
williamr@2
|
73 |
int equal_signed_unsigned(T1 x, T2 y)
|
williamr@2
|
74 |
{
|
williamr@2
|
75 |
typedef std::numeric_limits<T1> x_traits;
|
williamr@2
|
76 |
typedef std::numeric_limits<T2> y_traits;
|
williamr@2
|
77 |
return detail::do_compare<x_traits::is_signed, y_traits::is_signed>::equal(x, y);
|
williamr@2
|
78 |
}
|
williamr@2
|
79 |
|
williamr@2
|
80 |
template<class T1, class T2>
|
williamr@2
|
81 |
int lessthan_signed_unsigned(T1 x, T2 y)
|
williamr@2
|
82 |
{
|
williamr@2
|
83 |
typedef std::numeric_limits<T1> x_traits;
|
williamr@2
|
84 |
typedef std::numeric_limits<T2> y_traits;
|
williamr@2
|
85 |
return detail::do_compare<x_traits::is_signed, y_traits::is_signed>::lessthan(x, y);
|
williamr@2
|
86 |
}
|
williamr@2
|
87 |
|
williamr@2
|
88 |
} // namespace random
|
williamr@2
|
89 |
} // namespace boost
|
williamr@2
|
90 |
|
williamr@2
|
91 |
#endif // BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_COMPARE
|