Line data Source code
1 : /***************************************************************************\
2 : * Name : function_ref *
3 : * Description : non-owning reference to a callable *
4 : * Author : LLVM *
5 : * Reference : https://llvm.org/doxygen/classllvm_1_1function__ref_3_01Ret_07Params_8_8_8_08_4.html
6 : *
7 : * ------------------------------------------------------------------------- *
8 : * This is free software; you can redistribute it and/or modify it under the *
9 : * terms of the MIT license. A copy of the license can be found in the file *
10 : * "LICENSE" at the root of this distribution. *
11 : \***************************************************************************/
12 : #pragma once
13 : #pragma once
14 :
15 : #include <cstdint>
16 : #include <type_traits>
17 : #include <utility>
18 :
19 : namespace spb::detail
20 : {
21 :
22 : template <typename Fn> class function_ref;
23 :
24 : template <typename Ret, typename... Params> class function_ref<Ret(Params...)>
25 : {
26 : Ret (*callback)(intptr_t callable, Params... params) = nullptr;
27 : intptr_t callable;
28 :
29 4414531 : template <typename Callable> static Ret callback_fn(intptr_t callable, Params... params)
30 : {
31 4414531 : return (*reinterpret_cast<Callable *>(callable))(std::forward<Params>(params)...);
32 : }
33 :
34 : public:
35 : function_ref() = default;
36 5355 : function_ref(std::nullptr_t)
37 5355 : {
38 5355 : }
39 :
40 : template <typename Callable>
41 9306 : function_ref(
42 : Callable &&callable,
43 : // This is not the copy-constructor.
44 : std::enable_if_t<!std::is_same<std::remove_cvref_t<Callable>, function_ref>::value> * = nullptr,
45 : // Functor must be callable and return a suitable type.
46 : std::enable_if_t<std::is_void<Ret>::value ||
47 : std::is_convertible<decltype(std::declval<Callable>()(std::declval<Params>()...)),
48 : Ret>::value> * = nullptr)
49 9306 : : callback(callback_fn<std::remove_reference_t<Callable>>),
50 9306 : callable(reinterpret_cast<intptr_t>(&callable))
51 : {
52 9306 : }
53 :
54 4414531 : Ret operator()(Params... params) const
55 : {
56 4414531 : return callback(callable, std::forward<Params>(params)...);
57 : }
58 :
59 8771905 : explicit operator bool() const
60 : {
61 8771905 : return callback;
62 : }
63 : };
64 : } // namespace spb::detail
|