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
17template <class R, class... Args>
18class function_ref<R(Args...)> {
19 public:
20 constexpr function_ref() noexcept = delete;
21
25 constexpr function_ref(const function_ref<R(Args...)>& rhs) noexcept =
26 default;
27
32 template <typename F>
33 requires(!std::is_same_v<std::decay_t<F>, function_ref> &&
34 std::is_invocable_r_v<R, F &&, Args...>)
35 // NOLINTNEXTLINE (google-explicit-constructor)
36 constexpr function_ref(F&& f) noexcept
37 : obj_(const_cast<void*>(
38 reinterpret_cast<const void*>(std::addressof(f)))) {
39 callback_ = [](void* obj, Args... args) -> R {
40 return std::invoke(
41 *reinterpret_cast<typename std::add_pointer<F>::type>(obj),
42 std::forward<Args>(args)...);
43 };
44 }
45
50 constexpr function_ref<R(Args...)>& operator=(
51 const function_ref<R(Args...)>& rhs) noexcept = default;
52
57 template <typename F>
58 requires std::is_invocable_r_v<R, F&&, Args...>
59 constexpr function_ref<R(Args...)>& operator=(F&& f) noexcept {
60 obj_ = reinterpret_cast<void*>(std::addressof(f));
61 callback_ = [](void* obj, Args... args) {
62 return std::invoke(
63 *reinterpret_cast<typename std::add_pointer<F>::type>(obj),
64 std::forward<Args>(args)...);
65 };
66
67 return *this;
68 }
69
73 constexpr void swap(function_ref<R(Args...)>& rhs) noexcept {
74 std::swap(obj_, rhs.obj_);
75 std::swap(callback_, rhs.callback_);
76 }
77
82 R operator()(Args... args) const {
83 return callback_(obj_, std::forward<Args>(args)...);
84 }
85
86 private:
87 void* obj_ = nullptr;
88 R (*callback_)(void*, Args...) = nullptr;
89};
90
92template <typename R, typename... Args>
93constexpr void swap(function_ref<R(Args...)>& lhs,
94 function_ref<R(Args...)>& rhs) noexcept {
95 lhs.swap(rhs);
96}
97
98template <typename R, typename... Args>
99function_ref(R (*)(Args...)) -> function_ref<R(Args...)>;
100
101} // namespace slp
Definition intrusive_shared_ptr.hpp:27
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:59
R operator()(Args... args) const
Definition function_ref.hpp:82
constexpr function_ref(const function_ref< R(Args...)> &rhs) noexcept=default
constexpr function_ref(F &&f) noexcept
Definition function_ref.hpp:36
constexpr void swap(function_ref< R(Args...)> &rhs) noexcept
Definition function_ref.hpp:73
Definition function_ref.hpp:13