Lagrange
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
32
46template <class F>
48
51template <class R, class... Args>
52class function_ref<R(Args...)>
53{
54public:
55 constexpr function_ref() noexcept = delete;
56
58 constexpr function_ref(const function_ref<R(Args...)>& rhs) noexcept = default;
59
61 template <
62 typename F,
63 std::enable_if_t<
64 !std::is_same<std::decay_t<F>, function_ref>::value &&
65 std::is_invocable_r<R, F&&, Args...>::value>* = nullptr>
66 constexpr function_ref(F&& f) noexcept
67 : obj_(const_cast<void*>(reinterpret_cast<const void*>(std::addressof(f))))
68 {
69 callback_ = [](void* obj, Args... args) -> R {
70 return std::invoke(
71 *reinterpret_cast<typename std::add_pointer<F>::type>(obj),
72 std::forward<Args>(args)...);
73 };
74 }
75
77 constexpr function_ref<R(Args...)>& operator=(const function_ref<R(Args...)>& rhs) noexcept =
78 default;
79
81 template <typename F, std::enable_if_t<std::is_invocable_r<R, F&&, Args...>::value>* = nullptr>
82 constexpr function_ref<R(Args...)>& operator=(F&& f) noexcept
83 {
84 obj_ = reinterpret_cast<void*>(std::addressof(f));
85 callback_ = [](void* obj, Args... args) {
86 return std::invoke(
87 *reinterpret_cast<typename std::add_pointer<F>::type>(obj),
88 std::forward<Args>(args)...);
89 };
90
91 return *this;
92 }
93
95 constexpr void swap(function_ref<R(Args...)>& rhs) noexcept
96 {
97 std::swap(obj_, rhs.obj_);
98 std::swap(callback_, rhs.callback_);
99 }
100
102 R operator()(Args... args) const { return callback_(obj_, std::forward<Args>(args)...); }
103
105 explicit operator bool() const noexcept { return callback_ != nullptr; }
106
107private:
108 void* obj_ = nullptr;
109 R (*callback_)(void*, Args...) = nullptr;
110};
111
113template <typename R, typename... Args>
114constexpr void swap(function_ref<R(Args...)>& lhs, function_ref<R(Args...)>& rhs) noexcept
115{
116 lhs.swap(rhs);
117}
118
120template <typename R, typename... Args>
121function_ref(R (*)(Args...)) -> function_ref<R(Args...)>;
122
123// TODO, will require some kind of callable traits
124// template <typename F>
125// function_ref(F) -> function_ref</* deduced if possible */>;
126
128
129} // namespace lagrange
constexpr function_ref(F &&f) noexcept
Constructs a function_ref referring to f.
Definition: function_ref.h:66
constexpr void swap(function_ref< R(Args...)> &rhs) noexcept
Swaps the referred callables of *this and rhs.
Definition: function_ref.h:95
constexpr function_ref< R(Args...)> & operator=(F &&f) noexcept
Makes *this refer to f.
Definition: function_ref.h:82
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:102
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:47
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:114
function_ref(R(*)(Args...)) -> function_ref< R(Args...)>
Deduce function_ref type from a function pointer.
Main namespace for Lagrange.
Definition: AABBIGL.h:30
Definition: project.cpp:27