halcheck 1.0
Loading...
Searching...
No Matches
function_view.hpp
1#ifndef HALCHECK_LIB_FUNCTIONAL_FUNCTION_VIEW_HPP
2#define HALCHECK_LIB_FUNCTIONAL_FUNCTION_VIEW_HPP
3
4// IWYU pragma: private, include <halcheck/lib/functional.hpp>
5
6#include <halcheck/lib/functional/invoke.hpp>
7#include <halcheck/lib/functional/overload.hpp>
8#include <halcheck/lib/type_traits.hpp>
9#include <halcheck/lib/variant.hpp>
10
11namespace halcheck { namespace lib {
12
13template<typename T>
14class function_view;
15
22template<typename R, typename... Args>
23class function_view<R(Args...)> {
24public:
31 template<
32 typename F,
37 function_view(F &&func) noexcept // NOLINT: implicit reference to functor
38 : _impl(closure{std::addressof(func), [](void *impl, Args... args) {
39 return lib::invoke(*reinterpret_cast<lib::decay_t<F> *>(impl), std::forward<Args>(args)...);
40 }}) {}
41
47 function_view(R (*func)(Args...)) noexcept // NOLINT: implicit copy of function pointer
48 : _impl(func) {}
49
55 R operator()(Args... args) const {
56 return lib::visit(
58 [&](const closure &func) { return func.invoke(func.self, std::forward<Args>(args)...); },
59 [&](R (*func)(Args...)) { return func(std::forward<Args>(args)...); }),
60 _impl);
61 }
62
63private:
64 struct closure {
65 void *self;
66 R (*invoke)(void *, Args...);
67 };
68
69 lib::variant<R (*)(Args...), closure> _impl;
70};
71
78template<typename R, typename... Args>
79class function_view<R(Args...) const> {
80public:
87 template<
88 typename F,
92 function_view(F &&func) noexcept // NOLINT: implicit reference to functor
93 : _impl(closure{
94 std::addressof(func), [](const void *impl, Args... args) {
95 return lib::invoke(*reinterpret_cast<const lib::decay_t<F> *>(impl), std::forward<Args>(args)...);
96 }}) {}
97
103 function_view(R (*func)(Args...)) noexcept // NOLINT: implicit copy of function pointer
104 : _impl(func) {}
105
110 R operator()(Args... args) const {
111 return lib::visit(
113 [&](const closure &func) { return func.invoke(func.self, std::forward<Args>(args)...); },
114 [&](R (*func)(Args...)) { return func(std::forward<Args>(args)...); }),
115 _impl);
116 }
117
118private:
119 struct closure {
120 const void *self;
121 R (*invoke)(const void *, Args...);
122 };
123
124 lib::variant<R (*)(Args...), closure> _impl;
125};
126
127}} // namespace halcheck::lib
128
129#endif
T addressof(T... args)
R operator()(Args... args) const
Calls the underlying function.*.
Definition function_view.hpp:110
function_view(R(*func)(Args...)) noexcept
Constructs a new function view from a function pointer.
Definition function_view.hpp:103
function_view(F &&func) noexcept
Constructs a new function view from a function object.
Definition function_view.hpp:92
function_view(F &&func) noexcept
Constructs a new function view from a function object.
Definition function_view.hpp:37
R operator()(Args... args) const
Calls the underlying function.
Definition function_view.hpp:55
function_view(R(*func)(Args...)) noexcept
Constructs a new function view from a function pointer.
Definition function_view.hpp:47
T forward(T... args)
HALCHECK_INLINE_CONSTEXPR struct halcheck::lib::@20 invoke
An implementation of std::invoke.
lib::overload< Args... > make_overload(Args... args)
Constructs an overloaded functor from a set of pre-existing functors.
Definition overload.hpp:48
typename std::decay< T >::type decay_t
An implementation of std::decay_t.
Definition type_traits.hpp:101
#define HALCHECK_REQUIRE(...)
Expands to a template argument that is only valid if the given argument evaluates to true.
Definition type_traits.hpp:24
An implementation of std::is_invocable_r.
Definition invoke.hpp:54