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 >
23 : class function_ref;
24 :
25 : template < typename Ret, typename... Params >
26 : class function_ref< Ret( Params... ) >
27 : {
28 : Ret ( *callback )( intptr_t callable, Params... params ) = nullptr;
29 : intptr_t callable;
30 :
31 : template < typename Callable >
32 4410217 : static Ret callback_fn( intptr_t callable, Params... params )
33 : {
34 4410217 : return ( *reinterpret_cast< Callable * >( callable ) )(
35 8820434 : std::forward< Params >( params )... );
36 : }
37 :
38 : public:
39 : function_ref( ) = default;
40 4850 : function_ref( std::nullptr_t )
41 4850 : {
42 4850 : }
43 :
44 : template < typename Callable >
45 8814 : function_ref( Callable && callable,
46 : // This is not the copy-constructor.
47 : std::enable_if_t< !std::is_same< std::remove_cvref_t< Callable >,
48 : function_ref >::value > * = nullptr,
49 : // Functor must be callable and return a suitable type.
50 : std::enable_if_t< std::is_void< Ret >::value ||
51 : std::is_convertible< decltype( std::declval< Callable >( )(
52 : std::declval< Params >( )... ) ),
53 : Ret >::value > * = nullptr )
54 8814 : : callback( callback_fn< std::remove_reference_t< Callable > > )
55 8814 : , callable( reinterpret_cast< intptr_t >( &callable ) )
56 : {
57 8814 : }
58 :
59 4410217 : Ret operator( )( Params... params ) const
60 : {
61 4410217 : return callback( callable, std::forward< Params >( params )... );
62 : }
63 :
64 8764606 : explicit operator bool( ) const
65 : {
66 8764606 : return callback;
67 : }
68 : };
69 : }// namespace spb::detail
|