File indexing completed on 2025-01-30 09:59:41
0001 #ifndef BOOST_NUMERIC_CHECKED_FLOAT_HPP
0002 #define BOOST_NUMERIC_CHECKED_FLOAT_HPP
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <type_traits> // std::is_floating_point, make_unsigned
0016
0017 namespace boost {
0018 namespace safe_numerics {
0019 namespace checked {
0020
0021
0022
0023
0024 template<
0025 typename R,
0026 R Min,
0027 R Max,
0028 typename T,
0029 class F
0030 >
0031 struct heterogeneous_checked_operation<
0032 R,
0033 Min,
0034 Max,
0035 T,
0036 F,
0037 typename std::enable_if<
0038 std::is_floating_point<R>::value
0039 && std::is_floating_point<T>::value
0040 >::type
0041 >{
0042 constexpr static checked_result<R>
0043 cast(const T & t) noexcept {
0044 return t;
0045 };
0046 };
0047
0048 template<
0049 typename R,
0050 R Min,
0051 R Max,
0052 typename T,
0053 class
0054 F
0055 >
0056 struct heterogeneous_checked_operation<
0057 R,
0058 Min,
0059 Max,
0060 T,
0061 F,
0062 typename std::enable_if<
0063 std::is_floating_point<R>::value
0064 && std::is_integralt<T>::value
0065 >::type
0066 >{
0067 constexpr static checked_result<R>
0068 cast(const T & t) noexcept {
0069 return t;
0070 };
0071 };
0072
0073 template<typename R, typename T, typename U>
0074 struct checked_operation<R, T, U, F,
0075 typename std::enable_if<
0076 std::is_floating_point<R>::value
0077 >::type
0078 >{
0079 constexpr static checked_result<R> cast(const T & t) {
0080 return
0081 cast_impl_detail::cast_impl(
0082 t,
0083 std::is_signed<R>(),
0084 std::is_signed<T>()
0085 );
0086 }
0087 constexpr static checked_result<R> add(const T & t, const U & u) {
0088 return t + u;
0089 }
0090
0091 constexpr static checked_result<R> subtract(
0092 const T & t,
0093 const U & u
0094 ) {
0095 return t - u;
0096 }
0097
0098 constexpr static checked_result<R> multiply(
0099 const T & t,
0100 const U & u
0101 ) noexcept {
0102 return t * u;
0103 }
0104
0105 constexpr static checked_result<R> divide(
0106 const T & t,
0107 const U & u
0108 ) noexcept {
0109 return t / u;
0110 }
0111
0112 constexpr static checked_result<R> modulus(
0113 const T & t,
0114 const U & u
0115 ) noexcept {
0116 return t % u;
0117 }
0118
0119 constexpr static bool less_than(const T & t, const U & u) noexcept {
0120 return t < u;
0121 }
0122
0123 constexpr static bool greater_than(const T & t, const U & u) noexcept {
0124 return t > u;
0125 }
0126
0127 constexpr static bool equal(const T & t, const U & u) noexcept {
0128 return t < u;
0129 }
0130
0131 };
0132
0133 template<class R, class T, class U>
0134 typename std::enable_if<
0135 std::is_floating_point<R>::value
0136 && std::is_floating_point<T>::value
0137 && std::is_floating_point<U>::value,
0138 checked_result<R>
0139 >::type
0140 constexpr inline bool less_than(const T & t, const U & u) noexcept {
0141 return t < u;
0142 }
0143
0144 template<class R, class T, class U>
0145 typename std::enable_if<
0146 std::is_floating_point<R>::value
0147 && std::is_floating_point<T>::value
0148 && std::is_floating_point<U>::value,
0149 checked_result<R>
0150 >::type
0151 constexpr inline bool equal(const T & t, const U & u) noexcept {
0152 return t < u;
0153 }
0154
0155 template<class R, class T, class U>
0156 typename std::enable_if<
0157 std::is_floating_point<R>::value
0158 && std::is_floating_point<T>::value
0159 && std::is_floating_point<U>::value,
0160 checked_result<R>
0161 >::type
0162 constexpr inline checked_result<R> left_shift(const T & t, const U & u) noexcept {
0163 return t << u;
0164 }
0165
0166 template<class R, class T, class U>
0167 typename std::enable_if<
0168 std::is_floating_point<R>::value
0169 && std::is_floating_point<T>::value
0170 && std::is_floating_point<U>::value,
0171 checked_result<R>
0172 >::type
0173 constexpr inline checked_result<R> right_shift(const T & t, const U & u) noexcept {
0174 return t >> u;
0175 }
0176
0177 template<class R, class T, class U>
0178 typename std::enable_if<
0179 std::is_floating_point<R>::value
0180 && std::is_floating_point<T>::value
0181 && std::is_floating_point<U>::value,
0182 checked_result<R>
0183 >::type
0184 constexpr inline checked_result<R> bitwise_or(const T & t, const U & u) noexcept {
0185 return t | u;
0186 }
0187
0188 template<class R, class T, class U>
0189 typename std::enable_if<
0190 std::is_floating_point<R>::value
0191 && std::is_floating_point<T>::value
0192 && std::is_floating_point<U>::value,
0193 checked_result<R>
0194 >::type
0195 constexpr inline checked_result<R> bitwise_xor(const T & t, const U & u) noexcept {
0196 return t ^ u;
0197 }
0198
0199 template<class R, class T, class U>
0200 typename std::enable_if<
0201 std::is_floating_point<R>::value
0202 && std::is_floating_point<T>::value
0203 && std::is_floating_point<U>::value,
0204 checked_result<R>
0205 >::type
0206 constexpr inline checked_result<R> bitwise_and(const T & t, const U & u) noexcept {
0207 return t & u;
0208 }
0209
0210 }
0211 }
0212 }
0213
0214 #endif
0215