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 constexpr function_ref(F&& f) noexcept // NOLINT(google-explicit-constructor)
42 : obj_(const_cast<void*>(
43 reinterpret_cast<const void*>(std::addressof(f)))) {
44 callback_ = [](void* obj, Args... args) -> R {
45 return std::invoke(
46 *reinterpret_cast<typename std::add_pointer<F>::type>(obj),
47 std::forward<Args>(args)...);
48 };
49 }
50
57 constexpr function_ref<R(Args...)>& operator=(
58 const function_ref<R(Args...)>& rhs) noexcept = default;
59
66 template <typename F>
67 requires std::is_invocable_r_v<R, F&&, Args...>
68 constexpr function_ref<R(Args...)>& operator=(F&& f) noexcept {
69 obj_ = reinterpret_cast<void*>(std::addressof(f));
70 callback_ = [](void* obj, Args... args) {
71 return std::invoke(
72 *reinterpret_cast<typename std::add_pointer<F>::type>(obj),
73 std::forward<Args>(args)...);
74 };
75
76 return *this;
77 }
78
84 constexpr void swap(function_ref<R(Args...)>& rhs) noexcept {
85 std::swap(obj_, rhs.obj_);
86 std::swap(callback_, rhs.callback_);
87 }
88
95 R operator()(Args... args) const {
96 return callback_(obj_, std::forward<Args>(args)...);
97 }
98
99 private:
100 void* obj_ = nullptr;
101 R (*callback_)(void*, Args...) = nullptr;
102};
103
107template <typename R, typename... Args>
108constexpr void swap(function_ref<R(Args...)>& lhs,
109 function_ref<R(Args...)>& rhs) noexcept {
110 lhs.swap(rhs);
111}
112
113template <typename R, typename... Args>
114function_ref(R (*)(Args...)) -> function_ref<R(Args...)>;
115
116} // namespace slp
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:68
R operator()(Args... args) const
Definition function_ref.hpp:95
constexpr function_ref(const function_ref< R(Args...)> &rhs) noexcept=default
constexpr function_ref(F &&f) noexcept
Definition function_ref.hpp:41
constexpr void swap(function_ref< R(Args...)> &rhs) noexcept
Definition function_ref.hpp:84
Definition function_ref.hpp:13