File indexing completed on 2025-01-18 09:38:12
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_HISTOGRAM_DETAIL_OPERATORS_HPP
0008 #define BOOST_HISTOGRAM_DETAIL_OPERATORS_HPP
0009
0010 #include <boost/histogram/detail/detect.hpp>
0011 #include <boost/mp11/algorithm.hpp>
0012 #include <boost/mp11/list.hpp>
0013 #include <boost/mp11/utility.hpp>
0014 #include <type_traits>
0015
0016 namespace boost {
0017 namespace histogram {
0018 namespace detail {
0019
0020 template <class T, class U>
0021 using if_not_same = std::enable_if_t<(!std::is_same<T, U>::value), bool>;
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 template <class T, class U>
0035 struct mirrored {
0036 friend bool operator<(const U& a, const T& b) noexcept { return b > a; }
0037 friend bool operator>(const U& a, const T& b) noexcept { return b < a; }
0038 friend bool operator==(const U& a, const T& b) noexcept { return b == a; }
0039 friend bool operator<=(const U& a, const T& b) noexcept { return b >= a; }
0040 friend bool operator>=(const U& a, const T& b) noexcept { return b <= a; }
0041 friend bool operator!=(const U& a, const T& b) noexcept { return b != a; }
0042 };
0043
0044 template <class T>
0045 struct mirrored<T, void> {
0046 template <class U>
0047 friend if_not_same<T, U> operator<(const U& a, const T& b) noexcept {
0048 return b > a;
0049 }
0050 template <class U>
0051 friend if_not_same<T, U> operator>(const U& a, const T& b) noexcept {
0052 return b < a;
0053 }
0054 template <class U>
0055 friend std::enable_if_t<(!has_method_eq<U, T>::value), bool> operator==(
0056 const U& a, const T& b) noexcept {
0057 return b.operator==(a);
0058 }
0059 template <class U>
0060 friend if_not_same<T, U> operator<=(const U& a, const T& b) noexcept {
0061 return b >= a;
0062 }
0063 template <class U>
0064 friend if_not_same<T, U> operator>=(const U& a, const T& b) noexcept {
0065 return b <= a;
0066 }
0067 template <class U>
0068 friend if_not_same<T, U> operator!=(const U& a, const T& b) noexcept {
0069 return b != a;
0070 }
0071 };
0072
0073 template <class T>
0074 struct mirrored<T, T> {
0075 friend bool operator>(const T& a, const T& b) noexcept { return b.operator<(a); }
0076 };
0077
0078 template <class T, class U>
0079 struct equality {
0080 friend bool operator!=(const T& a, const U& b) noexcept { return !a.operator==(b); }
0081 };
0082
0083 template <class T>
0084 struct equality<T, void> {
0085 template <class U>
0086 friend if_not_same<T, U> operator!=(const T& a, const U& b) noexcept {
0087 return !(a == b);
0088 }
0089 };
0090
0091 template <class T, class U>
0092 struct totally_ordered_impl : equality<T, U>, mirrored<T, U> {
0093 friend bool operator<=(const T& a, const U& b) noexcept { return !(a > b); }
0094 friend bool operator>=(const T& a, const U& b) noexcept { return !(a < b); }
0095 };
0096
0097 template <class T>
0098 struct totally_ordered_impl<T, void> : equality<T, void>, mirrored<T, void> {
0099 template <class U>
0100 friend if_not_same<T, U> operator<=(const T& a, const U& b) noexcept {
0101 return !(a > b);
0102 }
0103 template <class U>
0104 friend if_not_same<T, U> operator>=(const T& a, const U& b) noexcept {
0105 return !(a < b);
0106 }
0107 };
0108
0109 template <class T, class... Ts>
0110 using totally_ordered = mp11::mp_rename<
0111 mp11::mp_product<totally_ordered_impl, mp11::mp_list<T>, mp11::mp_list<Ts...> >,
0112 mp11::mp_inherit>;
0113
0114 template <class T, class U>
0115 struct partially_ordered_impl : equality<T, U>, mirrored<T, U> {
0116 friend bool operator<=(const T& a, const U& b) noexcept { return a < b || a == b; }
0117 friend bool operator>=(const T& a, const U& b) noexcept { return a > b || a == b; }
0118 };
0119
0120 template <class T>
0121 struct partially_ordered_impl<T, void> : equality<T, void>, mirrored<T, void> {
0122 template <class U>
0123 friend if_not_same<T, U> operator<=(const T& a, const U& b) noexcept {
0124 return a < b || a == b;
0125 }
0126 template <class U>
0127 friend if_not_same<T, U> operator>=(const T& a, const U& b) noexcept {
0128 return a > b || a == b;
0129 }
0130 };
0131
0132 template <class T, class... Ts>
0133 using partially_ordered = mp11::mp_rename<
0134 mp11::mp_product<partially_ordered_impl, mp11::mp_list<T>, mp11::mp_list<Ts...> >,
0135 mp11::mp_inherit>;
0136
0137 }
0138 }
0139 }
0140
0141 #endif