Iros
 
Loading...
Searching...
No Matches
invoke.h
Go to the documentation of this file.
1#pragma once
2
3#include "di/meta/language.h"
5#include "di/meta/util.h"
6#include "di/meta/vocab.h"
7#include "di/util/declval.h"
8#include "di/util/forward.h"
9
10namespace di::function {
11namespace detail {
12 template<concepts::MemberFunctionPointer F, typename FirstArg, typename... Args>
13 requires(concepts::BaseOf<meta::MemberPointerClass<F>, meta::Decay<FirstArg>>)
14 constexpr auto invoke_impl(F f, FirstArg&& first_arg, Args&&... args)
15 -> decltype((util::forward<FirstArg>(first_arg).*f)(util::forward<Args>(args)...)) {
16 return (util::forward<FirstArg>(first_arg).*f)(util::forward<Args>(args)...);
17 }
18
19 template<concepts::MemberFunctionPointer F, typename FirstArg, typename... Args>
21 constexpr auto invoke_impl(F f, FirstArg&& first_arg, Args&&... args)
22 -> decltype((first_arg.get().*f)(util::forward<Args>(args)...)) {
23 return (first_arg.get().*f)(util::forward<Args>(args)...);
24 }
25
26 template<concepts::MemberFunctionPointer F, typename FirstArg, typename... Args>
27 constexpr auto invoke_impl(F f, FirstArg&& first_arg, Args&&... args)
28 -> decltype(((*util::forward<FirstArg>(first_arg)).*f)(util::forward<Args>(args)...)) {
29 return ((*util::forward<FirstArg>(first_arg)).*f)(util::forward<Args>(args)...);
30 }
31
32 template<concepts::MemberObjectPointer F, typename Arg>
34 constexpr auto invoke_impl(F f, Arg&& arg) -> decltype(util::forward<Arg>(arg).*f) {
35 return util::forward<Arg>(arg).*f;
36 }
37
38 template<concepts::MemberObjectPointer F, typename Arg>
40 constexpr auto invoke_impl(F f, Arg&& arg) -> decltype(arg.get().*f) {
41 return arg.get().*f;
42 }
43
44 template<concepts::MemberObjectPointer F, typename Arg>
45 constexpr auto invoke_impl(F f, Arg&& arg) -> decltype((*util::forward<Arg>(arg)).*f) {
46 return (*util::forward<Arg>(arg)).*f;
47 }
48
49 template<typename F, typename... Args>
50 constexpr auto invoke_impl(F&& f, Args&&... args) -> decltype(util::forward<F>(f)(util::forward<Args>(args)...)) {
51 return util::forward<F>(f)(util::forward<Args>(args)...);
52 }
53}
54}
55
56namespace di::concepts {
57template<typename... Ts>
58concept Invocable = requires(Ts&&... ts) { function::detail::invoke_impl(util::forward<Ts>(ts)...); };
59}
60
61namespace di::meta {
62template<typename... Ts>
63requires(concepts::Invocable<Ts...>)
65}
66
67namespace di::concepts {
68template<typename F, typename R, typename... Args>
69concept InvocableTo =
70 Invocable<F, Args...> && (LanguageVoid<R> || ImplicitlyConvertibleTo<meta::InvokeResult<F, Args...>, R>);
71
72template<typename R, typename... Ts>
74}
75
76namespace di::function {
77namespace detail {
79 template<typename F, typename... Args>
80 requires(concepts::Invocable<F, Args...>)
81 constexpr auto operator()(F&& f, Args&&... args) const -> meta::InvokeResult<F, Args...> {
82 return function::detail::invoke_impl(util::forward<F>(f), util::forward<Args>(args)...);
83 }
84 };
85
86 template<typename R>
88 template<typename F, typename... Args>
89 requires(concepts::InvocableTo<F, R, Args...>)
90 constexpr auto operator()(F&& f, Args&&... args) const -> R {
91 if constexpr (concepts::LanguageVoid<R>) {
92 (void) function::detail::invoke_impl(util::forward<F>(f), util::forward<Args>(args)...);
93 } else {
94 return function::detail::invoke_impl(util::forward<F>(f), util::forward<Args>(args)...);
95 }
96 }
97 };
98}
99
100constexpr inline auto invoke = function::detail::InvokeFunction {};
101
102template<typename R>
104}
105
106namespace di {
107using concepts::Invocable;
108using concepts::InvocableTo;
109using function::invoke;
112}
Definition language.h:373
Implicit conversion for this test refers to the ability to return a value of function from a type.
Definition operations.h:89
Definition invoke.h:73
Definition invoke.h:69
Definition invoke.h:58
Definition core.h:128
Definition language.h:200
Definition vocab.h:103
Definition impl.h:7
Definition any_storable.h:9
concept F
Definition zip_transform.h:12
Definition bind_back.h:16
constexpr auto invoke_impl(F f, FirstArg &&first_arg, Args &&... args) -> decltype((util::forward< FirstArg >(first_arg).*f)(util::forward< Args >(args)...))
Definition invoke.h:14
Definition as_bool.h:8
constexpr auto invoke
Definition invoke.h:100
constexpr auto invoke_r
Definition invoke.h:103
Definition merge_interfaces.h:6
Conditional< concepts::LanguageArray< RemoveReference< T > >, RemoveExtent< RemoveReference< T > > *, Conditional< concepts::LanguageFunction< RemoveReference< T > >, AddPointer< RemoveReference< T > >, RemoveCVRef< T > > > Decay
Definition language.h:574
decltype(function::detail::invoke_impl(util::declval< Ts >()...)) InvokeResult
Definition invoke.h:64
auto declval() -> meta::AddRValueReference< T >
Definition declval.h:8
Definition zstring_parser.h:9