invoke.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  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. //===----------------------------------------------------------------------===//
  9. #ifndef _LIBCPP___FUNCTIONAL_INVOKE_H
  10. #define _LIBCPP___FUNCTIONAL_INVOKE_H
  11. #include <__config>
  12. #include <__type_traits/add_lvalue_reference.h>
  13. #include <__type_traits/apply_cv.h>
  14. #include <__type_traits/conditional.h>
  15. #include <__type_traits/decay.h>
  16. #include <__type_traits/enable_if.h>
  17. #include <__type_traits/integral_constant.h>
  18. #include <__type_traits/is_base_of.h>
  19. #include <__type_traits/is_core_convertible.h>
  20. #include <__type_traits/is_member_function_pointer.h>
  21. #include <__type_traits/is_member_object_pointer.h>
  22. #include <__type_traits/is_reference_wrapper.h>
  23. #include <__type_traits/is_same.h>
  24. #include <__type_traits/is_void.h>
  25. #include <__type_traits/remove_cv.h>
  26. #include <__utility/declval.h>
  27. #include <__utility/forward.h>
  28. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  29. # pragma GCC system_header
  30. #endif
  31. // TODO: Disentangle the type traits and std::invoke properly
  32. _LIBCPP_BEGIN_NAMESPACE_STD
  33. struct __any
  34. {
  35. __any(...);
  36. };
  37. struct __nat
  38. {
  39. #ifndef _LIBCPP_CXX03_LANG
  40. __nat() = delete;
  41. __nat(const __nat&) = delete;
  42. __nat& operator=(const __nat&) = delete;
  43. ~__nat() = delete;
  44. #endif
  45. };
  46. template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>
  47. struct __member_pointer_traits_imp
  48. {
  49. };
  50. template <class _Rp, class _Class, class ..._Param>
  51. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false>
  52. {
  53. typedef _Class _ClassType;
  54. typedef _Rp _ReturnType;
  55. typedef _Rp (_FnType) (_Param...);
  56. };
  57. template <class _Rp, class _Class, class ..._Param>
  58. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false>
  59. {
  60. typedef _Class _ClassType;
  61. typedef _Rp _ReturnType;
  62. typedef _Rp (_FnType) (_Param..., ...);
  63. };
  64. template <class _Rp, class _Class, class ..._Param>
  65. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false>
  66. {
  67. typedef _Class const _ClassType;
  68. typedef _Rp _ReturnType;
  69. typedef _Rp (_FnType) (_Param...);
  70. };
  71. template <class _Rp, class _Class, class ..._Param>
  72. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false>
  73. {
  74. typedef _Class const _ClassType;
  75. typedef _Rp _ReturnType;
  76. typedef _Rp (_FnType) (_Param..., ...);
  77. };
  78. template <class _Rp, class _Class, class ..._Param>
  79. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false>
  80. {
  81. typedef _Class volatile _ClassType;
  82. typedef _Rp _ReturnType;
  83. typedef _Rp (_FnType) (_Param...);
  84. };
  85. template <class _Rp, class _Class, class ..._Param>
  86. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false>
  87. {
  88. typedef _Class volatile _ClassType;
  89. typedef _Rp _ReturnType;
  90. typedef _Rp (_FnType) (_Param..., ...);
  91. };
  92. template <class _Rp, class _Class, class ..._Param>
  93. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false>
  94. {
  95. typedef _Class const volatile _ClassType;
  96. typedef _Rp _ReturnType;
  97. typedef _Rp (_FnType) (_Param...);
  98. };
  99. template <class _Rp, class _Class, class ..._Param>
  100. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false>
  101. {
  102. typedef _Class const volatile _ClassType;
  103. typedef _Rp _ReturnType;
  104. typedef _Rp (_FnType) (_Param..., ...);
  105. };
  106. template <class _Rp, class _Class, class ..._Param>
  107. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &, true, false>
  108. {
  109. typedef _Class& _ClassType;
  110. typedef _Rp _ReturnType;
  111. typedef _Rp (_FnType) (_Param...);
  112. };
  113. template <class _Rp, class _Class, class ..._Param>
  114. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &, true, false>
  115. {
  116. typedef _Class& _ClassType;
  117. typedef _Rp _ReturnType;
  118. typedef _Rp (_FnType) (_Param..., ...);
  119. };
  120. template <class _Rp, class _Class, class ..._Param>
  121. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false>
  122. {
  123. typedef _Class const& _ClassType;
  124. typedef _Rp _ReturnType;
  125. typedef _Rp (_FnType) (_Param...);
  126. };
  127. template <class _Rp, class _Class, class ..._Param>
  128. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false>
  129. {
  130. typedef _Class const& _ClassType;
  131. typedef _Rp _ReturnType;
  132. typedef _Rp (_FnType) (_Param..., ...);
  133. };
  134. template <class _Rp, class _Class, class ..._Param>
  135. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false>
  136. {
  137. typedef _Class volatile& _ClassType;
  138. typedef _Rp _ReturnType;
  139. typedef _Rp (_FnType) (_Param...);
  140. };
  141. template <class _Rp, class _Class, class ..._Param>
  142. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false>
  143. {
  144. typedef _Class volatile& _ClassType;
  145. typedef _Rp _ReturnType;
  146. typedef _Rp (_FnType) (_Param..., ...);
  147. };
  148. template <class _Rp, class _Class, class ..._Param>
  149. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false>
  150. {
  151. typedef _Class const volatile& _ClassType;
  152. typedef _Rp _ReturnType;
  153. typedef _Rp (_FnType) (_Param...);
  154. };
  155. template <class _Rp, class _Class, class ..._Param>
  156. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false>
  157. {
  158. typedef _Class const volatile& _ClassType;
  159. typedef _Rp _ReturnType;
  160. typedef _Rp (_FnType) (_Param..., ...);
  161. };
  162. template <class _Rp, class _Class, class ..._Param>
  163. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &&, true, false>
  164. {
  165. typedef _Class&& _ClassType;
  166. typedef _Rp _ReturnType;
  167. typedef _Rp (_FnType) (_Param...);
  168. };
  169. template <class _Rp, class _Class, class ..._Param>
  170. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &&, true, false>
  171. {
  172. typedef _Class&& _ClassType;
  173. typedef _Rp _ReturnType;
  174. typedef _Rp (_FnType) (_Param..., ...);
  175. };
  176. template <class _Rp, class _Class, class ..._Param>
  177. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false>
  178. {
  179. typedef _Class const&& _ClassType;
  180. typedef _Rp _ReturnType;
  181. typedef _Rp (_FnType) (_Param...);
  182. };
  183. template <class _Rp, class _Class, class ..._Param>
  184. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false>
  185. {
  186. typedef _Class const&& _ClassType;
  187. typedef _Rp _ReturnType;
  188. typedef _Rp (_FnType) (_Param..., ...);
  189. };
  190. template <class _Rp, class _Class, class ..._Param>
  191. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false>
  192. {
  193. typedef _Class volatile&& _ClassType;
  194. typedef _Rp _ReturnType;
  195. typedef _Rp (_FnType) (_Param...);
  196. };
  197. template <class _Rp, class _Class, class ..._Param>
  198. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false>
  199. {
  200. typedef _Class volatile&& _ClassType;
  201. typedef _Rp _ReturnType;
  202. typedef _Rp (_FnType) (_Param..., ...);
  203. };
  204. template <class _Rp, class _Class, class ..._Param>
  205. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false>
  206. {
  207. typedef _Class const volatile&& _ClassType;
  208. typedef _Rp _ReturnType;
  209. typedef _Rp (_FnType) (_Param...);
  210. };
  211. template <class _Rp, class _Class, class ..._Param>
  212. struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false>
  213. {
  214. typedef _Class const volatile&& _ClassType;
  215. typedef _Rp _ReturnType;
  216. typedef _Rp (_FnType) (_Param..., ...);
  217. };
  218. template <class _Rp, class _Class>
  219. struct __member_pointer_traits_imp<_Rp _Class::*, false, true>
  220. {
  221. typedef _Class _ClassType;
  222. typedef _Rp _ReturnType;
  223. };
  224. template <class _MP>
  225. struct __member_pointer_traits
  226. : public __member_pointer_traits_imp<typename remove_cv<_MP>::type,
  227. is_member_function_pointer<_MP>::value,
  228. is_member_object_pointer<_MP>::value>
  229. {
  230. // typedef ... _ClassType;
  231. // typedef ... _ReturnType;
  232. // typedef ... _FnType;
  233. };
  234. template <class _DecayedFp>
  235. struct __member_pointer_class_type {};
  236. template <class _Ret, class _ClassType>
  237. struct __member_pointer_class_type<_Ret _ClassType::*> {
  238. typedef _ClassType type;
  239. };
  240. template <class _Fp, class _A0,
  241. class _DecayFp = typename decay<_Fp>::type,
  242. class _DecayA0 = typename decay<_A0>::type,
  243. class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
  244. using __enable_if_bullet1 = typename enable_if
  245. <
  246. is_member_function_pointer<_DecayFp>::value
  247. && is_base_of<_ClassT, _DecayA0>::value
  248. >::type;
  249. template <class _Fp, class _A0,
  250. class _DecayFp = typename decay<_Fp>::type,
  251. class _DecayA0 = typename decay<_A0>::type>
  252. using __enable_if_bullet2 = typename enable_if
  253. <
  254. is_member_function_pointer<_DecayFp>::value
  255. && __is_reference_wrapper<_DecayA0>::value
  256. >::type;
  257. template <class _Fp, class _A0,
  258. class _DecayFp = typename decay<_Fp>::type,
  259. class _DecayA0 = typename decay<_A0>::type,
  260. class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
  261. using __enable_if_bullet3 = typename enable_if
  262. <
  263. is_member_function_pointer<_DecayFp>::value
  264. && !is_base_of<_ClassT, _DecayA0>::value
  265. && !__is_reference_wrapper<_DecayA0>::value
  266. >::type;
  267. template <class _Fp, class _A0,
  268. class _DecayFp = typename decay<_Fp>::type,
  269. class _DecayA0 = typename decay<_A0>::type,
  270. class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
  271. using __enable_if_bullet4 = typename enable_if
  272. <
  273. is_member_object_pointer<_DecayFp>::value
  274. && is_base_of<_ClassT, _DecayA0>::value
  275. >::type;
  276. template <class _Fp, class _A0,
  277. class _DecayFp = typename decay<_Fp>::type,
  278. class _DecayA0 = typename decay<_A0>::type>
  279. using __enable_if_bullet5 = typename enable_if
  280. <
  281. is_member_object_pointer<_DecayFp>::value
  282. && __is_reference_wrapper<_DecayA0>::value
  283. >::type;
  284. template <class _Fp, class _A0,
  285. class _DecayFp = typename decay<_Fp>::type,
  286. class _DecayA0 = typename decay<_A0>::type,
  287. class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
  288. using __enable_if_bullet6 = typename enable_if
  289. <
  290. is_member_object_pointer<_DecayFp>::value
  291. && !is_base_of<_ClassT, _DecayA0>::value
  292. && !__is_reference_wrapper<_DecayA0>::value
  293. >::type;
  294. // __invoke forward declarations
  295. // fall back - none of the bullets
  296. template <class ..._Args>
  297. __nat __invoke(__any, _Args&& ...__args);
  298. // bullets 1, 2 and 3
  299. template <class _Fp, class _A0, class ..._Args,
  300. class = __enable_if_bullet1<_Fp, _A0> >
  301. inline _LIBCPP_INLINE_VISIBILITY
  302. _LIBCPP_CONSTEXPR decltype((std::declval<_A0>().*std::declval<_Fp>())(std::declval<_Args>()...))
  303. __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
  304. _NOEXCEPT_(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...)))
  305. { return (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); }
  306. template <class _Fp, class _A0, class ..._Args,
  307. class = __enable_if_bullet2<_Fp, _A0> >
  308. inline _LIBCPP_INLINE_VISIBILITY
  309. _LIBCPP_CONSTEXPR decltype((std::declval<_A0>().get().*std::declval<_Fp>())(std::declval<_Args>()...))
  310. __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
  311. _NOEXCEPT_(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...)))
  312. { return (__a0.get().*__f)(static_cast<_Args&&>(__args)...); }
  313. template <class _Fp, class _A0, class ..._Args,
  314. class = __enable_if_bullet3<_Fp, _A0> >
  315. inline _LIBCPP_INLINE_VISIBILITY
  316. _LIBCPP_CONSTEXPR decltype(((*std::declval<_A0>()).*std::declval<_Fp>())(std::declval<_Args>()...))
  317. __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
  318. _NOEXCEPT_(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...)))
  319. { return ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); }
  320. // bullets 4, 5 and 6
  321. template <class _Fp, class _A0,
  322. class = __enable_if_bullet4<_Fp, _A0> >
  323. inline _LIBCPP_INLINE_VISIBILITY
  324. _LIBCPP_CONSTEXPR decltype(std::declval<_A0>().*std::declval<_Fp>())
  325. __invoke(_Fp&& __f, _A0&& __a0)
  326. _NOEXCEPT_(noexcept(static_cast<_A0&&>(__a0).*__f))
  327. { return static_cast<_A0&&>(__a0).*__f; }
  328. template <class _Fp, class _A0,
  329. class = __enable_if_bullet5<_Fp, _A0> >
  330. inline _LIBCPP_INLINE_VISIBILITY
  331. _LIBCPP_CONSTEXPR decltype(std::declval<_A0>().get().*std::declval<_Fp>())
  332. __invoke(_Fp&& __f, _A0&& __a0)
  333. _NOEXCEPT_(noexcept(__a0.get().*__f))
  334. { return __a0.get().*__f; }
  335. template <class _Fp, class _A0,
  336. class = __enable_if_bullet6<_Fp, _A0> >
  337. inline _LIBCPP_INLINE_VISIBILITY
  338. _LIBCPP_CONSTEXPR decltype((*std::declval<_A0>()).*std::declval<_Fp>())
  339. __invoke(_Fp&& __f, _A0&& __a0)
  340. _NOEXCEPT_(noexcept((*static_cast<_A0&&>(__a0)).*__f))
  341. { return (*static_cast<_A0&&>(__a0)).*__f; }
  342. // bullet 7
  343. template <class _Fp, class ..._Args>
  344. inline _LIBCPP_INLINE_VISIBILITY
  345. _LIBCPP_CONSTEXPR decltype(std::declval<_Fp>()(std::declval<_Args>()...))
  346. __invoke(_Fp&& __f, _Args&& ...__args)
  347. _NOEXCEPT_(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...)))
  348. { return static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); }
  349. // __invokable
  350. template <class _Ret, class _Fp, class ..._Args>
  351. struct __invokable_r
  352. {
  353. template <class _XFp, class ..._XArgs>
  354. static decltype(std::__invoke(declval<_XFp>(), declval<_XArgs>()...)) __try_call(int);
  355. template <class _XFp, class ..._XArgs>
  356. static __nat __try_call(...);
  357. // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void,
  358. // or incomplete array types as required by the standard.
  359. using _Result = decltype(__try_call<_Fp, _Args...>(0));
  360. using type = typename conditional<
  361. _IsNotSame<_Result, __nat>::value,
  362. typename conditional< is_void<_Ret>::value, true_type, __is_core_convertible<_Result, _Ret> >::type,
  363. false_type >::type;
  364. static const bool value = type::value;
  365. };
  366. template <class _Fp, class ..._Args>
  367. using __invokable = __invokable_r<void, _Fp, _Args...>;
  368. template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class ..._Args>
  369. struct __nothrow_invokable_r_imp {
  370. static const bool value = false;
  371. };
  372. template <class _Ret, class _Fp, class ..._Args>
  373. struct __nothrow_invokable_r_imp<true, false, _Ret, _Fp, _Args...>
  374. {
  375. typedef __nothrow_invokable_r_imp _ThisT;
  376. template <class _Tp>
  377. static void __test_noexcept(_Tp) _NOEXCEPT;
  378. static const bool value = noexcept(_ThisT::__test_noexcept<_Ret>(
  379. _VSTD::__invoke(declval<_Fp>(), declval<_Args>()...)));
  380. };
  381. template <class _Ret, class _Fp, class ..._Args>
  382. struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...>
  383. {
  384. static const bool value = noexcept(
  385. _VSTD::__invoke(declval<_Fp>(), declval<_Args>()...));
  386. };
  387. template <class _Ret, class _Fp, class ..._Args>
  388. using __nothrow_invokable_r =
  389. __nothrow_invokable_r_imp<
  390. __invokable_r<_Ret, _Fp, _Args...>::value,
  391. is_void<_Ret>::value,
  392. _Ret, _Fp, _Args...
  393. >;
  394. template <class _Fp, class ..._Args>
  395. using __nothrow_invokable =
  396. __nothrow_invokable_r_imp<
  397. __invokable<_Fp, _Args...>::value,
  398. true, void, _Fp, _Args...
  399. >;
  400. template <class _Fp, class ..._Args>
  401. struct __invoke_of
  402. : public enable_if<
  403. __invokable<_Fp, _Args...>::value,
  404. typename __invokable_r<void, _Fp, _Args...>::_Result>
  405. {
  406. };
  407. template <class _Ret, bool = is_void<_Ret>::value>
  408. struct __invoke_void_return_wrapper
  409. {
  410. template <class ..._Args>
  411. static _Ret __call(_Args&&... __args) {
  412. return std::__invoke(std::forward<_Args>(__args)...);
  413. }
  414. };
  415. template <class _Ret>
  416. struct __invoke_void_return_wrapper<_Ret, true>
  417. {
  418. template <class ..._Args>
  419. static void __call(_Args&&... __args) {
  420. std::__invoke(std::forward<_Args>(__args)...);
  421. }
  422. };
  423. #if _LIBCPP_STD_VER > 14
  424. // is_invocable
  425. template <class _Fn, class ..._Args>
  426. struct _LIBCPP_TEMPLATE_VIS is_invocable
  427. : integral_constant<bool, __invokable<_Fn, _Args...>::value> {};
  428. template <class _Ret, class _Fn, class ..._Args>
  429. struct _LIBCPP_TEMPLATE_VIS is_invocable_r
  430. : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {};
  431. template <class _Fn, class ..._Args>
  432. inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
  433. template <class _Ret, class _Fn, class ..._Args>
  434. inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value;
  435. // is_nothrow_invocable
  436. template <class _Fn, class ..._Args>
  437. struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable
  438. : integral_constant<bool, __nothrow_invokable<_Fn, _Args...>::value> {};
  439. template <class _Ret, class _Fn, class ..._Args>
  440. struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r
  441. : integral_constant<bool, __nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {};
  442. template <class _Fn, class ..._Args>
  443. inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value;
  444. template <class _Ret, class _Fn, class ..._Args>
  445. inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
  446. template <class _Fn, class... _Args>
  447. struct _LIBCPP_TEMPLATE_VIS invoke_result
  448. : __invoke_of<_Fn, _Args...>
  449. {
  450. };
  451. template <class _Fn, class... _Args>
  452. using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
  453. template <class _Fn, class ..._Args>
  454. _LIBCPP_CONSTEXPR_AFTER_CXX17 invoke_result_t<_Fn, _Args...>
  455. invoke(_Fn&& __f, _Args&&... __args)
  456. noexcept(is_nothrow_invocable_v<_Fn, _Args...>)
  457. {
  458. return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);
  459. }
  460. #endif // _LIBCPP_STD_VER > 14
  461. _LIBCPP_END_NAMESPACE_STD
  462. #endif // _LIBCPP___FUNCTIONAL_INVOKE_H