openMSX
function_ref.hh
Go to the documentation of this file.
1// This is a simplified / stripped-down version of:
2// https://github.com/TartanLlama/function_ref/blob/master/include/tl/function_ref.hpp
3
5// function_ref - A low-overhead non-owning function
6// Written in 2017 by Simon Brand (@TartanLlama)
7//
8// To the extent possible under law, the author(s) have dedicated all
9// copyright and related and neighboring rights to this software to the
10// public domain worldwide. This software is distributed without any warranty.
11//
12// You should have received a copy of the CC0 Public Domain Dedication
13// along with this software. If not, see
14// <http://creativecommons.org/publicdomain/zero/1.0/>.
16
17#ifndef FUNCTION_REF_HH
18#define FUNCTION_REF_HH
19
20#include <functional>
21#include <type_traits>
22#include <utility>
23
24template<typename F> class function_ref;
25
26template<typename R, typename... Args>
27class function_ref<R(Args...)>
28{
29public:
30 constexpr function_ref() noexcept = delete;
31
32 template<typename F,
33 std::enable_if_t<!std::is_same_v<std::decay_t<F>, function_ref> &&
34 std::is_invocable_r_v<R, F &&, Args...>>* = nullptr>
35 constexpr function_ref(F&& f) noexcept
36 : obj(const_cast<void*>(reinterpret_cast<const void*>(std::addressof(f))))
37 {
38 callback = [](void* o, Args... args) -> R {
39 return std::invoke(*reinterpret_cast<std::add_pointer_t<F>>(o),
40 std::forward<Args>(args)...);
41 };
42 }
43
44 template<typename F,
45 std::enable_if_t<std::is_invocable_r_v<R, F &&, Args...>>* = nullptr>
46 constexpr function_ref& operator=(F&& f) noexcept
47 {
48 obj = reinterpret_cast<void*>(std::addressof(f));
49 callback = [](void* o, Args... args) {
50 return std::invoke(*reinterpret_cast<std::add_pointer_t<F>>(o),
51 std::forward<Args>(args)...);
52 };
53 return *this;
54 }
55
56 constexpr R operator()(Args... args) const
57 {
58 return callback(obj, std::forward<Args>(args)...);
59 }
60
61private:
62 void* obj = nullptr;
63 R (*callback)(void*, Args...) = nullptr;
64};
65
66template<typename R, typename... Args>
67function_ref(R(*)(Args...)) -> function_ref<R(Args...)>;
68
69#endif
constexpr R operator()(Args... args) const
constexpr function_ref & operator=(F &&f) noexcept
constexpr function_ref() noexcept=delete
RegFunction R
STL namespace.