]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/lambda2/lambda2.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / lambda2 / lambda2.hpp
1 #ifndef BOOST_LAMBDA2_LAMBDA2_HPP_INCLUDED
2 #define BOOST_LAMBDA2_LAMBDA2_HPP_INCLUDED
3
4 // Copyright 2020, 2021 Peter Dimov
5 // Distributed under the Boost Software License, Version 1.0.
6 // https://www.boost.org/LICENSE_1_0.txt
7
8 #include <functional>
9 #include <type_traits>
10 #include <utility>
11 #include <tuple>
12 #include <cstddef>
13 #include <iosfwd>
14
15 // Same format as BOOST_VERSION:
16 // major * 100000 + minor * 100 + patch
17 #define BOOST_LAMBDA2_VERSION 107900
18
19 namespace boost
20 {
21 namespace lambda2
22 {
23
24 namespace lambda2_detail
25 {
26
27 struct subscript
28 {
29 template<class T1, class T2> decltype(auto) operator()(T1&& t1, T2&& t2) const
30 {
31 return std::forward<T1>(t1)[ std::forward<T2>(t2) ];
32 }
33 };
34
35 template<int I> struct get
36 {
37 template<class T> decltype(auto) operator()( T&& t ) const
38 {
39 return std::get<I>( std::forward<T>(t) );
40 }
41 };
42
43 } // namespace lambda2_detail
44
45 // placeholders
46
47 template<int I> struct lambda2_arg
48 {
49 template<class... A> decltype(auto) operator()( A&&... a ) const noexcept
50 {
51 return std::get<std::size_t{I-1}>( std::tuple<A&&...>( std::forward<A>(a)... ) );
52 }
53
54 template<class T> auto operator[]( T&& t ) const
55 {
56 return std::bind( lambda2_detail::subscript(), *this, std::forward<T>( t ) );
57 }
58 };
59
60 #if defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L
61 # define BOOST_LAMBDA2_INLINE_VAR inline
62 #else
63 # define BOOST_LAMBDA2_INLINE_VAR
64 #endif
65
66 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<1> _1{};
67 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<2> _2{};
68 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<3> _3{};
69 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<4> _4{};
70 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<5> _5{};
71 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<6> _6{};
72 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<7> _7{};
73 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<8> _8{};
74 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<9> _9{};
75
76 // first, second
77
78 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_detail::get<0> first{};
79 BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_detail::get<1> second{};
80
81 #undef BOOST_LAMBDA2_INLINE_VAR
82
83 } // namespace lambda2
84 } // namespace boost
85
86 namespace std
87 {
88
89 template<int I> struct is_placeholder< boost::lambda2::lambda2_arg<I> >: integral_constant<int, I>
90 {
91 };
92
93 } // namespace std
94
95 namespace boost
96 {
97 namespace lambda2
98 {
99
100 namespace lambda2_detail
101 {
102
103 // additional function objects
104
105 #define BOOST_LAMBDA2_UNARY_FN(op, fn) \
106 struct fn \
107 { \
108 template<class T> decltype(auto) operator()(T&& t) const \
109 { \
110 return op std::forward<T>(t); \
111 } \
112 };
113
114 #define BOOST_LAMBDA2_POSTFIX_FN(op, fn) \
115 struct fn \
116 { \
117 template<class T> decltype(auto) operator()(T&& t) const \
118 { \
119 return std::forward<T>(t) op; \
120 } \
121 };
122
123 #define BOOST_LAMBDA2_BINARY_FN(op, fn) \
124 struct fn \
125 { \
126 template<class T1, class T2> decltype(auto) operator()(T1&& t1, T2&& t2) const \
127 { \
128 return std::forward<T1>(t1) op std::forward<T2>(t2); \
129 } \
130 };
131
132 BOOST_LAMBDA2_BINARY_FN(<<, left_shift)
133 BOOST_LAMBDA2_BINARY_FN(>>, right_shift)
134
135 BOOST_LAMBDA2_UNARY_FN(+, unary_plus)
136 BOOST_LAMBDA2_UNARY_FN(*, dereference)
137
138 BOOST_LAMBDA2_UNARY_FN(++, increment)
139 BOOST_LAMBDA2_UNARY_FN(--, decrement)
140
141 BOOST_LAMBDA2_POSTFIX_FN(++, postfix_increment)
142 BOOST_LAMBDA2_POSTFIX_FN(--, postfix_decrement)
143
144 BOOST_LAMBDA2_BINARY_FN(+=, plus_equal)
145 BOOST_LAMBDA2_BINARY_FN(-=, minus_equal)
146 BOOST_LAMBDA2_BINARY_FN(*=, multiplies_equal)
147 BOOST_LAMBDA2_BINARY_FN(/=, divides_equal)
148 BOOST_LAMBDA2_BINARY_FN(%=, modulus_equal)
149 BOOST_LAMBDA2_BINARY_FN(&=, bit_and_equal)
150 BOOST_LAMBDA2_BINARY_FN(|=, bit_or_equal)
151 BOOST_LAMBDA2_BINARY_FN(^=, bit_xor_equal)
152 BOOST_LAMBDA2_BINARY_FN(<<=, left_shift_equal)
153 BOOST_LAMBDA2_BINARY_FN(>>=, right_shift_equal)
154
155 // operators
156
157 template<class T> using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
158
159 template<class T, class T2 = remove_cvref_t<T>> using is_lambda_expression =
160 std::integral_constant<bool, std::is_placeholder<T2>::value || std::is_bind_expression<T2>::value>;
161
162 template<class A> using enable_unary_lambda =
163 std::enable_if_t<is_lambda_expression<A>::value>;
164
165 template<class A, class B> using enable_binary_lambda =
166 std::enable_if_t<is_lambda_expression<A>::value || is_lambda_expression<B>::value>;
167
168 template<class T> using is_stream = std::is_base_of<std::ios_base, remove_cvref_t<T>>;
169
170 } // namespace lambda2_detail
171
172 #define BOOST_LAMBDA2_UNARY_LAMBDA(op, fn) \
173 template<class A, class = lambda2_detail::enable_unary_lambda<A>> \
174 auto operator op( A&& a ) \
175 { \
176 return std::bind( fn(), std::forward<A>(a) ); \
177 }
178
179 #define BOOST_LAMBDA2_POSTFIX_LAMBDA(op, fn) \
180 template<class A, class = lambda2_detail::enable_unary_lambda<A>> \
181 auto operator op( A&& a, int ) \
182 { \
183 return std::bind( fn(), std::forward<A>(a) ); \
184 }
185
186 #define BOOST_LAMBDA2_BINARY_LAMBDA(op, fn) \
187 template<class A, class B, class = lambda2_detail::enable_binary_lambda<A, B>> \
188 auto operator op( A&& a, B&& b ) \
189 { \
190 return std::bind( fn(), std::forward<A>(a), std::forward<B>(b) ); \
191 }
192
193 // standard
194
195 BOOST_LAMBDA2_BINARY_LAMBDA(+, std::plus<>)
196 BOOST_LAMBDA2_BINARY_LAMBDA(-, std::minus<>)
197 BOOST_LAMBDA2_BINARY_LAMBDA(*, std::multiplies<>)
198 BOOST_LAMBDA2_BINARY_LAMBDA(/, std::divides<>)
199 BOOST_LAMBDA2_BINARY_LAMBDA(%, std::modulus<>)
200 BOOST_LAMBDA2_UNARY_LAMBDA(-, std::negate<>)
201
202 BOOST_LAMBDA2_BINARY_LAMBDA(==, std::equal_to<>)
203 BOOST_LAMBDA2_BINARY_LAMBDA(!=, std::not_equal_to<>)
204 BOOST_LAMBDA2_BINARY_LAMBDA(>, std::greater<>)
205 BOOST_LAMBDA2_BINARY_LAMBDA(<, std::less<>)
206 BOOST_LAMBDA2_BINARY_LAMBDA(>=, std::greater_equal<>)
207 BOOST_LAMBDA2_BINARY_LAMBDA(<=, std::less_equal<>)
208
209 BOOST_LAMBDA2_BINARY_LAMBDA(&&, std::logical_and<>)
210 BOOST_LAMBDA2_BINARY_LAMBDA(||, std::logical_or<>)
211 BOOST_LAMBDA2_UNARY_LAMBDA(!, std::logical_not<>)
212
213 BOOST_LAMBDA2_BINARY_LAMBDA(&, std::bit_and<>)
214 BOOST_LAMBDA2_BINARY_LAMBDA(|, std::bit_or<>)
215 BOOST_LAMBDA2_BINARY_LAMBDA(^, std::bit_xor<>)
216 BOOST_LAMBDA2_UNARY_LAMBDA(~, std::bit_not<>)
217
218 // additional
219
220 BOOST_LAMBDA2_UNARY_LAMBDA(+, lambda2_detail::unary_plus)
221 BOOST_LAMBDA2_UNARY_LAMBDA(*, lambda2_detail::dereference)
222
223 BOOST_LAMBDA2_UNARY_LAMBDA(++, lambda2_detail::increment)
224 BOOST_LAMBDA2_UNARY_LAMBDA(--, lambda2_detail::decrement)
225
226 BOOST_LAMBDA2_POSTFIX_LAMBDA(++, lambda2_detail::postfix_increment)
227 BOOST_LAMBDA2_POSTFIX_LAMBDA(--, lambda2_detail::postfix_decrement)
228
229 // compound assignment
230
231 BOOST_LAMBDA2_BINARY_LAMBDA(+=, lambda2_detail::plus_equal)
232 BOOST_LAMBDA2_BINARY_LAMBDA(-=, lambda2_detail::minus_equal)
233 BOOST_LAMBDA2_BINARY_LAMBDA(*=, lambda2_detail::multiplies_equal)
234 BOOST_LAMBDA2_BINARY_LAMBDA(/=, lambda2_detail::divides_equal)
235 BOOST_LAMBDA2_BINARY_LAMBDA(%=, lambda2_detail::modulus_equal)
236 BOOST_LAMBDA2_BINARY_LAMBDA(&=, lambda2_detail::bit_and_equal)
237 BOOST_LAMBDA2_BINARY_LAMBDA(|=, lambda2_detail::bit_or_equal)
238 BOOST_LAMBDA2_BINARY_LAMBDA(^=, lambda2_detail::bit_xor_equal)
239 BOOST_LAMBDA2_BINARY_LAMBDA(<<=, lambda2_detail::left_shift_equal)
240 BOOST_LAMBDA2_BINARY_LAMBDA(>>=, lambda2_detail::right_shift_equal)
241
242 // operator<<
243
244 template<class A, class = std::enable_if_t<!lambda2_detail::is_stream<A>::value>,
245 class B, class = lambda2_detail::enable_binary_lambda<A, B>>
246 auto operator<<( A&& a, B&& b )
247 {
248 return std::bind( lambda2_detail::left_shift(), std::forward<A>(a), std::forward<B>(b) );
249 }
250
251 template<class A, class = std::enable_if_t<lambda2_detail::is_stream<A>::value>,
252 class B, class = lambda2_detail::enable_unary_lambda<B>>
253 auto operator<<( A& a, B&& b )
254 {
255 return std::bind( lambda2_detail::left_shift(), std::ref(a), std::forward<B>(b) );
256 }
257
258 // operator>>
259
260 template<class A, class = std::enable_if_t<!lambda2_detail::is_stream<A>::value>,
261 class B, class = lambda2_detail::enable_binary_lambda<A, B>>
262 auto operator>>( A&& a, B&& b )
263 {
264 return std::bind( lambda2_detail::right_shift(), std::forward<A>(a), std::forward<B>(b) );
265 }
266
267 template<class A, class = std::enable_if_t<lambda2_detail::is_stream<A>::value>,
268 class B, class = lambda2_detail::enable_unary_lambda<B>>
269 auto operator>>( A& a, B&& b )
270 {
271 return std::bind( lambda2_detail::right_shift(), std::ref(a), std::forward<B>(b) );
272 }
273
274 // operator->*
275
276 template<class A, class B, class = lambda2_detail::enable_unary_lambda<A>>
277 auto operator->*( A&& a, B&& b )
278 {
279 return std::bind( std::forward<B>(b), std::forward<A>(a) );
280 }
281
282 } // namespace lambda2
283 } // namespace boost
284
285 #endif // #ifndef BOOST_LAMBDA2_LAMBDA2_HPP_INCLUDED