Sleipnir C++ API
Loading...
Searching...
No Matches
function_ref.hpp
1// Copyright (c) Sleipnir contributors
2
3#pragma once
4
5#include <functional>
6#include <memory>
7#include <type_traits>
8#include <utility>
9
10namespace slp {
11
12template <class F>
14
19template <class R, class... Args>
20class function_ref<R(Args...)> {
21 public:
22 constexpr function_ref() noexcept = delete;
23
29 constexpr function_ref(const function_ref<R(Args...)>& rhs) noexcept =
30 default;
31
38 template <typename F>
39 requires(!std::is_same_v<std::decay_t<F>, function_ref> &&
40 std::is_invocable_r_v<R, F &&, Args...>)
41 // NOLINTNEXTLINE (google-explicit-constructor)
42 constexpr function_ref(F&& f) noexcept
43 : obj_(const_cast<void*>(
44 reinterpret_cast<const void*>(std::addressof(f)))) {
45 callback_ = [](void* obj, Args... args) -> R {
46 return std::invoke(
47 *reinterpret_cast<typename std::add_pointer<F>::type>(obj),
48 std::forward<Args>(args)...);
49 };
50 }
51
58 constexpr function_ref<R(Args...)>& operator=(
59 const function_ref<R(Args...)>& rhs) noexcept = default;
60
67 template <typename F>
68 requires std::is_invocable_r_v<R, F&&, Args...>
69 constexpr function_ref<R(Args...)>& operator=(F&& f) noexcept {
70 obj_ = reinterpret_cast<void*>(std::addressof(f));
71 callback_ = [](void* obj, Args... args) {
72 return std::invoke(
73 *reinterpret_cast<typename std::add_pointer<F>::type>(obj),
74 std::forward<Args>(args)...);
75 };
76
77 return *this;
78 }
79
85 constexpr void swap(function_ref<R(Args...)>& rhs) noexcept {
86 std::swap(obj_, rhs.obj_);
87 std::swap(callback_, rhs.callback_);
88 }
89
96 R operator()(Args... args) const {
97 return callback_(obj_, std::forward<Args>(args)...);
98 }
99
100 private:
101 void* obj_ = nullptr;
102 R (*callback_)(void*, Args...) = nullptr;
103};
104
108template <typename R, typename... Args>
109constexpr void swap(function_ref<R(Args...)>& lhs,
110 function_ref<R(Args...)>& rhs) noexcept {
111 lhs.swap(rhs);
112}
113
114template <typename R, typename... Args>
115function_ref(R (*)(Args...)) -> function_ref<R(Args...)>;
116
117} // namespace slp
Definition intrusive_shared_ptr.hpp:29
constexpr function_ref< R(Args...)> & operator=(const function_ref< R(Args...)> &rhs) noexcept=default
constexpr function_ref< R(Args...)> & operator=(F &&f) noexcept
Definition function_ref.hpp:69
R operator()(Args... args) const
Definition function_ref.hpp:96
constexpr function_ref(const function_ref< R(Args...)> &rhs) noexcept=default
constexpr function_ref(F &&f) noexcept
Definition function_ref.hpp:42
constexpr void swap(function_ref< R(Args...)> &rhs) noexcept
Definition function_ref.hpp:85
Definition function_ref.hpp:13