]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/pfr/detail/functional.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / pfr / detail / functional.hpp
1 // Copyright (c) 2016-2020 Antony Polukhin
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #ifndef BOOST_PFR_DETAIL_FUNCTIONAL_HPP
7 #define BOOST_PFR_DETAIL_FUNCTIONAL_HPP
8 #pragma once
9
10 #include <boost/pfr/detail/config.hpp>
11
12 #include <functional>
13
14 #include <boost/pfr/detail/sequence_tuple.hpp>
15
16 namespace boost { namespace pfr { namespace detail {
17 template <std::size_t I, std::size_t N>
18 struct equal_impl {
19 template <class T, class U>
20 constexpr static bool cmp(const T& v1, const U& v2) noexcept {
21 return ::boost::pfr::detail::sequence_tuple::get<I>(v1) == ::boost::pfr::detail::sequence_tuple::get<I>(v2)
22 && equal_impl<I + 1, N>::cmp(v1, v2);
23 }
24 };
25
26 template <std::size_t N>
27 struct equal_impl<N, N> {
28 template <class T, class U>
29 constexpr static bool cmp(const T&, const U&) noexcept {
30 return T::size_v == U::size_v;
31 }
32 };
33
34 template <std::size_t I, std::size_t N>
35 struct not_equal_impl {
36 template <class T, class U>
37 constexpr static bool cmp(const T& v1, const U& v2) noexcept {
38 return ::boost::pfr::detail::sequence_tuple::get<I>(v1) != ::boost::pfr::detail::sequence_tuple::get<I>(v2)
39 || not_equal_impl<I + 1, N>::cmp(v1, v2);
40 }
41 };
42
43 template <std::size_t N>
44 struct not_equal_impl<N, N> {
45 template <class T, class U>
46 constexpr static bool cmp(const T&, const U&) noexcept {
47 return T::size_v != U::size_v;
48 }
49 };
50
51 template <std::size_t I, std::size_t N>
52 struct less_impl {
53 template <class T, class U>
54 constexpr static bool cmp(const T& v1, const U& v2) noexcept {
55 return sequence_tuple::get<I>(v1) < sequence_tuple::get<I>(v2)
56 || (sequence_tuple::get<I>(v1) == sequence_tuple::get<I>(v2) && less_impl<I + 1, N>::cmp(v1, v2));
57 }
58 };
59
60 template <std::size_t N>
61 struct less_impl<N, N> {
62 template <class T, class U>
63 constexpr static bool cmp(const T&, const U&) noexcept {
64 return T::size_v < U::size_v;
65 }
66 };
67
68 template <std::size_t I, std::size_t N>
69 struct less_equal_impl {
70 template <class T, class U>
71 constexpr static bool cmp(const T& v1, const U& v2) noexcept {
72 return sequence_tuple::get<I>(v1) < sequence_tuple::get<I>(v2)
73 || (sequence_tuple::get<I>(v1) == sequence_tuple::get<I>(v2) && less_equal_impl<I + 1, N>::cmp(v1, v2));
74 }
75 };
76
77 template <std::size_t N>
78 struct less_equal_impl<N, N> {
79 template <class T, class U>
80 constexpr static bool cmp(const T&, const U&) noexcept {
81 return T::size_v <= U::size_v;
82 }
83 };
84
85 template <std::size_t I, std::size_t N>
86 struct greater_impl {
87 template <class T, class U>
88 constexpr static bool cmp(const T& v1, const U& v2) noexcept {
89 return sequence_tuple::get<I>(v1) > sequence_tuple::get<I>(v2)
90 || (sequence_tuple::get<I>(v1) == sequence_tuple::get<I>(v2) && greater_impl<I + 1, N>::cmp(v1, v2));
91 }
92 };
93
94 template <std::size_t N>
95 struct greater_impl<N, N> {
96 template <class T, class U>
97 constexpr static bool cmp(const T&, const U&) noexcept {
98 return T::size_v > U::size_v;
99 }
100 };
101
102 template <std::size_t I, std::size_t N>
103 struct greater_equal_impl {
104 template <class T, class U>
105 constexpr static bool cmp(const T& v1, const U& v2) noexcept {
106 return sequence_tuple::get<I>(v1) > sequence_tuple::get<I>(v2)
107 || (sequence_tuple::get<I>(v1) == sequence_tuple::get<I>(v2) && greater_equal_impl<I + 1, N>::cmp(v1, v2));
108 }
109 };
110
111 template <std::size_t N>
112 struct greater_equal_impl<N, N> {
113 template <class T, class U>
114 constexpr static bool cmp(const T&, const U&) noexcept {
115 return T::size_v >= U::size_v;
116 }
117 };
118
119 template <typename SizeT>
120 constexpr void hash_combine(SizeT& seed, SizeT value) noexcept {
121 seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
122 }
123
124 template <typename T>
125 auto compute_hash(const T& value, long /*priority*/)
126 -> decltype(std::hash<T>()(value))
127 {
128 return std::hash<T>()(value);
129 }
130
131 template <typename T>
132 std::size_t compute_hash(const T& /*value*/, int /*priority*/) {
133 static_assert(sizeof(T) && false, "====================> Boost.PFR: std::hash not specialized for type T");
134 return 0;
135 }
136
137 template <std::size_t I, std::size_t N>
138 struct hash_impl {
139 template <class T>
140 constexpr static std::size_t compute(const T& val) noexcept {
141 std::size_t h = detail::compute_hash( ::boost::pfr::detail::sequence_tuple::get<I>(val), 1L );
142 detail::hash_combine(h, hash_impl<I + 1, N>::compute(val) );
143 return h;
144 }
145 };
146
147 template <std::size_t N>
148 struct hash_impl<N, N> {
149 template <class T>
150 constexpr static std::size_t compute(const T&) noexcept {
151 return 0;
152 }
153 };
154
155 ///////////////////// Define min_element and to avoid inclusion of <algorithm>
156 constexpr std::size_t min_size(std::size_t x, std::size_t y) noexcept {
157 return x < y ? x : y;
158 }
159
160 template <template <std::size_t, std::size_t> class Visitor, class T, class U>
161 bool binary_visit(const T& x, const U& y) {
162 constexpr std::size_t fields_count_lhs = detail::fields_count<std::remove_reference_t<T>>();
163 constexpr std::size_t fields_count_rhs = detail::fields_count<std::remove_reference_t<U>>();
164 constexpr std::size_t fields_count_min = detail::min_size(fields_count_lhs, fields_count_rhs);
165 typedef Visitor<0, fields_count_min> visitor_t;
166
167 #if BOOST_PFR_USE_CPP17 || BOOST_PFR_USE_LOOPHOLE
168 return visitor_t::cmp(detail::tie_as_tuple(x), detail::tie_as_tuple(y));
169 #else
170 bool result = true;
171 ::boost::pfr::detail::for_each_field_dispatcher(
172 x,
173 [&result, &y](const auto& lhs) {
174 ::boost::pfr::detail::for_each_field_dispatcher(
175 y,
176 [&result, &lhs](const auto& rhs) {
177 result = visitor_t::cmp(lhs, rhs);
178 },
179 detail::make_index_sequence<fields_count_rhs>{}
180 );
181 },
182 detail::make_index_sequence<fields_count_lhs>{}
183 );
184
185 return result;
186 #endif
187 }
188
189 }}} // namespace boost::pfr::detail
190
191 #endif // BOOST_PFR_DETAIL_FUNCTIONAL_HPP