]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/safe_numerics/safe_compare.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / safe_numerics / safe_compare.hpp
CommitLineData
92f5a8d4
TL
1#ifndef BOOST_NUMERIC_SAFE_COMPARE_HPP
2#define BOOST_NUMERIC_SAFE_COMPARE_HPP
3
4// Copyright (c) 2012 Robert Ramey
5//
6// Distributed under the Boost Software License, Version 1.0. (See
7// accompanying file LICENSE_1_0.txt or copy at
8// http://www.boost.org/LICENSE_1_0.txt)
9
10#include <type_traits>
11#include <limits>
12
13namespace boost {
14namespace safe_numerics {
15namespace safe_compare {
16
17////////////////////////////////////////////////////
18// safe comparison on primitive integral types
19namespace safe_compare_detail {
20 template<typename T>
21 using make_unsigned = typename std::conditional<
22 std::is_signed<T>::value,
23 std::make_unsigned<T>,
24 T
25 >::type;
26
27 // both arguments unsigned or signed
28 template<bool TS, bool US>
29 struct less_than {
30 template<class T, class U>
31 constexpr static bool invoke(const T & t, const U & u){
32 return t < u;
33 }
34 };
35
36 // T unsigned, U signed
37 template<>
38 struct less_than<false, true> {
39 template<class T, class U>
40 constexpr static bool invoke(const T & t, const U & u){
41 return
42 (u < 0) ?
43 false
44 :
45 less_than<false, false>::invoke(
46 t,
47 static_cast<const typename make_unsigned<U>::type &>(u)
48 )
49 ;
50 }
51 };
52 // T signed, U unsigned
53 template<>
54 struct less_than<true, false> {
55 template<class T, class U>
56 constexpr static bool invoke(const T & t, const U & u){
57 return
58 (t < 0) ?
59 true
60 :
61 less_than<false, false>::invoke(
62 static_cast<const typename make_unsigned<T>::type &>(t),
63 u
64 )
65 ;
66 }
67 };
68} // safe_compare_detail
69
70template<class T, class U>
71typename std::enable_if<
72 std::is_integral<T>::value && std::is_integral<U>::value,
73 bool
74>::type
75constexpr less_than(const T & lhs, const U & rhs) {
76 return safe_compare_detail::less_than<
77 std::is_signed<T>::value,
78 std::is_signed<U>::value
79 >::template invoke(lhs, rhs);
80}
81
82template<class T, class U>
83typename std::enable_if<
84 std::is_floating_point<T>::value && std::is_floating_point<U>::value,
85 bool
86>::type
87constexpr less_than(const T & lhs, const U & rhs) {
88 return lhs < rhs;
89}
90
91template<class T, class U>
92constexpr bool greater_than(const T & lhs, const U & rhs) {
93 return less_than(rhs, lhs);
94}
95
96template<class T, class U>
97constexpr bool less_than_equal(const T & lhs, const U & rhs) {
98 return ! greater_than(lhs, rhs);
99}
100
101template<class T, class U>
102constexpr bool greater_than_equal(const T & lhs, const U & rhs) {
103 return ! less_than(lhs, rhs);
104}
105
106namespace safe_compare_detail {
107 // both arguments unsigned or signed
108 template<bool TS, bool US>
109 struct equal {
110 template<class T, class U>
111 constexpr static bool invoke(const T & t, const U & u){
112 return t == u;
113 }
114 };
115
116 // T unsigned, U signed
117 template<>
118 struct equal<false, true> {
119 template<class T, class U>
120 constexpr static bool invoke(const T & t, const U & u){
121 return
122 (u < 0) ?
123 false
124 :
125 equal<false, false>::invoke(
126 t,
127 static_cast<const typename make_unsigned<U>::type &>(u)
128 )
129 ;
130 }
131 };
132 // T signed, U unsigned
133 template<>
134 struct equal<true, false> {
135 template<class T, class U>
136 constexpr static bool invoke(const T & t, const U & u){
137 return
138 (t < 0) ?
139 false
140 :
141 equal<false, false>::invoke(
142 static_cast<const typename make_unsigned<T>::type &>(t),
143 u
144 )
145 ;
146 }
147 };
148} // safe_compare_detail
149
150template<class T, class U>
151typename std::enable_if<
152 std::is_integral<T>::value && std::is_integral<U>::value,
153 bool
154>::type
155constexpr equal(const T & lhs, const U & rhs) {
156 return safe_compare_detail::equal<
157 std::numeric_limits<T>::is_signed,
158 std::numeric_limits<U>::is_signed
159 >::template invoke(lhs, rhs);
160}
161
162template<class T, class U>
163typename std::enable_if<
164 std::is_floating_point<T>::value && std::is_floating_point<U>::value,
165 bool
166>::type
167constexpr equal(const T & lhs, const U & rhs) {
168 return lhs == rhs;
169}
170
171template<class T, class U>
172constexpr bool not_equal(const T & lhs, const U & rhs) {
173 return ! equal(lhs, rhs);
174}
175
176} // safe_compare
177} // safe_numerics
178} // boost
179
180#endif // BOOST_NUMERIC_SAFE_COMPARE_HPP