14
14
15
15
#pragma once
16
16
17
+ #include < stdint.h>
18
+
17
19
#include " subspace/fn/callable.h"
18
20
#include " subspace/mem/addressof.h"
19
21
#include " subspace/mem/forward.h"
@@ -41,25 +43,20 @@ class SFn;
41
43
42
44
namespace __private {
43
45
44
- template <class R , class ... Args>
45
- struct CallVtable {
46
- R (*call)(void * p, Args... args);
47
- };
48
-
49
46
template <class F >
50
47
struct Invoker {
51
48
template <class R , class ... Args>
52
- static R call_mut (void * p, Args... args) {
53
- F& f = *static_cast <F*>(p);
49
+ static R call_mut (uintptr_t p, Args... args) {
50
+ F& f = *reinterpret_cast <F*>(p);
54
51
return f (::sus::forward<Args>(args)...);
55
52
}
56
53
57
54
template <class R , class ... Args>
58
- static R call_const (void * p, Args... args) {
59
- const F& f = *static_cast <const F*>(p);
55
+ static R call_const (uintptr_t p, Args... args) {
56
+ const F& f = *reinterpret_cast <const F*>(p);
60
57
return f (::sus::forward<Args>(args)...);
61
58
}
62
- }; // namespace __private
59
+ };
63
60
64
61
} // namespace __private
65
62
@@ -96,42 +93,36 @@ class [[sus_trivial_abi]] SFn<R(CallArgs...)> {
96
93
// / #[doc.overloads=ctor.fnpointer]
97
94
template <::sus::fn::callable::FunctionPointerMatches<R, CallArgs...> F>
98
95
SFn (F ptr) noexcept {
99
- ::sus::check (ptr != nullptr );
100
- callable_ = static_cast <void *>(ptr);
101
- static auto vtable = __private::CallVtable<R, CallArgs...>{
102
- .call = &__private::Invoker<
103
- std::remove_reference_t <F>>::template call_const<R, CallArgs...>,
104
- };
105
- vtable_ = &vtable;
96
+ ::sus::check (+ptr != nullptr );
97
+ callable_ = reinterpret_cast <uintptr_t >(+ptr);
98
+ invoke_ = &__private::Invoker<
99
+ std::remove_reference_t <F>>::template call_const<R, CallArgs...>;
106
100
}
107
101
108
102
// / Construction from a capturing lambda or other callable object.
109
103
// /
110
104
// / #[doc.overloads=ctor.lambda]
111
105
template <::sus::fn::callable::CallableObjectReturns<R, CallArgs...> F>
112
106
SFn (F&& object) noexcept {
113
- callable_ = static_cast <void *>(::sus::mem::addressof (object));
114
- static auto vtable = __private::CallVtable<R, CallArgs...>{
115
- .call = &__private::Invoker<
116
- std::remove_reference_t <F>>::template call_const<R, CallArgs...>,
117
- };
118
- vtable_ = &vtable;
107
+ callable_ = reinterpret_cast <uintptr_t >(::sus::mem::addressof (object));
108
+ invoke_ = &__private::Invoker<
109
+ std::remove_reference_t <F>>::template call_const<R, CallArgs...>;
119
110
}
120
111
121
112
~SFn () noexcept = default ;
122
113
123
114
SFn (SFn&& o) noexcept
124
- : callable_ (::sus::mem::replace_ptr (o.callable_ , nullptr )),
125
- // Not setting `o.vtable_ ` to nullptr, as vtable_ as nullptr is its
115
+ : callable_ (::sus::mem::replace (o.callable_ , uintptr_t { 0 } )),
116
+ // Not setting `o.invoke_ ` to nullptr, as invoke_ as nullptr is its
126
117
// never-value.
127
- vtable_ (o.vtable_ ) {
118
+ invoke_ (o.invoke_ ) {
128
119
::sus::check (callable_); // Catch use-after-move.
129
120
}
130
121
SFn& operator =(SFn&& o) noexcept {
131
- callable_ = ::sus::mem::replace_ptr (o.callable_ , nullptr );
132
- // Not setting `o.vtable_ ` to nullptr, as vtable_ as nullptr is its
122
+ callable_ = ::sus::mem::replace (o.callable_ , uintptr_t { 0 } );
123
+ // Not setting `o.invoke_ ` to nullptr, as invoke_ as nullptr is its
133
124
// never-value.
134
- vtable_ = o.vtable_ ;
125
+ invoke_ = o.invoke_ ;
135
126
::sus::check (callable_); // Catch use-after-move.
136
127
return *this ;
137
128
}
@@ -143,19 +134,19 @@ class [[sus_trivial_abi]] SFn<R(CallArgs...)> {
143
134
// / sus::mem::Clone trait.
144
135
SFn clone () const {
145
136
::sus::check (callable_); // Catch use-after-move.
146
- return SFn (callable_, vtable_ );
137
+ return SFn (callable_, invoke_ );
147
138
}
148
139
149
140
// / Runs the closure.
150
141
inline R operator ()(CallArgs... args) const & {
151
- return vtable_-> call (callable_, ::sus::forward<CallArgs>(args)...);
142
+ return (*invoke_) (callable_, ::sus::forward<CallArgs>(args)...);
152
143
}
153
144
154
145
// / Runs and consumes the closure.
155
146
inline R operator ()(CallArgs... args) && {
156
147
::sus::check (callable_); // Catch use-after-move.
157
- return vtable_-> call ( ::sus::mem::replace_ptr (callable_, nullptr ),
158
- ::sus::forward<CallArgs>(args)...);
148
+ return (*invoke_)( ::sus::mem::replace (callable_, uintptr_t { 0 } ),
149
+ ::sus::forward<CallArgs>(args)...);
159
150
}
160
151
161
152
// / `sus::construct::From` trait implementation.
@@ -171,12 +162,12 @@ class [[sus_trivial_abi]] SFn<R(CallArgs...)> {
171
162
// operator to avoid extra indirections being inserted when converting, since
172
163
// otherwise an extra Invoker call would be introduced.
173
164
operator SFnOnce<R, CallArgs...>() && {
174
- return SFnOnce (::sus::mem::replace (callable_, nullptr ), vtable_ );
165
+ return SFnOnce (::sus::mem::replace (callable_, uintptr_t { 0 } ), invoke_ );
175
166
}
176
167
// operator to avoid extra indirections being inserted when converting, since
177
168
// otherwise an extra Invoker call would be introduced.
178
169
operator SFnMut<R, CallArgs...>() && {
179
- return SFnMut (::sus::mem::replace (callable_, nullptr ), vtable_ );
170
+ return SFnMut (::sus::mem::replace (callable_, uintptr_t { 0 } ), invoke_ );
180
171
}
181
172
182
173
private:
@@ -185,15 +176,15 @@ class [[sus_trivial_abi]] SFn<R(CallArgs...)> {
185
176
template <class RR , class ... AArgs>
186
177
friend class SFnMut ;
187
178
188
- SFn (void * callable, __private::CallVtable<R , CallArgs...>* vtable )
189
- : callable_ (callable), vtable_ (vtable ) {}
179
+ SFn (uintptr_t callable, R (*invoke)( uintptr_t p , CallArgs... args) )
180
+ : callable_ (callable), invoke_ (invoke ) {}
190
181
191
- void * callable_;
192
- __private::CallVtable<R , CallArgs...>* vtable_ ;
182
+ uintptr_t callable_;
183
+ R (*invoke_)( uintptr_t p , CallArgs... args) ;
193
184
194
185
sus_class_trivially_relocatable (::sus::marker::unsafe_fn, decltype (callable_),
195
- decltype (vtable_ ));
196
- sus_class_never_value_field (::sus::marker::unsafe_fn, SFn, vtable_ , nullptr ,
186
+ decltype (invoke_ ));
187
+ sus_class_never_value_field (::sus::marker::unsafe_fn, SFn, invoke_ , nullptr ,
197
188
nullptr );
198
189
199
190
protected:
@@ -233,26 +224,20 @@ class [[sus_trivial_abi]] SFnMut<R(CallArgs...)> {
233
224
// / #[doc.overloads=ctor.fnpointer]
234
225
template <::sus::fn::callable::FunctionPointerMatches<R, CallArgs...> F>
235
226
SFnMut (F ptr) noexcept {
236
- ::sus::check (ptr != nullptr );
237
- callable_ = static_cast <void *>(ptr);
238
- static auto vtable = __private::CallVtable<R, CallArgs...>{
239
- .call = &__private::Invoker<
240
- std::remove_reference_t <F>>::template call_mut<R, CallArgs...>,
241
- };
242
- vtable_ = &vtable;
227
+ ::sus::check (+ptr != nullptr );
228
+ callable_ = reinterpret_cast <uintptr_t >(+ptr);
229
+ invoke_ = &__private::Invoker<
230
+ std::remove_reference_t <F>>::template call_mut<R, CallArgs...>;
243
231
}
244
232
245
233
// / Construction from a capturing lambda or other callable object.
246
234
// /
247
235
// / #[doc.overloads=ctor.lambda]
248
236
template <::sus::fn::callable::CallableObjectReturns<R, CallArgs...> F>
249
237
SFnMut (F&& object) noexcept {
250
- callable_ = static_cast <void *>(::sus::mem::addressof (object));
251
- static auto vtable = __private::CallVtable<R, CallArgs...>{
252
- .call = &__private::Invoker<
253
- std::remove_reference_t <F>>::template call_mut<R, CallArgs...>,
254
- };
255
- vtable_ = &vtable;
238
+ callable_ = reinterpret_cast <uintptr_t >(::sus::mem::addressof (object));
239
+ invoke_ = &__private::Invoker<
240
+ std::remove_reference_t <F>>::template call_mut<R, CallArgs...>;
256
241
}
257
242
258
243
// / Construction from SFn.
@@ -261,25 +246,25 @@ class [[sus_trivial_abi]] SFnMut<R(CallArgs...)> {
261
246
// / this constructor avoids extra indirections being inserted when converting,
262
247
// / since otherwise an extra invoker call would be introduced.
263
248
SFnMut (SFn<R (CallArgs...)>&& o) noexcept
264
- : callable_ (::sus::mem::replace_ptr (o.callable_ , nullptr )),
265
- vtable_ (o.vtable_ ) {
249
+ : callable_ (::sus::mem::replace (o.callable_ , uintptr_t { 0 } )),
250
+ invoke_ (o.invoke_ ) {
266
251
::sus::check (callable_); // Catch use-after-move.
267
252
}
268
253
269
254
~SFnMut () noexcept = default ;
270
255
271
256
SFnMut (SFnMut&& o) noexcept
272
- : callable_ (::sus::mem::replace_ptr (o.callable_ , nullptr )),
273
- // Not setting `o.vtable_ ` to nullptr, as vtable_ as nullptr is its
257
+ : callable_ (::sus::mem::replace (o.callable_ , uintptr_t { 0 } )),
258
+ // Not setting `o.invoke_ ` to nullptr, as invoke_ as nullptr is its
274
259
// never-value.
275
- vtable_ (o.vtable_ ) {
260
+ invoke_ (o.invoke_ ) {
276
261
::sus::check (callable_); // Catch use-after-move.
277
262
}
278
263
SFnMut& operator =(SFnMut&& o) noexcept {
279
- callable_ = ::sus::mem::replace_ptr (o.callable_ , nullptr );
280
- // Not setting `o.vtable_ ` to nullptr, as vtable_ as nullptr is its
264
+ callable_ = ::sus::mem::replace (o.callable_ , uintptr_t { 0 } );
265
+ // Not setting `o.invoke_ ` to nullptr, as invoke_ as nullptr is its
281
266
// never-value.
282
- vtable_ = o.vtable_ ;
267
+ invoke_ = o.invoke_ ;
283
268
::sus::check (callable_); // Catch use-after-move.
284
269
return *this ;
285
270
}
@@ -291,19 +276,19 @@ class [[sus_trivial_abi]] SFnMut<R(CallArgs...)> {
291
276
// / sus::mem::Clone trait.
292
277
SFnMut clone () const {
293
278
::sus::check (callable_); // Catch use-after-move.
294
- return SFnMut (callable_, vtable_ );
279
+ return SFnMut (callable_, invoke_ );
295
280
}
296
281
297
282
// / Runs the closure.
298
283
inline R operator ()(CallArgs... args) & {
299
- return vtable_-> call (callable_, ::sus::forward<CallArgs>(args)...);
284
+ return (*invoke_) (callable_, ::sus::forward<CallArgs>(args)...);
300
285
}
301
286
302
287
// / Runs and consumes the closure.
303
288
inline R operator ()(CallArgs... args) && {
304
289
::sus::check (callable_); // Catch use-after-move.
305
- return vtable_-> call ( ::sus::mem::replace_ptr (callable_, nullptr ),
306
- ::sus::forward<CallArgs>(args)...);
290
+ return (*invoke_)( ::sus::mem::replace (callable_, uintptr_t { 0 } ),
291
+ ::sus::forward<CallArgs>(args)...);
307
292
}
308
293
309
294
// / `sus::construct::From` trait implementation.
@@ -320,15 +305,15 @@ class [[sus_trivial_abi]] SFnMut<R(CallArgs...)> {
320
305
template <class RR , class ... AArgs>
321
306
friend class SFnOnce ;
322
307
323
- SFnMut (void * callable, __private::CallVtable<R , CallArgs...>* vtable )
324
- : callable_ (callable), vtable_ (vtable ) {}
308
+ SFnMut (uintptr_t callable, R (*invoke)( uintptr_t p , CallArgs... args) )
309
+ : callable_ (callable), invoke_ (invoke ) {}
325
310
326
- void * callable_;
327
- __private::CallVtable<R , CallArgs...>* vtable_ ;
311
+ uintptr_t callable_;
312
+ R (*invoke_)( uintptr_t p , CallArgs... args) ;
328
313
329
314
sus_class_trivially_relocatable (::sus::marker::unsafe_fn, decltype (callable_),
330
- decltype (vtable_ ));
331
- sus_class_never_value_field (::sus::marker::unsafe_fn, SFnMut, vtable_ ,
315
+ decltype (invoke_ ));
316
+ sus_class_never_value_field (::sus::marker::unsafe_fn, SFnMut, invoke_ ,
332
317
nullptr , nullptr );
333
318
334
319
protected:
@@ -367,26 +352,20 @@ class [[sus_trivial_abi]] SFnOnce<R(CallArgs...)> {
367
352
// / #[doc.overloads=ctor.fnpointer]
368
353
template <::sus::fn::callable::FunctionPointerMatches<R, CallArgs...> F>
369
354
SFnOnce (F ptr) noexcept {
370
- ::sus::check (ptr != nullptr );
371
- callable_ = static_cast <void *>(ptr);
372
- static auto vtable = __private::CallVtable<R, CallArgs...>{
373
- .call = &__private::Invoker<
374
- std::remove_reference_t <F>>::template call_mut<R, CallArgs...>,
375
- };
376
- vtable_ = &vtable;
355
+ ::sus::check (+ptr != nullptr );
356
+ callable_ = reinterpret_cast <uintptr_t >(+ptr);
357
+ invoke_ = &__private::Invoker<
358
+ std::remove_reference_t <F>>::template call_mut<R, CallArgs...>;
377
359
}
378
360
379
361
// / Construction from a capturing lambda or other callable object.
380
362
// /
381
363
// / #[doc.overloads=ctor.lambda]
382
364
template <::sus::fn::callable::CallableObjectReturns<R, CallArgs...> F>
383
365
SFnOnce (F&& object) noexcept {
384
- callable_ = static_cast <void *>(::sus::mem::addressof (object));
385
- static auto vtable = __private::CallVtable<R, CallArgs...>{
386
- .call = &__private::Invoker<
387
- std::remove_reference_t <F>>::template call_mut<R, CallArgs...>,
388
- };
389
- vtable_ = &vtable;
366
+ callable_ = reinterpret_cast <uintptr_t >(::sus::mem::addressof (object));
367
+ invoke_ = &__private::Invoker<
368
+ std::remove_reference_t <F>>::template call_mut<R, CallArgs...>;
390
369
}
391
370
392
371
// / Construction from SFnMut.
@@ -395,8 +374,8 @@ class [[sus_trivial_abi]] SFnOnce<R(CallArgs...)> {
395
374
// / this constructor avoids extra indirections being inserted when converting,
396
375
// / since otherwise an extra invoker call would be introduced.
397
376
SFnOnce (SFnMut<R (CallArgs...)>&& o) noexcept
398
- : callable_ (::sus::mem::replace_ptr (o.callable_ , nullptr )),
399
- vtable_ (o.vtable_ ) {
377
+ : callable_ (::sus::mem::replace (o.callable_ , uintptr_t { 0 } )),
378
+ invoke_ (o.invoke_ ) {
400
379
::sus::check (callable_); // Catch use-after-move.
401
380
}
402
381
@@ -406,25 +385,25 @@ class [[sus_trivial_abi]] SFnOnce<R(CallArgs...)> {
406
385
// / this constructor avoids extra indirections being inserted when converting,
407
386
// / since otherwise an extra invoker call would be introduced.
408
387
SFnOnce (SFn<R (CallArgs...)>&& o) noexcept
409
- : callable_ (::sus::mem::replace_ptr (o.callable_ , nullptr )),
410
- vtable_ (o.vtable_ ) {
388
+ : callable_ (::sus::mem::replace (o.callable_ , uintptr_t { 0 } )),
389
+ invoke_ (o.invoke_ ) {
411
390
::sus::check (callable_); // Catch use-after-move.
412
391
}
413
392
414
393
~SFnOnce () noexcept = default ;
415
394
416
395
SFnOnce (SFnOnce&& o) noexcept
417
- : callable_ (::sus::mem::replace_ptr (o.callable_ , nullptr )),
418
- // Not setting `o.vtable_ ` to nullptr, as vtable_ as nullptr is its
396
+ : callable_ (::sus::mem::replace (o.callable_ , uintptr_t { 0 } )),
397
+ // Not setting `o.invoke_ ` to nullptr, as invoke_ as nullptr is its
419
398
// never-value.
420
- vtable_ (o.vtable_ ) {
399
+ invoke_ (o.invoke_ ) {
421
400
::sus::check (callable_); // Catch use-after-move.
422
401
}
423
402
SFnOnce& operator =(SFnOnce&& o) noexcept {
424
- callable_ = ::sus::mem::replace_ptr (o.callable_ , nullptr );
425
- // Not setting `o.vtable_ ` to nullptr, as vtable_ as nullptr is its
403
+ callable_ = ::sus::mem::replace (o.callable_ , uintptr_t { 0 } );
404
+ // Not setting `o.invoke_ ` to nullptr, as invoke_ as nullptr is its
426
405
// never-value.
427
- vtable_ = o.vtable_ ;
406
+ invoke_ = o.invoke_ ;
428
407
::sus::check (callable_); // Catch use-after-move.
429
408
return *this ;
430
409
}
@@ -436,8 +415,8 @@ class [[sus_trivial_abi]] SFnOnce<R(CallArgs...)> {
436
415
// / Runs and consumes the closure.
437
416
inline R operator ()(CallArgs... args) && {
438
417
::sus::check (callable_); // Catch use-after-move.
439
- return vtable_-> call ( ::sus::mem::replace_ptr (callable_, nullptr ),
440
- ::sus::forward<CallArgs>(args)...);
418
+ return (*invoke_)( ::sus::mem::replace (callable_, uintptr_t { 0 } ),
419
+ ::sus::forward<CallArgs>(args)...);
441
420
}
442
421
443
422
// / `sus::construct::From` trait implementation.
@@ -454,15 +433,15 @@ class [[sus_trivial_abi]] SFnOnce<R(CallArgs...)> {
454
433
friend SFnMut<R, CallArgs...>;
455
434
friend SFn<R, CallArgs...>;
456
435
457
- SFnOnce (void * callable, __private::CallVtable<R , CallArgs...>* vtable )
458
- : callable_ (callable), vtable_ (vtable ) {}
436
+ SFnOnce (uintptr_t callable, R (*invoke)( uintptr_t p , CallArgs... args) )
437
+ : callable_ (callable), invoke_ (invoke ) {}
459
438
460
- void * callable_;
461
- __private::CallVtable<R , CallArgs...>* vtable_ ;
439
+ uintptr_t callable_;
440
+ R (*invoke_)( uintptr_t p , CallArgs... args) ;
462
441
463
442
sus_class_trivially_relocatable (::sus::marker::unsafe_fn, decltype (callable_),
464
- decltype (vtable_ ));
465
- sus_class_never_value_field (::sus::marker::unsafe_fn, SFnOnce, vtable_ ,
443
+ decltype (invoke_ ));
444
+ sus_class_never_value_field (::sus::marker::unsafe_fn, SFnOnce, invoke_ ,
466
445
nullptr , nullptr );
467
446
468
447
protected:
0 commit comments