File indexing completed on 2025-01-18 09:38:12
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_HISTOGRAM_DETAIL_SAFE_COMPARISON_HPP
0008 #define BOOST_HISTOGRAM_DETAIL_SAFE_COMPARISON_HPP
0009
0010 #include <boost/mp11/utility.hpp>
0011 #include <boost/type.hpp>
0012 #include <type_traits>
0013
0014 namespace boost {
0015 namespace histogram {
0016 namespace detail {
0017
0018 template <class T>
0019 auto make_unsigned(const T& t) noexcept {
0020 static_assert(std::is_integral<T>::value, "");
0021 return static_cast<std::make_unsigned_t<T>>(t);
0022 }
0023
0024 template <class T>
0025 using number_category =
0026 mp11::mp_if<std::is_integral<T>,
0027 mp11::mp_if<std::is_signed<T>, type<int>, type<unsigned>>, type<void>>;
0028
0029
0030 struct safe_equal {
0031 template <class T, class U>
0032 bool operator()(const T& t, const U& u) const noexcept {
0033 return impl(number_category<T>{}, number_category<U>{}, t, u);
0034 }
0035
0036 template <class C1, class C2, class T, class U>
0037 bool impl(C1, C2, const T& t, const U& u) const noexcept {
0038 return t == u;
0039 }
0040
0041 template <class T, class U>
0042 bool impl(type<int>, type<unsigned>, const T& t, const U& u) const noexcept {
0043 return t >= 0 && make_unsigned(t) == u;
0044 }
0045
0046 template <class T, class U>
0047 bool impl(type<unsigned>, type<int>, const T& t, const U& u) const noexcept {
0048 return impl(type<int>{}, type<unsigned>{}, u, t);
0049 }
0050 };
0051
0052
0053 struct safe_less {
0054 template <class T, class U>
0055 bool operator()(const T& t, const U& u) const noexcept {
0056 return impl(number_category<T>{}, number_category<U>{}, t, u);
0057 }
0058
0059 template <class C1, class C2, class T, class U>
0060 bool impl(C1, C2, const T& t, const U& u) const noexcept {
0061 return t < u;
0062 }
0063
0064 template <class T, class U>
0065 bool impl(type<int>, type<unsigned>, const T& t, const U& u) const noexcept {
0066 return t < 0 || make_unsigned(t) < u;
0067 }
0068
0069 template <class T, class U>
0070 bool impl(type<unsigned>, type<int>, const T& t, const U& u) const noexcept {
0071 return 0 < u && t < make_unsigned(u);
0072 }
0073 };
0074
0075
0076 struct safe_greater {
0077 template <class T, class U>
0078 bool operator()(const T& t, const U& u) const noexcept {
0079 return safe_less()(u, t);
0080 }
0081 };
0082
0083 }
0084 }
0085 }
0086
0087 #endif