1 #ifndef BOOST_NUMERIC_SAFE_COMPARE_HPP
2 #define BOOST_NUMERIC_SAFE_COMPARE_HPP
5 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
15 #include <type_traits>
19 namespace safe_numerics {
20 namespace safe_compare {
24 namespace safe_compare_detail {
26 using make_unsigned =
typename std::conditional<
27 std::is_signed<T>::value,
28 std::make_unsigned<T>,
33 template<
bool TS,
bool US>
35 template<
class T,
class U>
36 constexpr
static bool invoke(
const T & t,
const U & u){
43 struct less_than<false, true> {
44 template<
class T,
class U>
45 constexpr
static bool invoke(
const T & t,
const U & u){
50 less_than<false, false>::invoke(
52 static_cast<const typename make_unsigned<U>::type &
>(u)
59 struct less_than<true, false> {
60 template<
class T,
class U>
61 constexpr
static bool invoke(
const T & t,
const U & u){
66 less_than<false, false>::invoke(
67 static_cast<const typename make_unsigned<T>::type &
>(t),
75 template<
class T,
class U>
76 typename std::enable_if<
77 std::is_integral<T>::value && std::is_integral<U>::value,
80 constexpr less_than(
const T & lhs,
const U & rhs) {
81 return safe_compare_detail::less_than<
82 std::is_signed<T>::value,
83 std::is_signed<U>::value
84 >::template invoke(lhs, rhs);
87 template<
class T,
class U>
88 typename std::enable_if<
89 std::is_floating_point<T>::value && std::is_floating_point<U>::value,
92 constexpr less_than(
const T & lhs,
const U & rhs) {
96 template<
class T,
class U>
97 constexpr
bool greater_than(
const T & lhs,
const U & rhs) {
98 return less_than(rhs, lhs);
101 template<
class T,
class U>
102 constexpr
bool less_than_equal(
const T & lhs,
const U & rhs) {
103 return ! greater_than(lhs, rhs);
106 template<
class T,
class U>
107 constexpr
bool greater_than_equal(
const T & lhs,
const U & rhs) {
108 return ! less_than(lhs, rhs);
111 namespace safe_compare_detail {
113 template<
bool TS,
bool US>
115 template<
class T,
class U>
116 constexpr
static bool invoke(
const T & t,
const U & u){
123 struct equal<false, true> {
124 template<
class T,
class U>
125 constexpr
static bool invoke(
const T & t,
const U & u){
130 equal<false, false>::invoke(
132 static_cast<const typename make_unsigned<U>::type &
>(u)
139 struct equal<true, false> {
140 template<
class T,
class U>
141 constexpr
static bool invoke(
const T & t,
const U & u){
146 equal<false, false>::invoke(
147 static_cast<const typename make_unsigned<T>::type &
>(t),
155 template<
class T,
class U>
156 typename std::enable_if<
157 std::is_integral<T>::value && std::is_integral<U>::value,
160 constexpr equal(
const T & lhs,
const U & rhs) {
161 return safe_compare_detail::equal<
162 std::numeric_limits<T>::is_signed,
163 std::numeric_limits<U>::is_signed
164 >::template invoke(lhs, rhs);
167 template<
class T,
class U>
168 typename std::enable_if<
169 std::is_floating_point<T>::value && std::is_floating_point<U>::value,
172 constexpr equal(
const T & lhs,
const U & rhs) {
176 template<
class T,
class U>
177 constexpr
bool not_equal(
const T & lhs,
const U & rhs) {
178 return ! equal(lhs, rhs);
185 #endif // BOOST_NUMERIC_SAFE_COMPARE_HPP