]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/histogram/detail/operators.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / histogram / detail / operators.hpp
CommitLineData
92f5a8d4
TL
1// Copyright 2019 Hans Dembinski
2//
3// Distributed under the Boost Software License, Version 1.0.
4// (See accompanying file LICENSE_1_0.txt
5// or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7#ifndef BOOST_HISTOGRAM_DETAIL_OPERATORS_HPP
8#define BOOST_HISTOGRAM_DETAIL_OPERATORS_HPP
9
10#include <boost/histogram/detail/detect.hpp>
11#include <boost/mp11/algorithm.hpp>
12#include <boost/mp11/list.hpp>
13#include <boost/mp11/utility.hpp>
20effc67 14#include <type_traits>
92f5a8d4
TL
15
16namespace boost {
17namespace histogram {
18namespace detail {
19
20template <class T, class U>
20effc67
TL
21using if_not_same = std::enable_if_t<(!std::is_same<T, U>::value), bool>;
22
23// template <class T, class U>
24// using if_not_same_and_has_eq =
25// std::enable_if_t<(!std::is_same<T, U>::value && !has_method_eq<T, U>::value),
26// bool>;
92f5a8d4
TL
27
28// totally_ordered is for types with a <= b == !(a > b) [floats with NaN violate this]
29// Derived must implement <,== for symmetric form and <,>,== for non-symmetric.
30
31// partially_ordered is for types with a <= b == a < b || a == b [for floats with NaN]
20effc67 32// Derived must implement <,== for symmetric form and <,>,== for non-symmetric.
92f5a8d4
TL
33
34template <class T, class U>
35struct mirrored {
36 friend bool operator<(const U& a, const T& b) noexcept { return b > a; }
37 friend bool operator>(const U& a, const T& b) noexcept { return b < a; }
38 friend bool operator==(const U& a, const T& b) noexcept { return b == a; }
39 friend bool operator<=(const U& a, const T& b) noexcept { return b >= a; }
40 friend bool operator>=(const U& a, const T& b) noexcept { return b <= a; }
41 friend bool operator!=(const U& a, const T& b) noexcept { return b != a; }
20effc67 42}; // namespace histogram
92f5a8d4
TL
43
44template <class T>
45struct mirrored<T, void> {
46 template <class U>
20effc67 47 friend if_not_same<T, U> operator<(const U& a, const T& b) noexcept {
92f5a8d4
TL
48 return b > a;
49 }
50 template <class U>
20effc67 51 friend if_not_same<T, U> operator>(const U& a, const T& b) noexcept {
92f5a8d4
TL
52 return b < a;
53 }
54 template <class U>
20effc67
TL
55 friend std::enable_if_t<(!has_method_eq<U, T>::value), bool> operator==(
56 const U& a, const T& b) noexcept {
57 return b.operator==(a);
92f5a8d4
TL
58 }
59 template <class U>
20effc67 60 friend if_not_same<T, U> operator<=(const U& a, const T& b) noexcept {
92f5a8d4
TL
61 return b >= a;
62 }
63 template <class U>
20effc67 64 friend if_not_same<T, U> operator>=(const U& a, const T& b) noexcept {
92f5a8d4
TL
65 return b <= a;
66 }
67 template <class U>
20effc67 68 friend if_not_same<T, U> operator!=(const U& a, const T& b) noexcept {
92f5a8d4
TL
69 return b != a;
70 }
71};
72
73template <class T>
74struct mirrored<T, T> {
75 friend bool operator>(const T& a, const T& b) noexcept { return b.operator<(a); }
76};
77
78template <class T, class U>
79struct equality {
80 friend bool operator!=(const T& a, const U& b) noexcept { return !a.operator==(b); }
81};
82
83template <class T>
84struct equality<T, void> {
85 template <class U>
20effc67 86 friend if_not_same<T, U> operator!=(const T& a, const U& b) noexcept {
92f5a8d4
TL
87 return !(a == b);
88 }
89};
90
91template <class T, class U>
92struct totally_ordered_impl : equality<T, U>, mirrored<T, U> {
93 friend bool operator<=(const T& a, const U& b) noexcept { return !(a > b); }
94 friend bool operator>=(const T& a, const U& b) noexcept { return !(a < b); }
95};
96
97template <class T>
98struct totally_ordered_impl<T, void> : equality<T, void>, mirrored<T, void> {
99 template <class U>
20effc67 100 friend if_not_same<T, U> operator<=(const T& a, const U& b) noexcept {
92f5a8d4
TL
101 return !(a > b);
102 }
103 template <class U>
20effc67 104 friend if_not_same<T, U> operator>=(const T& a, const U& b) noexcept {
92f5a8d4
TL
105 return !(a < b);
106 }
107};
108
109template <class T, class... Ts>
110using totally_ordered = mp11::mp_rename<
111 mp11::mp_product<totally_ordered_impl, mp11::mp_list<T>, mp11::mp_list<Ts...> >,
112 mp11::mp_inherit>;
113
114template <class T, class U>
115struct partially_ordered_impl : equality<T, U>, mirrored<T, U> {
116 friend bool operator<=(const T& a, const U& b) noexcept { return a < b || a == b; }
117 friend bool operator>=(const T& a, const U& b) noexcept { return a > b || a == b; }
118};
119
120template <class T>
121struct partially_ordered_impl<T, void> : equality<T, void>, mirrored<T, void> {
122 template <class U>
20effc67 123 friend if_not_same<T, U> operator<=(const T& a, const U& b) noexcept {
92f5a8d4
TL
124 return a < b || a == b;
125 }
126 template <class U>
20effc67 127 friend if_not_same<T, U> operator>=(const T& a, const U& b) noexcept {
92f5a8d4
TL
128 return a > b || a == b;
129 }
130};
131
132template <class T, class... Ts>
133using partially_ordered = mp11::mp_rename<
134 mp11::mp_product<partially_ordered_impl, mp11::mp_list<T>, mp11::mp_list<Ts...> >,
135 mp11::mp_inherit>;
136
137} // namespace detail
138} // namespace histogram
139} // namespace boost
140
141#endif // BOOST_HISTOGRAM_DETAIL_OPERATORS_HPP