1 | // <functional> -*- C++ -*- |
2 | |
3 | // Copyright (C) 2001-2024 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
10 | |
11 | // This library is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version |
18 | // 3.1, as published by the Free Software Foundation. |
19 | |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 | // <http://www.gnu.org/licenses/>. |
24 | |
25 | /* |
26 | * Copyright (c) 1997 |
27 | * Silicon Graphics Computer Systems, Inc. |
28 | * |
29 | * Permission to use, copy, modify, distribute and sell this software |
30 | * and its documentation for any purpose is hereby granted without fee, |
31 | * provided that the above copyright notice appear in all copies and |
32 | * that both that copyright notice and this permission notice appear |
33 | * in supporting documentation. Silicon Graphics makes no |
34 | * representations about the suitability of this software for any |
35 | * purpose. It is provided "as is" without express or implied warranty. |
36 | * |
37 | */ |
38 | |
39 | /** @file include/functional |
40 | * This is a Standard C++ Library header. |
41 | */ |
42 | |
43 | #ifndef _GLIBCXX_FUNCTIONAL |
44 | #define _GLIBCXX_FUNCTIONAL 1 |
45 | |
46 | #pragma GCC system_header |
47 | |
48 | #include <bits/c++config.h> |
49 | #include <bits/stl_function.h> // std::equal_to, std::unary_function etc. |
50 | |
51 | #if __cplusplus >= 201103L |
52 | |
53 | #include <tuple> |
54 | #include <type_traits> |
55 | #include <bits/functional_hash.h> |
56 | #include <bits/invoke.h> |
57 | #include <bits/refwrap.h> // std::reference_wrapper and _Mem_fn_traits |
58 | #if _GLIBCXX_HOSTED |
59 | # include <bits/std_function.h> // std::function |
60 | #endif |
61 | #if __cplusplus >= 201703L |
62 | # if _GLIBCXX_HOSTED |
63 | # include <unordered_map> |
64 | # include <vector> |
65 | # include <array> |
66 | # endif |
67 | # include <bits/stl_algobase.h> // std::search |
68 | #endif |
69 | #if __cplusplus >= 202002L |
70 | # include <bits/ranges_cmp.h> // std::identity, ranges::equal_to etc. |
71 | # include <compare> |
72 | #endif |
73 | #if __cplusplus > 202002L && _GLIBCXX_HOSTED |
74 | # include <bits/move_only_function.h> |
75 | #endif |
76 | |
77 | #define __glibcxx_want_boyer_moore_searcher |
78 | #define __glibcxx_want_bind_front |
79 | #define __glibcxx_want_bind_back |
80 | #define __glibcxx_want_constexpr_functional |
81 | #define __glibcxx_want_invoke |
82 | #define __glibcxx_want_invoke_r |
83 | #define __glibcxx_want_move_only_function |
84 | #define __glibcxx_want_not_fn |
85 | #define __glibcxx_want_ranges |
86 | #define __glibcxx_want_reference_wrapper |
87 | #define __glibcxx_want_transparent_operators |
88 | #include <bits/version.h> |
89 | |
90 | #endif // C++11 |
91 | |
92 | namespace std _GLIBCXX_VISIBILITY(default) |
93 | { |
94 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
95 | |
96 | /** @brief The type of placeholder objects defined by libstdc++. |
97 | * @ingroup binders |
98 | * @since C++11 |
99 | */ |
100 | template<int _Num> struct _Placeholder { }; |
101 | |
102 | #ifdef __cpp_lib_invoke // C++ >= 17 |
103 | |
104 | /** Invoke a callable object. |
105 | * |
106 | * `std::invoke` takes a callable object as its first argument and calls it |
107 | * with the remaining arguments. The callable object can be a pointer or |
108 | * reference to a function, a lambda closure, a class with `operator()`, |
109 | * or even a pointer-to-member. For a pointer-to-member the first argument |
110 | * must be a reference or pointer to the object that the pointer-to-member |
111 | * will be applied to. |
112 | * |
113 | * @since C++17 |
114 | */ |
115 | template<typename _Callable, typename... _Args> |
116 | inline _GLIBCXX20_CONSTEXPR invoke_result_t<_Callable, _Args...> |
117 | invoke(_Callable&& __fn, _Args&&... __args) |
118 | noexcept(is_nothrow_invocable_v<_Callable, _Args...>) |
119 | { |
120 | return std::__invoke(std::forward<_Callable>(__fn), |
121 | std::forward<_Args>(__args)...); |
122 | } |
123 | #endif |
124 | |
125 | #ifdef __cpp_lib_invoke_r // C++ >= 23 |
126 | |
127 | /** Invoke a callable object and convert the result to `_Res`. |
128 | * |
129 | * `std::invoke_r<R>(f, args...)` is equivalent to `std::invoke(f, args...)` |
130 | * with the result implicitly converted to `R`. |
131 | * |
132 | * @since C++23 |
133 | */ |
134 | template<typename _Res, typename _Callable, typename... _Args> |
135 | requires is_invocable_r_v<_Res, _Callable, _Args...> |
136 | constexpr _Res |
137 | invoke_r(_Callable&& __fn, _Args&&... __args) |
138 | noexcept(is_nothrow_invocable_r_v<_Res, _Callable, _Args...>) |
139 | { |
140 | return std::__invoke_r<_Res>(std::forward<_Callable>(__fn), |
141 | std::forward<_Args>(__args)...); |
142 | } |
143 | #endif // __cpp_lib_invoke_r |
144 | |
145 | /// @cond undocumented |
146 | |
147 | #if __cplusplus >= 201103L |
148 | template<typename _MemFunPtr, |
149 | bool __is_mem_fn = is_member_function_pointer<_MemFunPtr>::value> |
150 | class _Mem_fn_base |
151 | : public _Mem_fn_traits<_MemFunPtr>::__maybe_type |
152 | { |
153 | using _Traits = _Mem_fn_traits<_MemFunPtr>; |
154 | |
155 | using _Arity = typename _Traits::__arity; |
156 | using _Varargs = typename _Traits::__vararg; |
157 | |
158 | template<typename _Func, typename... _BoundArgs> |
159 | friend struct _Bind_check_arity; |
160 | |
161 | _MemFunPtr _M_pmf; |
162 | |
163 | public: |
164 | |
165 | using result_type = typename _Traits::__result_type; |
166 | |
167 | explicit constexpr |
168 | _Mem_fn_base(_MemFunPtr __pmf) noexcept : _M_pmf(__pmf) { } |
169 | |
170 | template<typename... _Args> |
171 | _GLIBCXX20_CONSTEXPR |
172 | auto |
173 | operator()(_Args&&... __args) const |
174 | noexcept(noexcept( |
175 | std::__invoke(_M_pmf, std::forward<_Args>(__args)...))) |
176 | -> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...)) |
177 | { return std::__invoke(_M_pmf, std::forward<_Args>(__args)...); } |
178 | }; |
179 | |
180 | // Partial specialization for member object pointers. |
181 | template<typename _MemObjPtr> |
182 | class _Mem_fn_base<_MemObjPtr, false> |
183 | { |
184 | using _Arity = integral_constant<size_t, 0>; |
185 | using _Varargs = false_type; |
186 | |
187 | template<typename _Func, typename... _BoundArgs> |
188 | friend struct _Bind_check_arity; |
189 | |
190 | _MemObjPtr _M_pm; |
191 | |
192 | public: |
193 | explicit constexpr |
194 | _Mem_fn_base(_MemObjPtr __pm) noexcept : _M_pm(__pm) { } |
195 | |
196 | template<typename _Tp> |
197 | _GLIBCXX20_CONSTEXPR |
198 | auto |
199 | operator()(_Tp&& __obj) const |
200 | noexcept(noexcept(std::__invoke(_M_pm, std::forward<_Tp>(__obj)))) |
201 | -> decltype(std::__invoke(_M_pm, std::forward<_Tp>(__obj))) |
202 | { return std::__invoke(_M_pm, std::forward<_Tp>(__obj)); } |
203 | }; |
204 | |
205 | template<typename _MemberPointer> |
206 | struct _Mem_fn; // undefined |
207 | |
208 | template<typename _Res, typename _Class> |
209 | struct _Mem_fn<_Res _Class::*> |
210 | : _Mem_fn_base<_Res _Class::*> |
211 | { |
212 | using _Mem_fn_base<_Res _Class::*>::_Mem_fn_base; |
213 | }; |
214 | /// @endcond |
215 | |
216 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
217 | // 2048. Unnecessary mem_fn overloads |
218 | /** |
219 | * @brief Returns a function object that forwards to the member pointer |
220 | * pointer `pm`. |
221 | * |
222 | * This allows a pointer-to-member to be transformed into a function object |
223 | * that can be called with an object expression as its first argument. |
224 | * |
225 | * For a pointer-to-data-member the result must be called with exactly one |
226 | * argument, the object expression that would be used as the first operand |
227 | * in a `obj.*memptr` or `objp->*memptr` expression. |
228 | * |
229 | * For a pointer-to-member-function the result must be called with an object |
230 | * expression and any additional arguments to pass to the member function, |
231 | * as in an expression like `(obj.*memfun)(args...)` or |
232 | * `(objp->*memfun)(args...)`. |
233 | * |
234 | * The object expression can be a pointer, reference, `reference_wrapper`, |
235 | * or smart pointer, and the call wrapper will dereference it as needed |
236 | * to apply the pointer-to-member. |
237 | * |
238 | * @ingroup functors |
239 | * @since C++11 |
240 | */ |
241 | template<typename _Tp, typename _Class> |
242 | _GLIBCXX20_CONSTEXPR |
243 | inline _Mem_fn<_Tp _Class::*> |
244 | mem_fn(_Tp _Class::* __pm) noexcept |
245 | { |
246 | return _Mem_fn<_Tp _Class::*>(__pm); |
247 | } |
248 | |
249 | /** |
250 | * @brief Trait that identifies a bind expression. |
251 | * |
252 | * Determines if the given type `_Tp` is a function object that |
253 | * should be treated as a subexpression when evaluating calls to |
254 | * function objects returned by `std::bind`. |
255 | * |
256 | * C++11 [func.bind.isbind]. |
257 | * @ingroup binders |
258 | * @since C++11 |
259 | */ |
260 | template<typename _Tp> |
261 | struct is_bind_expression |
262 | : public false_type { }; |
263 | |
264 | /** |
265 | * @brief Determines if the given type _Tp is a placeholder in a |
266 | * bind() expression and, if so, which placeholder it is. |
267 | * |
268 | * C++11 [func.bind.isplace]. |
269 | * @ingroup binders |
270 | * @since C++11 |
271 | */ |
272 | template<typename _Tp> |
273 | struct is_placeholder |
274 | : public integral_constant<int, 0> |
275 | { }; |
276 | |
277 | #if __cplusplus > 201402L |
278 | template <typename _Tp> inline constexpr bool is_bind_expression_v |
279 | = is_bind_expression<_Tp>::value; |
280 | template <typename _Tp> inline constexpr int is_placeholder_v |
281 | = is_placeholder<_Tp>::value; |
282 | #endif // C++17 |
283 | |
284 | /** @namespace std::placeholders |
285 | * @brief ISO C++ 2011 namespace for std::bind placeholders. |
286 | * @ingroup binders |
287 | * @since C++11 |
288 | */ |
289 | namespace placeholders |
290 | { |
291 | /* Define a large number of placeholders. There is no way to |
292 | * simplify this with variadic templates, because we're introducing |
293 | * unique names for each. |
294 | */ |
295 | #if __cpp_inline_variables |
296 | # define _GLIBCXX_PLACEHOLDER inline |
297 | #else |
298 | # define _GLIBCXX_PLACEHOLDER extern |
299 | #endif |
300 | |
301 | _GLIBCXX_PLACEHOLDER const _Placeholder<1> _1; |
302 | _GLIBCXX_PLACEHOLDER const _Placeholder<2> _2; |
303 | _GLIBCXX_PLACEHOLDER const _Placeholder<3> _3; |
304 | _GLIBCXX_PLACEHOLDER const _Placeholder<4> _4; |
305 | _GLIBCXX_PLACEHOLDER const _Placeholder<5> _5; |
306 | _GLIBCXX_PLACEHOLDER const _Placeholder<6> _6; |
307 | _GLIBCXX_PLACEHOLDER const _Placeholder<7> _7; |
308 | _GLIBCXX_PLACEHOLDER const _Placeholder<8> _8; |
309 | _GLIBCXX_PLACEHOLDER const _Placeholder<9> _9; |
310 | _GLIBCXX_PLACEHOLDER const _Placeholder<10> _10; |
311 | _GLIBCXX_PLACEHOLDER const _Placeholder<11> _11; |
312 | _GLIBCXX_PLACEHOLDER const _Placeholder<12> _12; |
313 | _GLIBCXX_PLACEHOLDER const _Placeholder<13> _13; |
314 | _GLIBCXX_PLACEHOLDER const _Placeholder<14> _14; |
315 | _GLIBCXX_PLACEHOLDER const _Placeholder<15> _15; |
316 | _GLIBCXX_PLACEHOLDER const _Placeholder<16> _16; |
317 | _GLIBCXX_PLACEHOLDER const _Placeholder<17> _17; |
318 | _GLIBCXX_PLACEHOLDER const _Placeholder<18> _18; |
319 | _GLIBCXX_PLACEHOLDER const _Placeholder<19> _19; |
320 | _GLIBCXX_PLACEHOLDER const _Placeholder<20> _20; |
321 | _GLIBCXX_PLACEHOLDER const _Placeholder<21> _21; |
322 | _GLIBCXX_PLACEHOLDER const _Placeholder<22> _22; |
323 | _GLIBCXX_PLACEHOLDER const _Placeholder<23> _23; |
324 | _GLIBCXX_PLACEHOLDER const _Placeholder<24> _24; |
325 | _GLIBCXX_PLACEHOLDER const _Placeholder<25> _25; |
326 | _GLIBCXX_PLACEHOLDER const _Placeholder<26> _26; |
327 | _GLIBCXX_PLACEHOLDER const _Placeholder<27> _27; |
328 | _GLIBCXX_PLACEHOLDER const _Placeholder<28> _28; |
329 | _GLIBCXX_PLACEHOLDER const _Placeholder<29> _29; |
330 | |
331 | #undef _GLIBCXX_PLACEHOLDER |
332 | } |
333 | |
334 | /** |
335 | * Partial specialization of is_placeholder that provides the placeholder |
336 | * number for the placeholder objects defined by libstdc++. |
337 | * @ingroup binders |
338 | * @since C++11 |
339 | */ |
340 | template<int _Num> |
341 | struct is_placeholder<_Placeholder<_Num> > |
342 | : public integral_constant<int, _Num> |
343 | { }; |
344 | |
345 | template<int _Num> |
346 | struct is_placeholder<const _Placeholder<_Num> > |
347 | : public integral_constant<int, _Num> |
348 | { }; |
349 | |
350 | /// @cond undocumented |
351 | |
352 | // Like tuple_element_t but SFINAE-friendly. |
353 | template<std::size_t __i, typename _Tuple> |
354 | using _Safe_tuple_element_t |
355 | = typename enable_if<(__i < tuple_size<_Tuple>::value), |
356 | tuple_element<__i, _Tuple>>::type::type; |
357 | |
358 | /** |
359 | * Maps an argument to bind() into an actual argument to the bound |
360 | * function object [func.bind.bind]/10. Only the first parameter should |
361 | * be specified: the rest are used to determine among the various |
362 | * implementations. Note that, although this class is a function |
363 | * object, it isn't entirely normal because it takes only two |
364 | * parameters regardless of the number of parameters passed to the |
365 | * bind expression. The first parameter is the bound argument and |
366 | * the second parameter is a tuple containing references to the |
367 | * rest of the arguments. |
368 | */ |
369 | template<typename _Arg, |
370 | bool _IsBindExp = is_bind_expression<_Arg>::value, |
371 | bool _IsPlaceholder = (is_placeholder<_Arg>::value > 0)> |
372 | class _Mu; |
373 | |
374 | /** |
375 | * If the argument is reference_wrapper<_Tp>, returns the |
376 | * underlying reference. |
377 | * C++11 [func.bind.bind] p10 bullet 1. |
378 | */ |
379 | template<typename _Tp> |
380 | class _Mu<reference_wrapper<_Tp>, false, false> |
381 | { |
382 | public: |
383 | /* Note: This won't actually work for const volatile |
384 | * reference_wrappers, because reference_wrapper::get() is const |
385 | * but not volatile-qualified. This might be a defect in the TR. |
386 | */ |
387 | template<typename _CVRef, typename _Tuple> |
388 | _GLIBCXX20_CONSTEXPR |
389 | _Tp& |
390 | operator()(_CVRef& __arg, _Tuple&) const volatile |
391 | { return __arg.get(); } |
392 | }; |
393 | |
394 | /** |
395 | * If the argument is a bind expression, we invoke the underlying |
396 | * function object with the same cv-qualifiers as we are given and |
397 | * pass along all of our arguments (unwrapped). |
398 | * C++11 [func.bind.bind] p10 bullet 2. |
399 | */ |
400 | template<typename _Arg> |
401 | class _Mu<_Arg, true, false> |
402 | { |
403 | public: |
404 | template<typename _CVArg, typename... _Args> |
405 | _GLIBCXX20_CONSTEXPR |
406 | auto |
407 | operator()(_CVArg& __arg, |
408 | tuple<_Args...>& __tuple) const volatile |
409 | -> decltype(__arg(declval<_Args>()...)) |
410 | { |
411 | // Construct an index tuple and forward to __call |
412 | typedef typename _Build_index_tuple<sizeof...(_Args)>::__type |
413 | _Indexes; |
414 | return this->__call(__arg, __tuple, _Indexes()); |
415 | } |
416 | |
417 | private: |
418 | // Invokes the underlying function object __arg by unpacking all |
419 | // of the arguments in the tuple. |
420 | template<typename _CVArg, typename... _Args, std::size_t... _Indexes> |
421 | _GLIBCXX20_CONSTEXPR |
422 | auto |
423 | __call(_CVArg& __arg, tuple<_Args...>& __tuple, |
424 | const _Index_tuple<_Indexes...>&) const volatile |
425 | -> decltype(__arg(declval<_Args>()...)) |
426 | { |
427 | return __arg(std::get<_Indexes>(std::move(__tuple))...); |
428 | } |
429 | }; |
430 | |
431 | /** |
432 | * If the argument is a placeholder for the Nth argument, returns |
433 | * a reference to the Nth argument to the bind function object. |
434 | * C++11 [func.bind.bind] p10 bullet 3. |
435 | */ |
436 | template<typename _Arg> |
437 | class _Mu<_Arg, false, true> |
438 | { |
439 | public: |
440 | template<typename _Tuple> |
441 | _GLIBCXX20_CONSTEXPR |
442 | _Safe_tuple_element_t<(is_placeholder<_Arg>::value - 1), _Tuple>&& |
443 | operator()(const volatile _Arg&, _Tuple& __tuple) const volatile |
444 | { |
445 | return |
446 | ::std::get<(is_placeholder<_Arg>::value - 1)>(std::move(__tuple)); |
447 | } |
448 | }; |
449 | |
450 | /** |
451 | * If the argument is just a value, returns a reference to that |
452 | * value. The cv-qualifiers on the reference are determined by the caller. |
453 | * C++11 [func.bind.bind] p10 bullet 4. |
454 | */ |
455 | template<typename _Arg> |
456 | class _Mu<_Arg, false, false> |
457 | { |
458 | public: |
459 | template<typename _CVArg, typename _Tuple> |
460 | _GLIBCXX20_CONSTEXPR |
461 | _CVArg&& |
462 | operator()(_CVArg&& __arg, _Tuple&) const volatile |
463 | { return std::forward<_CVArg>(__arg); } |
464 | }; |
465 | |
466 | // std::get<I> for volatile-qualified tuples |
467 | template<std::size_t _Ind, typename... _Tp> |
468 | inline auto |
469 | __volget(volatile tuple<_Tp...>& __tuple) |
470 | -> __tuple_element_t<_Ind, tuple<_Tp...>> volatile& |
471 | { return std::get<_Ind>(const_cast<tuple<_Tp...>&>(__tuple)); } |
472 | |
473 | // std::get<I> for const-volatile-qualified tuples |
474 | template<std::size_t _Ind, typename... _Tp> |
475 | inline auto |
476 | __volget(const volatile tuple<_Tp...>& __tuple) |
477 | -> __tuple_element_t<_Ind, tuple<_Tp...>> const volatile& |
478 | { return std::get<_Ind>(const_cast<const tuple<_Tp...>&>(__tuple)); } |
479 | |
480 | /// @endcond |
481 | |
482 | #if __cplusplus == 201703L && _GLIBCXX_USE_DEPRECATED |
483 | # define _GLIBCXX_VOLATILE_BIND |
484 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
485 | // 2487. bind() should be const-overloaded, not cv-overloaded |
486 | # define _GLIBCXX_DEPR_BIND \ |
487 | [[deprecated("std::bind does not support volatile in C++17")]] |
488 | #elif __cplusplus < 201703L |
489 | # define _GLIBCXX_VOLATILE_BIND |
490 | # define _GLIBCXX_DEPR_BIND |
491 | #endif |
492 | |
493 | /// Type of the function object returned from bind(). |
494 | template<typename _Signature> |
495 | class _Bind; |
496 | |
497 | template<typename _Functor, typename... _Bound_args> |
498 | class _Bind<_Functor(_Bound_args...)> |
499 | : public _Weak_result_type<_Functor> |
500 | { |
501 | typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type |
502 | _Bound_indexes; |
503 | |
504 | _Functor _M_f; |
505 | tuple<_Bound_args...> _M_bound_args; |
506 | |
507 | // Call unqualified |
508 | template<typename _Result, typename... _Args, std::size_t... _Indexes> |
509 | _GLIBCXX20_CONSTEXPR |
510 | _Result |
511 | __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) |
512 | { |
513 | return std::__invoke(_M_f, |
514 | _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)... |
515 | ); |
516 | } |
517 | |
518 | // Call as const |
519 | template<typename _Result, typename... _Args, std::size_t... _Indexes> |
520 | _GLIBCXX20_CONSTEXPR |
521 | _Result |
522 | __call_c(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const |
523 | { |
524 | return std::__invoke(_M_f, |
525 | _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)... |
526 | ); |
527 | } |
528 | |
529 | #ifdef _GLIBCXX_VOLATILE_BIND |
530 | // Call as volatile |
531 | template<typename _Result, typename... _Args, std::size_t... _Indexes> |
532 | _Result |
533 | __call_v(tuple<_Args...>&& __args, |
534 | _Index_tuple<_Indexes...>) volatile |
535 | { |
536 | return std::__invoke(_M_f, |
537 | _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)... |
538 | ); |
539 | } |
540 | |
541 | // Call as const volatile |
542 | template<typename _Result, typename... _Args, std::size_t... _Indexes> |
543 | _Result |
544 | __call_c_v(tuple<_Args...>&& __args, |
545 | _Index_tuple<_Indexes...>) const volatile |
546 | { |
547 | return std::__invoke(_M_f, |
548 | _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)... |
549 | ); |
550 | } |
551 | #endif // volatile |
552 | |
553 | template<typename _BoundArg, typename _CallArgs> |
554 | using _Mu_type = decltype( |
555 | _Mu<typename remove_cv<_BoundArg>::type>()( |
556 | std::declval<_BoundArg&>(), std::declval<_CallArgs&>()) ); |
557 | |
558 | template<typename _Fn, typename _CallArgs, typename... _BArgs> |
559 | using _Res_type_impl |
560 | = __invoke_result_t<_Fn&, _Mu_type<_BArgs, _CallArgs>&&...>; |
561 | |
562 | template<typename _CallArgs> |
563 | using _Res_type = _Res_type_impl<_Functor, _CallArgs, _Bound_args...>; |
564 | |
565 | template<typename _CallArgs> |
566 | using __dependent = typename |
567 | enable_if<bool(tuple_size<_CallArgs>::value+1), _Functor>::type; |
568 | |
569 | template<typename _CallArgs, template<class> class __cv_quals> |
570 | using _Res_type_cv = _Res_type_impl< |
571 | typename __cv_quals<__dependent<_CallArgs>>::type, |
572 | _CallArgs, |
573 | typename __cv_quals<_Bound_args>::type...>; |
574 | |
575 | public: |
576 | template<typename... _Args> |
577 | explicit _GLIBCXX20_CONSTEXPR |
578 | _Bind(const _Functor& __f, _Args&&... __args) |
579 | : _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...) |
580 | { } |
581 | |
582 | template<typename... _Args> |
583 | explicit _GLIBCXX20_CONSTEXPR |
584 | _Bind(_Functor&& __f, _Args&&... __args) |
585 | : _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...) |
586 | { } |
587 | |
588 | _Bind(const _Bind&) = default; |
589 | _Bind(_Bind&&) = default; |
590 | |
591 | // Call unqualified |
592 | template<typename... _Args, |
593 | typename _Result = _Res_type<tuple<_Args...>>> |
594 | _GLIBCXX20_CONSTEXPR |
595 | _Result |
596 | operator()(_Args&&... __args) |
597 | { |
598 | return this->__call<_Result>( |
599 | std::forward_as_tuple(std::forward<_Args>(__args)...), |
600 | _Bound_indexes()); |
601 | } |
602 | |
603 | // Call as const |
604 | template<typename... _Args, |
605 | typename _Result = _Res_type_cv<tuple<_Args...>, add_const>> |
606 | _GLIBCXX20_CONSTEXPR |
607 | _Result |
608 | operator()(_Args&&... __args) const |
609 | { |
610 | return this->__call_c<_Result>( |
611 | std::forward_as_tuple(std::forward<_Args>(__args)...), |
612 | _Bound_indexes()); |
613 | } |
614 | |
615 | #ifdef _GLIBCXX_VOLATILE_BIND |
616 | // Call as volatile |
617 | template<typename... _Args, |
618 | typename _Result = _Res_type_cv<tuple<_Args...>, add_volatile>> |
619 | _GLIBCXX_DEPR_BIND |
620 | _Result |
621 | operator()(_Args&&... __args) volatile |
622 | { |
623 | return this->__call_v<_Result>( |
624 | std::forward_as_tuple(std::forward<_Args>(__args)...), |
625 | _Bound_indexes()); |
626 | } |
627 | |
628 | // Call as const volatile |
629 | template<typename... _Args, |
630 | typename _Result = _Res_type_cv<tuple<_Args...>, add_cv>> |
631 | _GLIBCXX_DEPR_BIND |
632 | _Result |
633 | operator()(_Args&&... __args) const volatile |
634 | { |
635 | return this->__call_c_v<_Result>( |
636 | std::forward_as_tuple(std::forward<_Args>(__args)...), |
637 | _Bound_indexes()); |
638 | } |
639 | #endif // volatile |
640 | }; |
641 | |
642 | /// Type of the function object returned from bind<R>(). |
643 | template<typename _Result, typename _Signature> |
644 | class _Bind_result; |
645 | |
646 | template<typename _Result, typename _Functor, typename... _Bound_args> |
647 | class _Bind_result<_Result, _Functor(_Bound_args...)> |
648 | { |
649 | typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type |
650 | _Bound_indexes; |
651 | |
652 | _Functor _M_f; |
653 | tuple<_Bound_args...> _M_bound_args; |
654 | |
655 | // Call unqualified |
656 | template<typename _Res, typename... _Args, std::size_t... _Indexes> |
657 | _GLIBCXX20_CONSTEXPR |
658 | _Res |
659 | __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) |
660 | { |
661 | return std::__invoke_r<_Res>(_M_f, _Mu<_Bound_args>() |
662 | (std::get<_Indexes>(_M_bound_args), __args)...); |
663 | } |
664 | |
665 | // Call as const |
666 | template<typename _Res, typename... _Args, std::size_t... _Indexes> |
667 | _GLIBCXX20_CONSTEXPR |
668 | _Res |
669 | __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const |
670 | { |
671 | return std::__invoke_r<_Res>(_M_f, _Mu<_Bound_args>() |
672 | (std::get<_Indexes>(_M_bound_args), __args)...); |
673 | } |
674 | |
675 | #ifdef _GLIBCXX_VOLATILE_BIND |
676 | // Call as volatile |
677 | template<typename _Res, typename... _Args, std::size_t... _Indexes> |
678 | _Res |
679 | __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile |
680 | { |
681 | return std::__invoke_r<_Res>(_M_f, _Mu<_Bound_args>() |
682 | (__volget<_Indexes>(_M_bound_args), __args)...); |
683 | } |
684 | |
685 | // Call as const volatile |
686 | template<typename _Res, typename... _Args, std::size_t... _Indexes> |
687 | _Res |
688 | __call(tuple<_Args...>&& __args, |
689 | _Index_tuple<_Indexes...>) const volatile |
690 | { |
691 | return std::__invoke_r<_Res>(_M_f, _Mu<_Bound_args>() |
692 | (__volget<_Indexes>(_M_bound_args), __args)...); |
693 | } |
694 | #endif // volatile |
695 | |
696 | public: |
697 | typedef _Result result_type; |
698 | |
699 | template<typename... _Args> |
700 | explicit _GLIBCXX20_CONSTEXPR |
701 | _Bind_result(const _Functor& __f, _Args&&... __args) |
702 | : _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...) |
703 | { } |
704 | |
705 | template<typename... _Args> |
706 | explicit _GLIBCXX20_CONSTEXPR |
707 | _Bind_result(_Functor&& __f, _Args&&... __args) |
708 | : _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...) |
709 | { } |
710 | |
711 | _Bind_result(const _Bind_result&) = default; |
712 | _Bind_result(_Bind_result&&) = default; |
713 | |
714 | // Call unqualified |
715 | template<typename... _Args> |
716 | _GLIBCXX20_CONSTEXPR |
717 | result_type |
718 | operator()(_Args&&... __args) |
719 | { |
720 | return this->__call<_Result>( |
721 | std::forward_as_tuple(std::forward<_Args>(__args)...), |
722 | _Bound_indexes()); |
723 | } |
724 | |
725 | // Call as const |
726 | template<typename... _Args> |
727 | _GLIBCXX20_CONSTEXPR |
728 | result_type |
729 | operator()(_Args&&... __args) const |
730 | { |
731 | return this->__call<_Result>( |
732 | std::forward_as_tuple(std::forward<_Args>(__args)...), |
733 | _Bound_indexes()); |
734 | } |
735 | |
736 | #ifdef _GLIBCXX_VOLATILE_BIND |
737 | // Call as volatile |
738 | template<typename... _Args> |
739 | _GLIBCXX_DEPR_BIND |
740 | result_type |
741 | operator()(_Args&&... __args) volatile |
742 | { |
743 | return this->__call<_Result>( |
744 | std::forward_as_tuple(std::forward<_Args>(__args)...), |
745 | _Bound_indexes()); |
746 | } |
747 | |
748 | // Call as const volatile |
749 | template<typename... _Args> |
750 | _GLIBCXX_DEPR_BIND |
751 | result_type |
752 | operator()(_Args&&... __args) const volatile |
753 | { |
754 | return this->__call<_Result>( |
755 | std::forward_as_tuple(std::forward<_Args>(__args)...), |
756 | _Bound_indexes()); |
757 | } |
758 | #else |
759 | template<typename... _Args> |
760 | void operator()(_Args&&...) const volatile = delete; |
761 | #endif // volatile |
762 | }; |
763 | |
764 | #undef _GLIBCXX_VOLATILE_BIND |
765 | #undef _GLIBCXX_DEPR_BIND |
766 | |
767 | /** |
768 | * @brief Class template _Bind is always a bind expression. |
769 | * @ingroup binders |
770 | */ |
771 | template<typename _Signature> |
772 | struct is_bind_expression<_Bind<_Signature> > |
773 | : public true_type { }; |
774 | |
775 | /** |
776 | * @brief Class template _Bind is always a bind expression. |
777 | * @ingroup binders |
778 | */ |
779 | template<typename _Signature> |
780 | struct is_bind_expression<const _Bind<_Signature> > |
781 | : public true_type { }; |
782 | |
783 | /** |
784 | * @brief Class template _Bind is always a bind expression. |
785 | * @ingroup binders |
786 | */ |
787 | template<typename _Signature> |
788 | struct is_bind_expression<volatile _Bind<_Signature> > |
789 | : public true_type { }; |
790 | |
791 | /** |
792 | * @brief Class template _Bind is always a bind expression. |
793 | * @ingroup binders |
794 | */ |
795 | template<typename _Signature> |
796 | struct is_bind_expression<const volatile _Bind<_Signature>> |
797 | : public true_type { }; |
798 | |
799 | /** |
800 | * @brief Class template _Bind_result is always a bind expression. |
801 | * @ingroup binders |
802 | */ |
803 | template<typename _Result, typename _Signature> |
804 | struct is_bind_expression<_Bind_result<_Result, _Signature>> |
805 | : public true_type { }; |
806 | |
807 | /** |
808 | * @brief Class template _Bind_result is always a bind expression. |
809 | * @ingroup binders |
810 | */ |
811 | template<typename _Result, typename _Signature> |
812 | struct is_bind_expression<const _Bind_result<_Result, _Signature>> |
813 | : public true_type { }; |
814 | |
815 | /** |
816 | * @brief Class template _Bind_result is always a bind expression. |
817 | * @ingroup binders |
818 | */ |
819 | template<typename _Result, typename _Signature> |
820 | struct is_bind_expression<volatile _Bind_result<_Result, _Signature>> |
821 | : public true_type { }; |
822 | |
823 | /** |
824 | * @brief Class template _Bind_result is always a bind expression. |
825 | * @ingroup binders |
826 | */ |
827 | template<typename _Result, typename _Signature> |
828 | struct is_bind_expression<const volatile _Bind_result<_Result, _Signature>> |
829 | : public true_type { }; |
830 | |
831 | template<typename _Func, typename... _BoundArgs> |
832 | struct _Bind_check_arity { }; |
833 | |
834 | template<typename _Ret, typename... _Args, typename... _BoundArgs> |
835 | struct _Bind_check_arity<_Ret (*)(_Args...), _BoundArgs...> |
836 | { |
837 | static_assert(sizeof...(_BoundArgs) == sizeof...(_Args), |
838 | "Wrong number of arguments for function" ); |
839 | }; |
840 | |
841 | template<typename _Ret, typename... _Args, typename... _BoundArgs> |
842 | struct _Bind_check_arity<_Ret (*)(_Args......), _BoundArgs...> |
843 | { |
844 | static_assert(sizeof...(_BoundArgs) >= sizeof...(_Args), |
845 | "Wrong number of arguments for function" ); |
846 | }; |
847 | |
848 | template<typename _Tp, typename _Class, typename... _BoundArgs> |
849 | struct _Bind_check_arity<_Tp _Class::*, _BoundArgs...> |
850 | { |
851 | using _Arity = typename _Mem_fn<_Tp _Class::*>::_Arity; |
852 | using _Varargs = typename _Mem_fn<_Tp _Class::*>::_Varargs; |
853 | static_assert(_Varargs::value |
854 | ? sizeof...(_BoundArgs) >= _Arity::value + 1 |
855 | : sizeof...(_BoundArgs) == _Arity::value + 1, |
856 | "Wrong number of arguments for pointer-to-member" ); |
857 | }; |
858 | |
859 | // Trait type used to remove std::bind() from overload set via SFINAE |
860 | // when first argument has integer type, so that std::bind() will |
861 | // not be a better match than ::bind() from the BSD Sockets API. |
862 | template<typename _Tp, typename _Tp2 = typename decay<_Tp>::type> |
863 | using __is_socketlike = __or_<is_integral<_Tp2>, is_enum<_Tp2>>; |
864 | |
865 | template<bool _SocketLike, typename _Func, typename... _BoundArgs> |
866 | struct _Bind_helper |
867 | : _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...> |
868 | { |
869 | typedef typename decay<_Func>::type __func_type; |
870 | typedef _Bind<__func_type(typename decay<_BoundArgs>::type...)> type; |
871 | }; |
872 | |
873 | // Partial specialization for is_socketlike == true, does not define |
874 | // nested type so std::bind() will not participate in overload resolution |
875 | // when the first argument might be a socket file descriptor. |
876 | template<typename _Func, typename... _BoundArgs> |
877 | struct _Bind_helper<true, _Func, _BoundArgs...> |
878 | { }; |
879 | |
880 | /** |
881 | * @brief Function template for std::bind. |
882 | * @ingroup binders |
883 | * @since C++11 |
884 | */ |
885 | template<typename _Func, typename... _BoundArgs> |
886 | inline _GLIBCXX20_CONSTEXPR typename |
887 | _Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type |
888 | bind(_Func&& __f, _BoundArgs&&... __args) |
889 | { |
890 | typedef _Bind_helper<false, _Func, _BoundArgs...> __helper_type; |
891 | return typename __helper_type::type(std::forward<_Func>(__f), |
892 | std::forward<_BoundArgs>(__args)...); |
893 | } |
894 | |
895 | template<typename _Result, typename _Func, typename... _BoundArgs> |
896 | struct _Bindres_helper |
897 | : _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...> |
898 | { |
899 | typedef typename decay<_Func>::type __functor_type; |
900 | typedef _Bind_result<_Result, |
901 | __functor_type(typename decay<_BoundArgs>::type...)> |
902 | type; |
903 | }; |
904 | |
905 | /** |
906 | * @brief Function template for std::bind<R>. |
907 | * @ingroup binders |
908 | * @since C++11 |
909 | */ |
910 | template<typename _Result, typename _Func, typename... _BoundArgs> |
911 | inline _GLIBCXX20_CONSTEXPR |
912 | typename _Bindres_helper<_Result, _Func, _BoundArgs...>::type |
913 | bind(_Func&& __f, _BoundArgs&&... __args) |
914 | { |
915 | typedef _Bindres_helper<_Result, _Func, _BoundArgs...> __helper_type; |
916 | return typename __helper_type::type(std::forward<_Func>(__f), |
917 | std::forward<_BoundArgs>(__args)...); |
918 | } |
919 | |
920 | #ifdef __cpp_lib_bind_front // C++ >= 20 |
921 | |
922 | template<typename _Fd, typename... _BoundArgs> |
923 | struct _Bind_front |
924 | { |
925 | static_assert(is_move_constructible_v<_Fd>); |
926 | static_assert((is_move_constructible_v<_BoundArgs> && ...)); |
927 | |
928 | // First parameter is to ensure this constructor is never used |
929 | // instead of the copy/move constructor. |
930 | template<typename _Fn, typename... _Args> |
931 | explicit constexpr |
932 | _Bind_front(int, _Fn&& __fn, _Args&&... __args) |
933 | noexcept(__and_<is_nothrow_constructible<_Fd, _Fn>, |
934 | is_nothrow_constructible<_BoundArgs, _Args>...>::value) |
935 | : _M_fd(std::forward<_Fn>(__fn)), |
936 | _M_bound_args(std::forward<_Args>(__args)...) |
937 | { static_assert(sizeof...(_Args) == sizeof...(_BoundArgs)); } |
938 | |
939 | #if __cpp_explicit_this_parameter |
940 | template<typename _Self, typename... _CallArgs> |
941 | constexpr |
942 | invoke_result_t<__like_t<_Self, _Fd>, __like_t<_Self, _BoundArgs>..., _CallArgs...> |
943 | operator()(this _Self&& __self, _CallArgs&&... __call_args) |
944 | noexcept(is_nothrow_invocable_v<__like_t<_Self, _Fd>, |
945 | __like_t<_Self, _BoundArgs>..., _CallArgs...>) |
946 | { |
947 | return _S_call(__like_t<_Self, _Bind_front>(__self), _BoundIndices(), |
948 | std::forward<_CallArgs>(__call_args)...); |
949 | } |
950 | #else |
951 | template<typename... _CallArgs> |
952 | requires true |
953 | constexpr |
954 | invoke_result_t<_Fd&, _BoundArgs&..., _CallArgs...> |
955 | operator()(_CallArgs&&... __call_args) & |
956 | noexcept(is_nothrow_invocable_v<_Fd&, _BoundArgs&..., _CallArgs...>) |
957 | { |
958 | return _S_call(*this, _BoundIndices(), |
959 | std::forward<_CallArgs>(__call_args)...); |
960 | } |
961 | |
962 | template<typename... _CallArgs> |
963 | requires true |
964 | constexpr |
965 | invoke_result_t<const _Fd&, const _BoundArgs&..., _CallArgs...> |
966 | operator()(_CallArgs&&... __call_args) const & |
967 | noexcept(is_nothrow_invocable_v<const _Fd&, const _BoundArgs&..., |
968 | _CallArgs...>) |
969 | { |
970 | return _S_call(*this, _BoundIndices(), |
971 | std::forward<_CallArgs>(__call_args)...); |
972 | } |
973 | |
974 | template<typename... _CallArgs> |
975 | requires true |
976 | constexpr |
977 | invoke_result_t<_Fd, _BoundArgs..., _CallArgs...> |
978 | operator()(_CallArgs&&... __call_args) && |
979 | noexcept(is_nothrow_invocable_v<_Fd, _BoundArgs..., _CallArgs...>) |
980 | { |
981 | return _S_call(std::move(*this), _BoundIndices(), |
982 | std::forward<_CallArgs>(__call_args)...); |
983 | } |
984 | |
985 | template<typename... _CallArgs> |
986 | requires true |
987 | constexpr |
988 | invoke_result_t<const _Fd, const _BoundArgs..., _CallArgs...> |
989 | operator()(_CallArgs&&... __call_args) const && |
990 | noexcept(is_nothrow_invocable_v<const _Fd, const _BoundArgs..., |
991 | _CallArgs...>) |
992 | { |
993 | return _S_call(std::move(*this), _BoundIndices(), |
994 | std::forward<_CallArgs>(__call_args)...); |
995 | } |
996 | |
997 | template<typename... _CallArgs> |
998 | void operator()(_CallArgs&&...) & = delete; |
999 | |
1000 | template<typename... _CallArgs> |
1001 | void operator()(_CallArgs&&...) const & = delete; |
1002 | |
1003 | template<typename... _CallArgs> |
1004 | void operator()(_CallArgs&&...) && = delete; |
1005 | |
1006 | template<typename... _CallArgs> |
1007 | void operator()(_CallArgs&&...) const && = delete; |
1008 | #endif |
1009 | |
1010 | private: |
1011 | using _BoundIndices = index_sequence_for<_BoundArgs...>; |
1012 | |
1013 | template<typename _Tp, size_t... _Ind, typename... _CallArgs> |
1014 | static constexpr |
1015 | decltype(auto) |
1016 | _S_call(_Tp&& __g, index_sequence<_Ind...>, _CallArgs&&... __call_args) |
1017 | { |
1018 | return std::invoke(std::forward<_Tp>(__g)._M_fd, |
1019 | std::get<_Ind>(std::forward<_Tp>(__g)._M_bound_args)..., |
1020 | std::forward<_CallArgs>(__call_args)...); |
1021 | } |
1022 | |
1023 | [[no_unique_address]] _Fd _M_fd; |
1024 | [[no_unique_address]] std::tuple<_BoundArgs...> _M_bound_args; |
1025 | }; |
1026 | |
1027 | template<typename _Fn, typename... _Args> |
1028 | using _Bind_front_t = _Bind_front<decay_t<_Fn>, decay_t<_Args>...>; |
1029 | |
1030 | /** Create call wrapper by partial application of arguments to function. |
1031 | * |
1032 | * The result of `std::bind_front(f, args...)` is a function object that |
1033 | * stores `f` and the bound arguments, `args...`. When that function |
1034 | * object is invoked with `call_args...` it returns the result of calling |
1035 | * `f(args..., call_args...)`. |
1036 | * |
1037 | * @since C++20 |
1038 | */ |
1039 | template<typename _Fn, typename... _Args> |
1040 | constexpr _Bind_front_t<_Fn, _Args...> |
1041 | bind_front(_Fn&& __fn, _Args&&... __args) |
1042 | noexcept(is_nothrow_constructible_v<_Bind_front_t<_Fn, _Args...>, |
1043 | int, _Fn, _Args...>) |
1044 | { |
1045 | return _Bind_front_t<_Fn, _Args...>(0, std::forward<_Fn>(__fn), |
1046 | std::forward<_Args>(__args)...); |
1047 | } |
1048 | #endif // __cpp_lib_bind_front |
1049 | |
1050 | #ifdef __cpp_lib_bind_back // C++ >= 23 |
1051 | template<typename _Fd, typename... _BoundArgs> |
1052 | struct _Bind_back |
1053 | { |
1054 | static_assert(is_move_constructible_v<_Fd>); |
1055 | static_assert((is_move_constructible_v<_BoundArgs> && ...)); |
1056 | |
1057 | // First parameter is to ensure this constructor is never used |
1058 | // instead of the copy/move constructor. |
1059 | template<typename _Fn, typename... _Args> |
1060 | explicit constexpr |
1061 | _Bind_back(int, _Fn&& __fn, _Args&&... __args) |
1062 | noexcept(__and_<is_nothrow_constructible<_Fd, _Fn>, |
1063 | is_nothrow_constructible<_BoundArgs, _Args>...>::value) |
1064 | : _M_fd(std::forward<_Fn>(__fn)), |
1065 | _M_bound_args(std::forward<_Args>(__args)...) |
1066 | { static_assert(sizeof...(_Args) == sizeof...(_BoundArgs)); } |
1067 | |
1068 | template<typename _Self, typename... _CallArgs> |
1069 | constexpr |
1070 | invoke_result_t<__like_t<_Self, _Fd>, _CallArgs..., __like_t<_Self, _BoundArgs>...> |
1071 | operator()(this _Self&& __self, _CallArgs&&... __call_args) |
1072 | noexcept(is_nothrow_invocable_v<__like_t<_Self, _Fd>, |
1073 | _CallArgs..., __like_t<_Self, _BoundArgs>...>) |
1074 | { |
1075 | return _S_call(__like_t<_Self, _Bind_back>(__self), _BoundIndices(), |
1076 | std::forward<_CallArgs>(__call_args)...); |
1077 | } |
1078 | |
1079 | private: |
1080 | using _BoundIndices = index_sequence_for<_BoundArgs...>; |
1081 | |
1082 | template<typename _Tp, size_t... _Ind, typename... _CallArgs> |
1083 | static constexpr |
1084 | decltype(auto) |
1085 | _S_call(_Tp&& __g, index_sequence<_Ind...>, _CallArgs&&... __call_args) |
1086 | { |
1087 | return std::invoke(std::forward<_Tp>(__g)._M_fd, |
1088 | std::forward<_CallArgs>(__call_args)..., |
1089 | std::get<_Ind>(std::forward<_Tp>(__g)._M_bound_args)...); |
1090 | } |
1091 | |
1092 | [[no_unique_address]] _Fd _M_fd; |
1093 | [[no_unique_address]] std::tuple<_BoundArgs...> _M_bound_args; |
1094 | }; |
1095 | |
1096 | template<typename _Fn, typename... _Args> |
1097 | using _Bind_back_t = _Bind_back<decay_t<_Fn>, decay_t<_Args>...>; |
1098 | |
1099 | /** Create call wrapper by partial application of arguments to function. |
1100 | * |
1101 | * The result of `std::bind_back(f, args...)` is a function object that |
1102 | * stores `f` and the bound arguments, `args...`. When that function |
1103 | * object is invoked with `call_args...` it returns the result of calling |
1104 | * `f(call_args..., args...)`. |
1105 | * |
1106 | * @since C++23 |
1107 | */ |
1108 | template<typename _Fn, typename... _Args> |
1109 | constexpr _Bind_back_t<_Fn, _Args...> |
1110 | bind_back(_Fn&& __fn, _Args&&... __args) |
1111 | noexcept(is_nothrow_constructible_v<_Bind_back_t<_Fn, _Args...>, |
1112 | int, _Fn, _Args...>) |
1113 | { |
1114 | return _Bind_back_t<_Fn, _Args...>(0, std::forward<_Fn>(__fn), |
1115 | std::forward<_Args>(__args)...); |
1116 | } |
1117 | #endif // __cpp_lib_bind_back |
1118 | |
1119 | #if __cplusplus >= 201402L |
1120 | /// Generalized negator. |
1121 | template<typename _Fn> |
1122 | class _Not_fn |
1123 | { |
1124 | template<typename _Fn2, typename... _Args> |
1125 | using __inv_res_t = typename __invoke_result<_Fn2, _Args...>::type; |
1126 | |
1127 | template<typename _Tp> |
1128 | static decltype(!std::declval<_Tp>()) |
1129 | _S_not() noexcept(noexcept(!std::declval<_Tp>())); |
1130 | |
1131 | public: |
1132 | template<typename _Fn2> |
1133 | constexpr |
1134 | _Not_fn(_Fn2&& __fn, int) |
1135 | : _M_fn(std::forward<_Fn2>(__fn)) { } |
1136 | |
1137 | _Not_fn(const _Not_fn& __fn) = default; |
1138 | _Not_fn(_Not_fn&& __fn) = default; |
1139 | ~_Not_fn() = default; |
1140 | |
1141 | // Macro to define operator() with given cv-qualifiers ref-qualifiers, |
1142 | // forwarding _M_fn and the function arguments with the same qualifiers, |
1143 | // and deducing the return type and exception-specification. |
1144 | #define _GLIBCXX_NOT_FN_CALL_OP( _QUALS ) \ |
1145 | template<typename... _Args, \ |
1146 | typename = enable_if_t<__is_invocable<_Fn _QUALS, _Args...>::value>> \ |
1147 | _GLIBCXX20_CONSTEXPR \ |
1148 | decltype(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>()) \ |
1149 | operator()(_Args&&... __args) _QUALS \ |
1150 | noexcept(__is_nothrow_invocable<_Fn _QUALS, _Args...>::value \ |
1151 | && noexcept(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>())) \ |
1152 | { \ |
1153 | return !std::__invoke(std::forward< _Fn _QUALS >(_M_fn), \ |
1154 | std::forward<_Args>(__args)...); \ |
1155 | } \ |
1156 | \ |
1157 | template<typename... _Args, \ |
1158 | typename = enable_if_t<!__is_invocable<_Fn _QUALS, _Args...>::value>> \ |
1159 | void operator()(_Args&&... __args) _QUALS = delete; |
1160 | |
1161 | _GLIBCXX_NOT_FN_CALL_OP( & ) |
1162 | _GLIBCXX_NOT_FN_CALL_OP( const & ) |
1163 | _GLIBCXX_NOT_FN_CALL_OP( && ) |
1164 | _GLIBCXX_NOT_FN_CALL_OP( const && ) |
1165 | #undef _GLIBCXX_NOT_FN_CALL_OP |
1166 | |
1167 | private: |
1168 | _Fn _M_fn; |
1169 | }; |
1170 | |
1171 | template<typename _Tp, typename _Pred> |
1172 | struct __is_byte_like : false_type { }; |
1173 | |
1174 | template<typename _Tp> |
1175 | struct __is_byte_like<_Tp, equal_to<_Tp>> |
1176 | : __bool_constant<sizeof(_Tp) == 1 && is_integral<_Tp>::value> { }; |
1177 | |
1178 | template<typename _Tp> |
1179 | struct __is_byte_like<_Tp, equal_to<void>> |
1180 | : __bool_constant<sizeof(_Tp) == 1 && is_integral<_Tp>::value> { }; |
1181 | |
1182 | #if __cplusplus >= 201703L |
1183 | // Declare std::byte (full definition is in <cstddef>). |
1184 | enum class byte : unsigned char; |
1185 | |
1186 | template<> |
1187 | struct __is_byte_like<byte, equal_to<byte>> |
1188 | : true_type { }; |
1189 | |
1190 | template<> |
1191 | struct __is_byte_like<byte, equal_to<void>> |
1192 | : true_type { }; |
1193 | #endif |
1194 | |
1195 | // [func.not_fn] Function template not_fn |
1196 | #ifdef __cpp_lib_not_fn // C++ >= 17 |
1197 | /** Wrap a function object to create one that negates its result. |
1198 | * |
1199 | * The function template `std::not_fn` creates a "forwarding call wrapper", |
1200 | * which is a function object that wraps another function object and |
1201 | * when called, forwards its arguments to the wrapped function object. |
1202 | * |
1203 | * The result of invoking the wrapper is the negation (using `!`) of |
1204 | * the wrapped function object. |
1205 | * |
1206 | * @ingroup functors |
1207 | * @since C++17 |
1208 | */ |
1209 | template<typename _Fn> |
1210 | _GLIBCXX20_CONSTEXPR |
1211 | inline auto |
1212 | not_fn(_Fn&& __fn) |
1213 | noexcept(std::is_nothrow_constructible<std::decay_t<_Fn>, _Fn&&>::value) |
1214 | { |
1215 | return _Not_fn<std::decay_t<_Fn>>{std::forward<_Fn>(__fn), 0}; |
1216 | } |
1217 | #endif |
1218 | |
1219 | #if __cplusplus >= 201703L |
1220 | // Searchers |
1221 | |
1222 | template<typename _ForwardIterator1, typename _BinaryPredicate = equal_to<>> |
1223 | class default_searcher |
1224 | { |
1225 | public: |
1226 | _GLIBCXX20_CONSTEXPR |
1227 | default_searcher(_ForwardIterator1 __pat_first, |
1228 | _ForwardIterator1 __pat_last, |
1229 | _BinaryPredicate __pred = _BinaryPredicate()) |
1230 | : _M_m(__pat_first, __pat_last, std::move(__pred)) |
1231 | { } |
1232 | |
1233 | template<typename _ForwardIterator2> |
1234 | _GLIBCXX20_CONSTEXPR |
1235 | pair<_ForwardIterator2, _ForwardIterator2> |
1236 | operator()(_ForwardIterator2 __first, _ForwardIterator2 __last) const |
1237 | { |
1238 | _ForwardIterator2 __first_ret = |
1239 | std::search(__first, __last, std::get<0>(_M_m), std::get<1>(_M_m), |
1240 | std::get<2>(_M_m)); |
1241 | auto __ret = std::make_pair(__first_ret, __first_ret); |
1242 | if (__ret.first != __last) |
1243 | std::advance(__ret.second, std::distance(std::get<0>(_M_m), |
1244 | std::get<1>(_M_m))); |
1245 | return __ret; |
1246 | } |
1247 | |
1248 | private: |
1249 | tuple<_ForwardIterator1, _ForwardIterator1, _BinaryPredicate> _M_m; |
1250 | }; |
1251 | |
1252 | #ifdef __cpp_lib_boyer_moore_searcher // C++ >= 17 && HOSTED |
1253 | |
1254 | template<typename _Key, typename _Tp, typename _Hash, typename _Pred> |
1255 | struct __boyer_moore_map_base |
1256 | { |
1257 | template<typename _RAIter> |
1258 | __boyer_moore_map_base(_RAIter __pat, size_t __patlen, |
1259 | _Hash&& __hf, _Pred&& __pred) |
1260 | : _M_bad_char{ __patlen, std::move(__hf), std::move(__pred) } |
1261 | { |
1262 | if (__patlen > 0) |
1263 | for (__diff_type __i = 0; __i < __patlen - 1; ++__i) |
1264 | _M_bad_char[__pat[__i]] = __patlen - 1 - __i; |
1265 | } |
1266 | |
1267 | using __diff_type = _Tp; |
1268 | |
1269 | __diff_type |
1270 | _M_lookup(_Key __key, __diff_type __not_found) const |
1271 | { |
1272 | auto __iter = _M_bad_char.find(__key); |
1273 | if (__iter == _M_bad_char.end()) |
1274 | return __not_found; |
1275 | return __iter->second; |
1276 | } |
1277 | |
1278 | _Pred |
1279 | _M_pred() const { return _M_bad_char.key_eq(); } |
1280 | |
1281 | _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred> _M_bad_char; |
1282 | }; |
1283 | |
1284 | template<typename _Tp, size_t _Len, typename _Pred> |
1285 | struct __boyer_moore_array_base |
1286 | { |
1287 | template<typename _RAIter, typename _Unused> |
1288 | __boyer_moore_array_base(_RAIter __pat, size_t __patlen, |
1289 | _Unused&&, _Pred&& __pred) |
1290 | : _M_bad_char{ array<_Tp, _Len>{}, std::move(__pred) } |
1291 | { |
1292 | std::get<0>(_M_bad_char).fill(__patlen); |
1293 | if (__patlen > 0) |
1294 | for (__diff_type __i = 0; __i < __patlen - 1; ++__i) |
1295 | { |
1296 | auto __ch = __pat[__i]; |
1297 | using _UCh = make_unsigned_t<decltype(__ch)>; |
1298 | auto __uch = static_cast<_UCh>(__ch); |
1299 | std::get<0>(_M_bad_char)[__uch] = __patlen - 1 - __i; |
1300 | } |
1301 | } |
1302 | |
1303 | using __diff_type = _Tp; |
1304 | |
1305 | template<typename _Key> |
1306 | __diff_type |
1307 | _M_lookup(_Key __key, __diff_type __not_found) const |
1308 | { |
1309 | auto __ukey = static_cast<make_unsigned_t<_Key>>(__key); |
1310 | if (__ukey >= _Len) |
1311 | return __not_found; |
1312 | return std::get<0>(_M_bad_char)[__ukey]; |
1313 | } |
1314 | |
1315 | const _Pred& |
1316 | _M_pred() const { return std::get<1>(_M_bad_char); } |
1317 | |
1318 | tuple<array<_Tp, _Len>, _Pred> _M_bad_char; |
1319 | }; |
1320 | |
1321 | // Use __boyer_moore_array_base when pattern consists of narrow characters |
1322 | // (or std::byte) and uses std::equal_to as the predicate. |
1323 | template<typename _RAIter, typename _Hash, typename _Pred, |
1324 | typename _Val = typename iterator_traits<_RAIter>::value_type, |
1325 | typename _Diff = typename iterator_traits<_RAIter>::difference_type> |
1326 | using __boyer_moore_base_t |
1327 | = __conditional_t<__is_byte_like<_Val, _Pred>::value, |
1328 | __boyer_moore_array_base<_Diff, 256, _Pred>, |
1329 | __boyer_moore_map_base<_Val, _Diff, _Hash, _Pred>>; |
1330 | |
1331 | template<typename _RAIter, typename _Hash |
1332 | = hash<typename iterator_traits<_RAIter>::value_type>, |
1333 | typename _BinaryPredicate = equal_to<>> |
1334 | class boyer_moore_searcher |
1335 | : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate> |
1336 | { |
1337 | using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>; |
1338 | using typename _Base::__diff_type; |
1339 | |
1340 | public: |
1341 | boyer_moore_searcher(_RAIter __pat_first, _RAIter __pat_last, |
1342 | _Hash __hf = _Hash(), |
1343 | _BinaryPredicate __pred = _BinaryPredicate()); |
1344 | |
1345 | template<typename _RandomAccessIterator2> |
1346 | pair<_RandomAccessIterator2, _RandomAccessIterator2> |
1347 | operator()(_RandomAccessIterator2 __first, |
1348 | _RandomAccessIterator2 __last) const; |
1349 | |
1350 | private: |
1351 | bool |
1352 | _M_is_prefix(_RAIter __word, __diff_type __len, |
1353 | __diff_type __pos) |
1354 | { |
1355 | const auto& __pred = this->_M_pred(); |
1356 | __diff_type __suffixlen = __len - __pos; |
1357 | for (__diff_type __i = 0; __i < __suffixlen; ++__i) |
1358 | if (!__pred(__word[__i], __word[__pos + __i])) |
1359 | return false; |
1360 | return true; |
1361 | } |
1362 | |
1363 | __diff_type |
1364 | _M_suffix_length(_RAIter __word, __diff_type __len, |
1365 | __diff_type __pos) |
1366 | { |
1367 | const auto& __pred = this->_M_pred(); |
1368 | __diff_type __i = 0; |
1369 | while (__pred(__word[__pos - __i], __word[__len - 1 - __i]) |
1370 | && __i < __pos) |
1371 | { |
1372 | ++__i; |
1373 | } |
1374 | return __i; |
1375 | } |
1376 | |
1377 | template<typename _Tp> |
1378 | __diff_type |
1379 | _M_bad_char_shift(_Tp __c) const |
1380 | { return this->_M_lookup(__c, _M_pat_end - _M_pat); } |
1381 | |
1382 | _RAIter _M_pat; |
1383 | _RAIter _M_pat_end; |
1384 | _GLIBCXX_STD_C::vector<__diff_type> _M_good_suffix; |
1385 | }; |
1386 | |
1387 | template<typename _RAIter, typename _Hash |
1388 | = hash<typename iterator_traits<_RAIter>::value_type>, |
1389 | typename _BinaryPredicate = equal_to<>> |
1390 | class boyer_moore_horspool_searcher |
1391 | : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate> |
1392 | { |
1393 | using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>; |
1394 | using typename _Base::__diff_type; |
1395 | |
1396 | public: |
1397 | boyer_moore_horspool_searcher(_RAIter __pat, |
1398 | _RAIter __pat_end, |
1399 | _Hash __hf = _Hash(), |
1400 | _BinaryPredicate __pred |
1401 | = _BinaryPredicate()) |
1402 | : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)), |
1403 | _M_pat(__pat), _M_pat_end(__pat_end) |
1404 | { } |
1405 | |
1406 | template<typename _RandomAccessIterator2> |
1407 | pair<_RandomAccessIterator2, _RandomAccessIterator2> |
1408 | operator()(_RandomAccessIterator2 __first, |
1409 | _RandomAccessIterator2 __last) const |
1410 | { |
1411 | const auto& __pred = this->_M_pred(); |
1412 | auto __patlen = _M_pat_end - _M_pat; |
1413 | if (__patlen == 0) |
1414 | return std::make_pair(__first, __first); |
1415 | auto __len = __last - __first; |
1416 | while (__len >= __patlen) |
1417 | { |
1418 | for (auto __scan = __patlen - 1; |
1419 | __pred(__first[__scan], _M_pat[__scan]); --__scan) |
1420 | if (__scan == 0) |
1421 | return std::make_pair(__first, __first + __patlen); |
1422 | auto __shift = _M_bad_char_shift(__first[__patlen - 1]); |
1423 | __len -= __shift; |
1424 | __first += __shift; |
1425 | } |
1426 | return std::make_pair(__last, __last); |
1427 | } |
1428 | |
1429 | private: |
1430 | template<typename _Tp> |
1431 | __diff_type |
1432 | _M_bad_char_shift(_Tp __c) const |
1433 | { return this->_M_lookup(__c, _M_pat_end - _M_pat); } |
1434 | |
1435 | _RAIter _M_pat; |
1436 | _RAIter _M_pat_end; |
1437 | }; |
1438 | |
1439 | template<typename _RAIter, typename _Hash, typename _BinaryPredicate> |
1440 | boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>:: |
1441 | boyer_moore_searcher(_RAIter __pat, _RAIter __pat_end, |
1442 | _Hash __hf, _BinaryPredicate __pred) |
1443 | : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)), |
1444 | _M_pat(__pat), _M_pat_end(__pat_end), _M_good_suffix(__pat_end - __pat) |
1445 | { |
1446 | auto __patlen = __pat_end - __pat; |
1447 | if (__patlen == 0) |
1448 | return; |
1449 | __diff_type __last_prefix = __patlen - 1; |
1450 | for (__diff_type __p = __patlen - 1; __p >= 0; --__p) |
1451 | { |
1452 | if (_M_is_prefix(word: __pat, len: __patlen, pos: __p + 1)) |
1453 | __last_prefix = __p + 1; |
1454 | _M_good_suffix[__p] = __last_prefix + (__patlen - 1 - __p); |
1455 | } |
1456 | for (__diff_type __p = 0; __p < __patlen - 1; ++__p) |
1457 | { |
1458 | auto __slen = _M_suffix_length(word: __pat, len: __patlen, pos: __p); |
1459 | auto __pos = __patlen - 1 - __slen; |
1460 | if (!__pred(__pat[__p - __slen], __pat[__pos])) |
1461 | _M_good_suffix[__pos] = __patlen - 1 - __p + __slen; |
1462 | } |
1463 | } |
1464 | |
1465 | template<typename _RAIter, typename _Hash, typename _BinaryPredicate> |
1466 | template<typename _RandomAccessIterator2> |
1467 | pair<_RandomAccessIterator2, _RandomAccessIterator2> |
1468 | boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>:: |
1469 | operator()(_RandomAccessIterator2 __first, |
1470 | _RandomAccessIterator2 __last) const |
1471 | { |
1472 | auto __patlen = _M_pat_end - _M_pat; |
1473 | if (__patlen == 0) |
1474 | return std::make_pair(__first, __first); |
1475 | const auto& __pred = this->_M_pred(); |
1476 | __diff_type __i = __patlen - 1; |
1477 | auto __stringlen = __last - __first; |
1478 | while (__i < __stringlen) |
1479 | { |
1480 | __diff_type __j = __patlen - 1; |
1481 | while (__j >= 0 && __pred(__first[__i], _M_pat[__j])) |
1482 | { |
1483 | --__i; |
1484 | --__j; |
1485 | } |
1486 | if (__j < 0) |
1487 | { |
1488 | const auto __match = __first + __i + 1; |
1489 | return std::make_pair(__match, __match + __patlen); |
1490 | } |
1491 | __i += std::max(_M_bad_char_shift(__first[__i]), |
1492 | _M_good_suffix[__j]); |
1493 | } |
1494 | return std::make_pair(__last, __last); |
1495 | } |
1496 | #endif // __cpp_lib_boyer_moore_searcher |
1497 | |
1498 | #endif // C++17 |
1499 | #endif // C++14 |
1500 | #endif // C++11 |
1501 | |
1502 | _GLIBCXX_END_NAMESPACE_VERSION |
1503 | } // namespace std |
1504 | |
1505 | #endif // _GLIBCXX_FUNCTIONAL |
1506 | |