dispenso
1.6.0
A library for task parallelism
Loading...
Searching...
No Matches
once_function.h
Go to the documentation of this file.
1
/*
2
* Copyright (c) Meta Platforms, Inc. and affiliates.
3
*
4
* This source code is licensed under the MIT license found in the
5
* LICENSE file in the root directory of this source tree.
6
*/
7
15
#pragma once
16
17
#include <cstring>
18
#include <utility>
19
20
#include <dispenso/detail/once_callable_impl.h>
21
#include <
dispenso/platform.h
>
22
23
namespace
dispenso {
24
25
#if DISPENSO_HAS_CONCEPTS
34
template
<
typename
F>
35
concept
OnceCallableFunc = std::invocable<F>;
36
#endif
// DISPENSO_HAS_CONCEPTS
37
38
namespace
detail {
39
template
<
typename
Result>
40
class
FutureBase;
41
template
<
typename
Result>
42
class
FutureImplBase;
43
}
// namespace detail
44
54
class
OnceFunction
{
55
public
:
59
OnceFunction
()
60
#if defined DISPENSO_DEBUG
61
: invoke_(
nullptr
)
62
#endif
// DISPENSO_DEBUG
63
{
64
}
65
73
template
<
typename
F>
74
DISPENSO_REQUIRES(OnceCallableFunc<F>)
75
OnceFunction
(F&& f) {
76
auto
callable = detail::createOnceCallable(std::forward<F>(f), buf_);
77
invoke_ = callable.invoke;
78
}
79
80
OnceFunction
(
const
OnceFunction
& other) =
delete
;
81
83
OnceFunction
(
OnceFunction
&& other)
noexcept
{
84
std::memcpy(
static_cast<
void
*
>
(
this
), &other,
sizeof
(
OnceFunction
));
85
#if defined DISPENSO_DEBUG
86
other.invoke_ =
nullptr
;
87
#endif
// DISPENSO_DEBUG
88
}
89
90
OnceFunction
& operator=(
OnceFunction
&& other)
noexcept
{
91
if
(
this
!= &other) {
92
#if defined DISPENSO_DEBUG
93
assert(
94
invoke_ ==
nullptr
&&
95
"OnceFunction must be invoked or cleanupNotRun() before reassignment"
);
96
#endif
// DISPENSO_DEBUG
97
std::memcpy(
static_cast<
void
*
>
(
this
), &other,
sizeof
(
OnceFunction
));
98
#if defined DISPENSO_DEBUG
99
other.invoke_ =
nullptr
;
100
#endif
// DISPENSO_DEBUG
101
}
102
return
*
this
;
103
}
104
110
void
cleanupNotRun
() {
111
#if defined DISPENSO_DEBUG
112
assert(invoke_ !=
nullptr
&&
"Must not cleanup an invalid OnceFunction!"
);
113
invoke_(buf_,
false
);
114
invoke_ =
nullptr
;
115
#else
116
invoke_(buf_,
false
);
117
#endif
// DISPENSO_DEBUG
118
}
119
124
void
operator()()
const
{
125
#if defined DISPENSO_DEBUG
126
assert(invoke_ !=
nullptr
&&
"Must not use OnceFunction more than once!"
);
127
#endif
// DISPENSO_DEBUG
128
129
invoke_(buf_,
true
);
130
131
#if defined DISPENSO_DEBUG
132
invoke_ =
nullptr
;
133
#endif
// DISPENSO_DEBUG
134
}
135
136
private
:
137
// 64 bytes total (one cache line): 56 bytes inline storage + 8 bytes invoke ptr.
138
// Inline: buf_ holds the functor directly.
139
// Spill: buf_[0..7] holds a void* to pool-allocated storage.
140
// Moves are a 64-byte memcpy — no pointer fixup needed.
141
alignas
(64)
mutable
char
buf_[detail::kOnceFunctionInlineSize];
142
mutable
void (*invoke_)(
void
*, bool);
143
144
template
<
typename
Result>
145
friend
class
detail::FutureBase;
146
template
<
typename
Result>
147
friend
class
detail::FutureImplBase;
148
};
149
150
}
// namespace dispenso
dispenso::OnceFunction
Definition
once_function.h:54
dispenso::OnceFunction::OnceFunction
OnceFunction()
Definition
once_function.h:59
dispenso::OnceFunction::cleanupNotRun
void cleanupNotRun()
Definition
once_function.h:110
dispenso::OnceFunction::OnceFunction
OnceFunction(OnceFunction &&other) noexcept
Definition
once_function.h:83
platform.h
dispenso
once_function.h
Generated by
1.12.0