tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
function_ref.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch
3
4#ifndef TETL_FUNCTIONAL_FUNCTION_REF_HPP
5#define TETL_FUNCTIONAL_FUNCTION_REF_HPP
6
7#include <etl/_functional/invoke_r.hpp>
8#include <etl/_memory/addressof.hpp>
9#include <etl/_type_traits/add_pointer.hpp>
10#include <etl/_type_traits/decay.hpp>
11#include <etl/_type_traits/is_invocable_r.hpp>
12#include <etl/_type_traits/is_same.hpp>
13#include <etl/_utility/forward.hpp>
14#include <etl/_utility/swap.hpp>
15
16namespace etl {
17
18namespace detail {
19
20template <bool Noexcept, typename Signature>
21struct function_ref;
22
23template <bool Noexcept, typename R, typename... Args>
24struct function_ref<Noexcept, R(Args...)> {
25 template <typename F>
26 requires(not etl::is_same_v<decay_t<F>, function_ref> and etl::is_invocable_r_v<R, F &&, Args...>)
27 function_ref(F&& f) noexcept
28 : _obj(const_cast<void*>(reinterpret_cast<void const*>(etl::addressof(f))))
29 , _callable{+[](void* obj, Args... args) -> R {
30 auto* func = reinterpret_cast<etl::add_pointer_t<F>>(obj);
31 return etl::invoke_r<R>(*func, etl::forward<Args>(args)...);
32 }}
33 {
34 }
35
36 constexpr function_ref(function_ref const&) noexcept = default;
37 constexpr auto operator=(function_ref const&) noexcept -> function_ref& = default;
38
39 template <typename T>
40 auto operator=(T /*t*/) -> function_ref& = delete;
41
42 auto operator()(Args... args) const noexcept(Noexcept) -> R
43 {
44 return _callable(_obj, etl::forward<Args>(args)...);
45 }
46
47private:
48 using internal_signature_t = R (*)(void*, Args...) noexcept(Noexcept);
49
50 void* _obj{nullptr};
51 internal_signature_t _callable{nullptr};
52};
53} // namespace detail
54
55/// Non-owning view of a callable.
56///
57/// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p0792r14.html
58/// https://github.com/TartanLlama/function_ref
59template <typename Signature>
60struct function_ref;
61
62template <typename R, typename... Args>
63struct function_ref<R(Args...)> : etl::detail::function_ref<false, R(Args...)> {
64 using etl::detail::function_ref<false, R(Args...)>::function_ref;
65};
66
67template <typename R, typename... Args>
68struct function_ref<R(Args...) noexcept> : etl::detail::function_ref<true, R(Args...)> {
69 using etl::detail::function_ref<true, R(Args...)>::function_ref;
70};
71
72template <typename R, typename... Args>
73function_ref(R (*)(Args...)) -> function_ref<R(Args...)>;
74
75} // namespace etl
76
77#endif // TETL_FUNCTIONAL_FUNCTION_REF_HPP
Definition adjacent_find.hpp:9
function_ref(R(*)(Args...)) -> function_ref< R(Args...)>