Lagrange
Loading...
Searching...
No Matches
function_ref.h
1// Source: https://github.com/TartanLlama/function_ref
2// SPDX-License-Identifier: CC0-1.0
3//
4// This file has been modified by Adobe.
5//
6// All modifications are Copyright 2022 Adobe.
7//
8// function_ref - A low-overhead non-owning function
9// Written in 2017 by Simon Brand (@TartanLlama)
10//
11// To the extent possible under law, the author(s) have dedicated all
12// copyright and related and neighboring rights to this software to the
13// public domain worldwide. This software is distributed without any warranty.
14//
15// You should have received a copy of the CC0 Public Domain Dedication
16// along with this software. If not, see
17// <http://creativecommons.org/publicdomain/zero/1.0/>.
18//
19
20#pragma once
21
22#include <functional>
23#include <type_traits>
24#include <utility>
25
26namespace lagrange {
27
30
44template <class F>
46
49template <class R, class... Args>
50class function_ref<R(Args...)>
51{
52public:
53 constexpr function_ref() noexcept = delete;
54
56 constexpr function_ref(const function_ref<R(Args...)>& rhs) noexcept = default;
57
59 template <
60 typename F,
61 std::enable_if_t<
62 !std::is_same<std::decay_t<F>, function_ref>::value &&
63 std::is_invocable_r<R, F&&, Args...>::value>* = nullptr>
64 constexpr function_ref(F&& f) noexcept
65 : obj_(const_cast<void*>(reinterpret_cast<const void*>(std::addressof(f))))
66 {
67 callback_ = [](void* obj, Args... args) -> R {
68 return std::invoke(
69 *reinterpret_cast<typename std::add_pointer<F>::type>(obj),
70 std::forward<Args>(args)...);
71 };
72 }
73
75 constexpr function_ref<R(Args...)>& operator=(const function_ref<R(Args...)>& rhs) noexcept =
76 default;
77
79 template <typename F, std::enable_if_t<std::is_invocable_r<R, F&&, Args...>::value>* = nullptr>
80 constexpr function_ref<R(Args...)>& operator=(F&& f) noexcept
81 {
82 obj_ = reinterpret_cast<void*>(std::addressof(f));
83 callback_ = [](void* obj, Args... args) {
84 return std::invoke(
85 *reinterpret_cast<typename std::add_pointer<F>::type>(obj),
86 std::forward<Args>(args)...);
87 };
88
89 return *this;
90 }
91
93 constexpr void swap(function_ref<R(Args...)>& rhs) noexcept
94 {
95 std::swap(obj_, rhs.obj_);
96 std::swap(callback_, rhs.callback_);
97 }
98
100 R operator()(Args... args) const { return callback_(obj_, std::forward<Args>(args)...); }
101
103 explicit operator bool() const noexcept { return callback_ != nullptr; }
104
105private:
106 void* obj_ = nullptr;
107 R (*callback_)(void*, Args...) = nullptr;
108};
109
111template <typename R, typename... Args>
112constexpr void swap(function_ref<R(Args...)>& lhs, function_ref<R(Args...)>& rhs) noexcept
113{
114 lhs.swap(rhs);
115}
116
118template <typename R, typename... Args>
119function_ref(R (*)(Args...)) -> function_ref<R(Args...)>;
120
121// TODO, will require some kind of callable traits
122// template <typename F>
123// function_ref(F) -> function_ref</* deduced if possible */>;
124
126
127} // namespace lagrange
constexpr function_ref(F &&f) noexcept
Constructs a function_ref referring to f.
Definition function_ref.h:64
constexpr void swap(function_ref< R(Args...)> &rhs) noexcept
Swaps the referred callables of *this and rhs.
Definition function_ref.h:93
constexpr function_ref< R(Args...)> & operator=(F &&f) noexcept
Makes *this refer to f.
Definition function_ref.h:80
constexpr function_ref(const function_ref< R(Args...)> &rhs) noexcept=default
Creates a function_ref which refers to the same callable as rhs.
R operator()(Args... args) const
Call the stored callable with the given arguments.
Definition function_ref.h:100
constexpr function_ref< R(Args...)> & operator=(const function_ref< R(Args...)> &rhs) noexcept=default
Makes *this refer to the same callable as rhs.
A lightweight non-owning reference to a callable.
Definition function_ref.h:45
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.h:112
function_ref(R(*)(Args...)) -> function_ref< R(Args...)>
Deduce function_ref type from a function pointer.
Main namespace for Lagrange.
Definition project.cpp:27