WPILibC++ 2027.0.0-alpha-2
Loading...
Searching...
No Matches
function_ref.hpp
Go to the documentation of this file.
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
15/**
16 * An implementation of std::function_ref, a lightweight non-owning reference to
17 * a callable.
18 */
19template <class R, class... Args>
20class function_ref<R(Args...)> {
21 public:
22 constexpr function_ref() noexcept = delete;
23
24 /**
25 * Creates a `function_ref` which refers to the same callable as `rhs`.
26 *
27 * @param rhs Other `function_ref`.
28 */
29 constexpr function_ref(const function_ref<R(Args...)>& rhs) noexcept =
30 default;
31
32 /**
33 * Constructs a `function_ref` referring to `f`.
34 *
35 * @tparam F Callable type.
36 * @param f Callable to which to refer.
37 */
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
51 /**
52 * Makes `*this` refer to the same callable as `rhs`.
53 *
54 * @param rhs Other `function_ref`.
55 * @return `*this`
56 */
57 constexpr function_ref<R(Args...)>& operator=(
58 const function_ref<R(Args...)>& rhs) noexcept = default;
59
60 /**
61 * Makes `*this` refer to `f`.
62 *
63 * @param f Callable to which to refer.
64 * @return `*this`
65 */
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
79 /**
80 * Swaps the referred callables of `*this` and `rhs`.
81 *
82 * @param rhs Other `function_ref`.
83 */
84 constexpr void swap(function_ref<R(Args...)>& rhs) noexcept {
85 std::swap(obj_, rhs.obj_);
86 std::swap(callback_, rhs.callback_);
87 }
88
89 /**
90 * Call the stored callable with the given arguments.
91 *
92 * @param args The arguments.
93 * @return The return value of the callable.
94 */
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
104/**
105 * Swaps the referred callables of `lhs` and `rhs`.
106 */
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() noexcept=delete
constexpr function_ref< R(Args...)> & operator=(const function_ref< R(Args...)> &rhs) noexcept=default
Makes *this refer to the same callable as rhs.
constexpr function_ref< R(Args...)> & operator=(F &&f) noexcept
Makes *this refer to f.
Definition function_ref.hpp:68
R operator()(Args... args) const
Call the stored callable with the given arguments.
Definition function_ref.hpp:95
constexpr void swap(function_ref< R(Args...)> &rhs) noexcept
Swaps the referred callables of *this and rhs.
Definition function_ref.hpp:84
Definition function_ref.hpp:13
Definition expression_graph.hpp:11
function_ref(R(*)(Args...)) -> function_ref< R(Args...)>
constexpr void swap(function_ref< R(Args...)> &lhs, function_ref< R(Args...)> &rhs) noexcept
Swaps the referred callables of lhs and rhs.
Definition function_ref.hpp:108
Definition PointerIntPair.h:280
WPI_BASIC_JSON_TPL_DECLARATION void swap(wpi::WPI_BASIC_JSON_TPL &j1, wpi::WPI_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp) is_nothrow_move_constructible< wpi::WPI_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression, cppcoreguidelines-noexcept-swap, performance-noexcept-swap) is_nothrow_move_assignable< wpi::WPI_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition json.h:5258
typename std::decay< T >::type decay_t
Definition base.h:326