|
| VLINK_EXPORT void | vlink::detail::throw_bad_function_call () |
| |
| template<typename ReturnT , typename... ArgsT, size_t SboSizeT> |
| void | vlink::swap (Function< ReturnT(ArgsT...), SboSizeT > &lhs, Function< ReturnT(ArgsT...), SboSizeT > &rhs) noexcept |
| | Free-function swap; defers to the member swap of lhs. More...
|
| |
| template<typename ReturnT , typename... ArgsT, size_t SboSizeT> |
| bool | vlink::operator== (const Function< ReturnT(ArgsT...), SboSizeT > &cb, std::nullptr_t) noexcept |
| | Equality with nullptr; true when cb has no stored target. More...
|
| |
| template<typename ReturnT , typename... ArgsT, size_t SboSizeT> |
| bool | vlink::operator== (std::nullptr_t, const Function< ReturnT(ArgsT...), SboSizeT > &cb) noexcept |
| | Commutative overload of operator==(Function, nullptr_t). More...
|
| |
| template<typename ReturnT , typename... ArgsT, size_t SboSizeT> |
| bool | vlink::operator!= (const Function< ReturnT(ArgsT...), SboSizeT > &cb, std::nullptr_t) noexcept |
| | Inequality with nullptr; true when cb stores a target. More...
|
| |
| template<typename ReturnT , typename... ArgsT, size_t SboSizeT> |
| bool | vlink::operator!= (std::nullptr_t, const Function< ReturnT(ArgsT...), SboSizeT > &cb) noexcept |
| | Commutative overload of operator!=(Function, nullptr_t). More...
|
| |
| template<typename ReturnT , typename... ArgsT, size_t SboSizeT> |
| void | vlink::swap (MoveFunction< ReturnT(ArgsT...), SboSizeT > &lhs, MoveFunction< ReturnT(ArgsT...), SboSizeT > &rhs) noexcept |
| | Free-function swap; defers to the member swap of lhs. More...
|
| |
| template<typename ReturnT , typename... ArgsT, size_t SboSizeT> |
| bool | vlink::operator== (const MoveFunction< ReturnT(ArgsT...), SboSizeT > &cb, std::nullptr_t) noexcept |
| | Equality with nullptr; true when cb has no stored target. More...
|
| |
| template<typename ReturnT , typename... ArgsT, size_t SboSizeT> |
| bool | vlink::operator== (std::nullptr_t, const MoveFunction< ReturnT(ArgsT...), SboSizeT > &cb) noexcept |
| | Commutative overload of operator==(MoveFunction, nullptr_t). More...
|
| |
| template<typename ReturnT , typename... ArgsT, size_t SboSizeT> |
| bool | vlink::operator!= (const MoveFunction< ReturnT(ArgsT...), SboSizeT > &cb, std::nullptr_t) noexcept |
| | Inequality with nullptr; true when cb stores a target. More...
|
| |
| template<typename ReturnT , typename... ArgsT, size_t SboSizeT> |
| bool | vlink::operator!= (std::nullptr_t, const MoveFunction< ReturnT(ArgsT...), SboSizeT > &cb) noexcept |
| | Commutative overload of operator!=(MoveFunction, nullptr_t). More...
|
| |
Pool-backed type-erased callables: copyable vlink::Function and move-only vlink::MoveFunction.
vlink::Function tracks the public surface of std::function while vlink::MoveFunction tracks std::move_only_function. Both store the target in a configurable small-buffer region (64 bytes by default) and spill to vlink::MemoryPool::global_instance when the target does not fit. This eliminates the heap-allocation surprise common to std::function on hot paths while still permitting arbitrarily large closures.
- Comparison vs the standard library
| Property | std::function | std::move_only_function | vlink::Function | vlink::MoveFunction |
| Copyable | yes | no | yes | no |
| Movable | yes | yes | yes | yes |
| Default SBO size | ~16-24 B (impl) | ~16-24 B (impl) | 64 B (tunable) | 64 B (tunable) |
| Spill allocator | ::operator new | ::operator new | MemoryPool tier | MemoryPool tier |
| Empty-call behaviour | throws bad_func | UB | throws bad_func | throws bad_func |
| RTTI inspection | target / type | not provided | target / type | target / type |
- Storage predicate (kIsInline)
- A target
FunctorT is held inline only when all three hold simultaneously: sizeof(FunctorT) <= SboSizeT, alignof(FunctorT) <= alignof(std::max_align_t) and FunctorT is nothrow move-constructible. Anything else goes to the heap path through MemoryPool::global_instance; the original sizeof / alignof values are passed back to deallocate so the block returns to its source tier. This mirrors libstdc++'s __stored_locally rule.
- SBO sizing
- Both wrappers expose
SboSizeT as the second non-type template argument. Convenience aliases vlink::LargeFunction / vlink::LargeMoveFunction pick 256 bytes; the bound SboSizeT >= sizeof(void*) is enforced by static_assert so the heap-fallback pointer always fits in the SBO. Distinct SboSizeT instantiations are distinct types but may still convert through the generic functor path – a Function<Sig, 64> serves as a regular callable target for Function<Sig, 256>.
- Empty-state propagation
- Constructing or assigning from any of these sources yields an empty wrapper with no vtable and no allocation:
- an empty function-wrapper source (
std::function, vlink::Function, and – when the target is MoveFunction – std::move_only_function / vlink::MoveFunction);
- a null raw function pointer;
- a null pointer-to-member.
- Exception safety
- Copy operations use copy-and-swap and offer the strong guarantee;
swap, move construction and move assignment are noexcept. The kIsInline predicate guarantees that inline-path moves never throw, while the heap path simply moves a pointer. Inline construction uses placement-new directly into the SBO; heap construction is wrapped in try / catch so the pool block is returned on a constructor exception.
- Object-lifetime model
- Inline targets are placement-new'd into the SBO. Heap storage holds a
FunctorT*; the pointer object's lifetime is started explicitly via ::new(dst) FunctorT*(p) at every site that introduces a new slot, avoiding reliance on the C++20 [intro.object]/10 implicit-object rule and keeping the code well-defined under C++17. Subsequent accesses go through std::launder to satisfy [basic.life]/8.
- RTTI surface
- When
__cpp_rtti is defined both wrappers expose target_type() and target<FunctorT>() with std::function semantics. This is an extension over std::move_only_function which omits target inspection.
- Example
int y = f(21);
auto pkg = std::packaged_task<int()>([] { return 7; });
mf();
Copyable type-erased callable analogue of std::function with a tunable SBO and pool spill.
Definition: functional.h:131
Move-only type-erased callable analogue of std::move_only_function with pool spill.
Definition: functional.h:134
- Note
- Only the unqualified
ReturnT(ArgsT...) signature is specialised; cv / ref / noexcept-qualified function types resolve to the undefined primary template (hard error). This header self-defines VLINK_ENABLE_BASE_FUNCTIONAL when absent so normal builds always select the VLink implementation; the standard-library alias block at the bottom is not exposed via a compile-command opt-out.