CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Toggle main menu visibility
Loading...
Searching...
No Matches
sdk
include
function_wrapper.hh
1
#include <cdefs.h>
2
#include <functional>
3
#include <tuple>
4
5
/**
6
* Base template for `FunctionWrapper`, never used.
7
*/
8
template
<
typename
FnType>
9
class
FunctionWrapper
;
10
11
/**
12
* A non-owning type-erased reference to a callable object. This is used
13
* to pass lambdas (and similar) down the stack without increasing code
14
* size by template specialisation. Instances of this class must not be
15
* stored, they should be used only for passing type-erased callable objects
16
* down the stack.
17
*
18
* Instances of this class are two words: a reference to the lambda, and a
19
* wrapper callback that invokes the lambda.
20
*
21
* This is similar to `std::function` but is non-owning and so is guaranteed
22
* not to allocate memory (the called function may capture memory).
23
*/
24
template
<
class
R,
class
... Args>
25
class
FunctionWrapper
<R(Args...)>
26
{
27
/**
28
* Storage for the type-erased function. This holds the reference to
29
* lambda and to the invoke function.
30
*/
31
alignas
(
void
*)
char
storage[2 *
sizeof
(
void
*)];
32
33
/**
34
* Base type for the type-erased function. This defines the virtual
35
* function that is used to invoke the captured lambda.
36
*/
37
struct
ErasedFunctionWrapperBase
38
{
39
virtual
R
operator()
(Args... args) = 0;
40
};
41
42
/**
43
* Returns a pointer to the storage, cast to the type-erased function
44
* type.
45
*/
46
ErasedFunctionWrapperBase &stored_function()
47
{
48
return
*
reinterpret_cast<
ErasedFunctionWrapperBase *
>
(storage);
49
}
50
51
/**
52
* Templated subclass that is specialised for each concrete callable
53
* type `T` that is passed. One instance of this will be created for
54
* each lambda type, with a single method in its vtable that invokes
55
* the lambda.
56
*/
57
template
<
typename
T>
58
class
ErasedFunctionWrapper :
public
ErasedFunctionWrapperBase
59
{
60
/// Pointer to the captured lambda.
61
T &&fn;
62
63
public
:
64
/**
65
* Invoke function. This is virtual and overrides the version in
66
* the parent class, allowing this to be called from code that does
67
* not know the cocrete type of the lambda.
68
*/
69
R
operator()
(Args... args)
override
70
{
71
return
fn(std::forward<Args>(args)...);
72
}
73
74
/**
75
* Construct the type-erased function wrapper, capturing the
76
* lambda.
77
*/
78
ErasedFunctionWrapper(T &&fn) : fn{std::forward<T>(fn)} {}
79
};
80
81
public
:
82
/**
83
* This is a non-owning reference, its copy constructor is safe to use for
84
* passing down the stack.
85
*/
86
FunctionWrapper
(
FunctionWrapper
&) =
default
;
87
FunctionWrapper
(
FunctionWrapper
&&) =
delete
;
88
FunctionWrapper
&operator=(
FunctionWrapper
&&) =
delete
;
89
90
/**
91
* Construct the type-erased function wrapper, capturing the lambda.
92
*/
93
template
<
typename
T>
94
__always_inline
FunctionWrapper
(T &&fn)
95
requires
(!std::is_same_v<T, FunctionWrapper>)
96
{
97
// Make sure that we got the size for the storage right!
98
static_assert
(
sizeof
(storage) >=
sizeof
(ErasedFunctionWrapper<T>));
99
// Construct the type-erased function in place.
100
new
(storage) ErasedFunctionWrapper<T>(std::forward<T>(fn));
101
}
102
103
/**
104
* Invoke the captured lambda.
105
*/
106
__always_inline R
operator()
(Args... args)
107
{
108
return
stored_function()(std::forward<Args>(args)...);
109
}
110
};
FunctionWrapper< R(Args...)>::FunctionWrapper
FunctionWrapper(T &&fn)
Construct the type-erased function wrapper, capturing the lambda.
Definition
function_wrapper.hh:94
FunctionWrapper< R(Args...)>::operator()
R operator()(Args... args)
Invoke the captured lambda.
Definition
function_wrapper.hh:106
FunctionWrapper< R(Args...)>::FunctionWrapper
FunctionWrapper(FunctionWrapper &)=default
This is a non-owning reference, its copy constructor is safe to use for passing down the stack.
FunctionWrapper
Base template for FunctionWrapper, never used.
Definition
function_wrapper.hh:9
Generated by
1.18.0