[lld][WebAssembly] Reinstate mistakenly disabled test. NFC
[llvm-project.git] / libcxx / include / __functional / bind.h
blob11a51e5957ee4c9f9289dce2588c7c1e5cc6bb45
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___FUNCTIONAL_BIND_H
11 #define _LIBCPP___FUNCTIONAL_BIND_H
13 #include <__config>
14 #include <__functional/invoke.h>
15 #include <__functional/weak_result_type.h>
16 #include <cstddef>
17 #include <tuple>
18 #include <type_traits>
20 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21 #pragma GCC system_header
22 #endif
24 _LIBCPP_BEGIN_NAMESPACE_STD
26 template<class _Tp>
27 struct is_bind_expression : _If<
28 _IsSame<_Tp, typename __uncvref<_Tp>::type>::value,
29 false_type,
30 is_bind_expression<typename __uncvref<_Tp>::type>
31 > {};
33 #if _LIBCPP_STD_VER > 14
34 template <class _Tp>
35 inline constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value;
36 #endif
38 template<class _Tp>
39 struct is_placeholder : _If<
40 _IsSame<_Tp, typename __uncvref<_Tp>::type>::value,
41 integral_constant<int, 0>,
42 is_placeholder<typename __uncvref<_Tp>::type>
43 > {};
45 #if _LIBCPP_STD_VER > 14
46 template <class _Tp>
47 inline constexpr size_t is_placeholder_v = is_placeholder<_Tp>::value;
48 #endif
50 namespace placeholders
53 template <int _Np> struct __ph {};
55 #if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
56 _LIBCPP_FUNC_VIS extern const __ph<1> _1;
57 _LIBCPP_FUNC_VIS extern const __ph<2> _2;
58 _LIBCPP_FUNC_VIS extern const __ph<3> _3;
59 _LIBCPP_FUNC_VIS extern const __ph<4> _4;
60 _LIBCPP_FUNC_VIS extern const __ph<5> _5;
61 _LIBCPP_FUNC_VIS extern const __ph<6> _6;
62 _LIBCPP_FUNC_VIS extern const __ph<7> _7;
63 _LIBCPP_FUNC_VIS extern const __ph<8> _8;
64 _LIBCPP_FUNC_VIS extern const __ph<9> _9;
65 _LIBCPP_FUNC_VIS extern const __ph<10> _10;
66 #else
67 /* inline */ constexpr __ph<1> _1{};
68 /* inline */ constexpr __ph<2> _2{};
69 /* inline */ constexpr __ph<3> _3{};
70 /* inline */ constexpr __ph<4> _4{};
71 /* inline */ constexpr __ph<5> _5{};
72 /* inline */ constexpr __ph<6> _6{};
73 /* inline */ constexpr __ph<7> _7{};
74 /* inline */ constexpr __ph<8> _8{};
75 /* inline */ constexpr __ph<9> _9{};
76 /* inline */ constexpr __ph<10> _10{};
77 #endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
79 } // namespace placeholders
81 template<int _Np>
82 struct is_placeholder<placeholders::__ph<_Np> >
83 : public integral_constant<int, _Np> {};
86 #ifndef _LIBCPP_CXX03_LANG
88 template <class _Tp, class _Uj>
89 inline _LIBCPP_INLINE_VISIBILITY
90 _Tp&
91 __mu(reference_wrapper<_Tp> __t, _Uj&)
93 return __t.get();
96 template <class _Ti, class ..._Uj, size_t ..._Indx>
97 inline _LIBCPP_INLINE_VISIBILITY
98 typename __invoke_of<_Ti&, _Uj...>::type
99 __mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>)
101 return __ti(_VSTD::forward<_Uj>(_VSTD::get<_Indx>(__uj))...);
104 template <class _Ti, class ..._Uj>
105 inline _LIBCPP_INLINE_VISIBILITY
106 typename __enable_if_t
108 is_bind_expression<_Ti>::value,
109 __invoke_of<_Ti&, _Uj...>
110 >::type
111 __mu(_Ti& __ti, tuple<_Uj...>& __uj)
113 typedef typename __make_tuple_indices<sizeof...(_Uj)>::type __indices;
114 return _VSTD::__mu_expand(__ti, __uj, __indices());
117 template <bool IsPh, class _Ti, class _Uj>
118 struct __mu_return2 {};
120 template <class _Ti, class _Uj>
121 struct __mu_return2<true, _Ti, _Uj>
123 typedef typename tuple_element<is_placeholder<_Ti>::value - 1, _Uj>::type type;
126 template <class _Ti, class _Uj>
127 inline _LIBCPP_INLINE_VISIBILITY
128 typename enable_if
130 0 < is_placeholder<_Ti>::value,
131 typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type
132 >::type
133 __mu(_Ti&, _Uj& __uj)
135 const size_t _Indx = is_placeholder<_Ti>::value - 1;
136 return _VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj));
139 template <class _Ti, class _Uj>
140 inline _LIBCPP_INLINE_VISIBILITY
141 typename enable_if
143 !is_bind_expression<_Ti>::value &&
144 is_placeholder<_Ti>::value == 0 &&
145 !__is_reference_wrapper<_Ti>::value,
146 _Ti&
147 >::type
148 __mu(_Ti& __ti, _Uj&)
150 return __ti;
153 template <class _Ti, bool IsReferenceWrapper, bool IsBindEx, bool IsPh,
154 class _TupleUj>
155 struct __mu_return_impl;
157 template <bool _Invokable, class _Ti, class ..._Uj>
158 struct __mu_return_invokable // false
160 typedef __nat type;
163 template <class _Ti, class ..._Uj>
164 struct __mu_return_invokable<true, _Ti, _Uj...>
166 typedef typename __invoke_of<_Ti&, _Uj...>::type type;
169 template <class _Ti, class ..._Uj>
170 struct __mu_return_impl<_Ti, false, true, false, tuple<_Uj...> >
171 : public __mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...>
175 template <class _Ti, class _TupleUj>
176 struct __mu_return_impl<_Ti, false, false, true, _TupleUj>
178 typedef typename tuple_element<is_placeholder<_Ti>::value - 1,
179 _TupleUj>::type&& type;
182 template <class _Ti, class _TupleUj>
183 struct __mu_return_impl<_Ti, true, false, false, _TupleUj>
185 typedef typename _Ti::type& type;
188 template <class _Ti, class _TupleUj>
189 struct __mu_return_impl<_Ti, false, false, false, _TupleUj>
191 typedef _Ti& type;
194 template <class _Ti, class _TupleUj>
195 struct __mu_return
196 : public __mu_return_impl<_Ti,
197 __is_reference_wrapper<_Ti>::value,
198 is_bind_expression<_Ti>::value,
199 0 < is_placeholder<_Ti>::value &&
200 is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value,
201 _TupleUj>
205 template <class _Fp, class _BoundArgs, class _TupleUj>
206 struct __is_valid_bind_return
208 static const bool value = false;
211 template <class _Fp, class ..._BoundArgs, class _TupleUj>
212 struct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj>
214 static const bool value = __invokable<_Fp,
215 typename __mu_return<_BoundArgs, _TupleUj>::type...>::value;
218 template <class _Fp, class ..._BoundArgs, class _TupleUj>
219 struct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj>
221 static const bool value = __invokable<_Fp,
222 typename __mu_return<const _BoundArgs, _TupleUj>::type...>::value;
225 template <class _Fp, class _BoundArgs, class _TupleUj,
226 bool = __is_valid_bind_return<_Fp, _BoundArgs, _TupleUj>::value>
227 struct __bind_return;
229 template <class _Fp, class ..._BoundArgs, class _TupleUj>
230 struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true>
232 typedef typename __invoke_of
234 _Fp&,
235 typename __mu_return
237 _BoundArgs,
238 _TupleUj
239 >::type...
240 >::type type;
243 template <class _Fp, class ..._BoundArgs, class _TupleUj>
244 struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true>
246 typedef typename __invoke_of
248 _Fp&,
249 typename __mu_return
251 const _BoundArgs,
252 _TupleUj
253 >::type...
254 >::type type;
257 template <class _Fp, class _BoundArgs, size_t ..._Indx, class _Args>
258 inline _LIBCPP_INLINE_VISIBILITY
259 typename __bind_return<_Fp, _BoundArgs, _Args>::type
260 __apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
261 _Args&& __args)
263 return _VSTD::__invoke(__f, _VSTD::__mu(_VSTD::get<_Indx>(__bound_args), __args)...);
266 template<class _Fp, class ..._BoundArgs>
267 class __bind
268 #if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES)
269 : public __weak_result_type<typename decay<_Fp>::type>
270 #endif
272 protected:
273 typedef typename decay<_Fp>::type _Fd;
274 typedef tuple<typename decay<_BoundArgs>::type...> _Td;
275 private:
276 _Fd __f_;
277 _Td __bound_args_;
279 typedef typename __make_tuple_indices<sizeof...(_BoundArgs)>::type __indices;
280 public:
281 template <class _Gp, class ..._BA,
282 class = typename enable_if
284 is_constructible<_Fd, _Gp>::value &&
285 !is_same<typename remove_reference<_Gp>::type,
286 __bind>::value
287 >::type>
288 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
289 explicit __bind(_Gp&& __f, _BA&& ...__bound_args)
290 : __f_(_VSTD::forward<_Gp>(__f)),
291 __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {}
293 template <class ..._Args>
294 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
295 typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type
296 operator()(_Args&& ...__args)
298 return _VSTD::__apply_functor(__f_, __bound_args_, __indices(),
299 tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));
302 template <class ..._Args>
303 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
304 typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type
305 operator()(_Args&& ...__args) const
307 return _VSTD::__apply_functor(__f_, __bound_args_, __indices(),
308 tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));
312 template<class _Fp, class ..._BoundArgs>
313 struct is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {};
315 template<class _Rp, class _Fp, class ..._BoundArgs>
316 class __bind_r
317 : public __bind<_Fp, _BoundArgs...>
319 typedef __bind<_Fp, _BoundArgs...> base;
320 typedef typename base::_Fd _Fd;
321 typedef typename base::_Td _Td;
322 public:
323 typedef _Rp result_type;
326 template <class _Gp, class ..._BA,
327 class = typename enable_if
329 is_constructible<_Fd, _Gp>::value &&
330 !is_same<typename remove_reference<_Gp>::type,
331 __bind_r>::value
332 >::type>
333 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
334 explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args)
335 : base(_VSTD::forward<_Gp>(__f),
336 _VSTD::forward<_BA>(__bound_args)...) {}
338 template <class ..._Args>
339 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
340 typename enable_if
342 is_convertible<typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type,
343 result_type>::value || is_void<_Rp>::value,
344 result_type
345 >::type
346 operator()(_Args&& ...__args)
348 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
349 return _Invoker::__call(static_cast<base&>(*this), _VSTD::forward<_Args>(__args)...);
352 template <class ..._Args>
353 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
354 typename enable_if
356 is_convertible<typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type,
357 result_type>::value || is_void<_Rp>::value,
358 result_type
359 >::type
360 operator()(_Args&& ...__args) const
362 typedef __invoke_void_return_wrapper<_Rp> _Invoker;
363 return _Invoker::__call(static_cast<base const&>(*this), _VSTD::forward<_Args>(__args)...);
367 template<class _Rp, class _Fp, class ..._BoundArgs>
368 struct is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {};
370 template<class _Fp, class ..._BoundArgs>
371 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
372 __bind<_Fp, _BoundArgs...>
373 bind(_Fp&& __f, _BoundArgs&&... __bound_args)
375 typedef __bind<_Fp, _BoundArgs...> type;
376 return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
379 template<class _Rp, class _Fp, class ..._BoundArgs>
380 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
381 __bind_r<_Rp, _Fp, _BoundArgs...>
382 bind(_Fp&& __f, _BoundArgs&&... __bound_args)
384 typedef __bind_r<_Rp, _Fp, _BoundArgs...> type;
385 return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
388 #endif // _LIBCPP_CXX03_LANG
390 _LIBCPP_END_NAMESPACE_STD
392 #endif // _LIBCPP___FUNCTIONAL_BIND_H