20#ifndef INPLACE_FUNCTION_H
21#define INPLACE_FUNCTION_H
41template <
typename Sig, std::
size_t Capacity = 4 * sizeof(
void* )>
44template <
typename R,
typename... Args, std::size_t Capacity>
51 typename = std::enable_if_t<
53 && std::is_invocable_r_v<R, const std::decay_t<F>&, Args...>>>
56 assign( std::forward<F>( aCallable ) );
88 typename = std::enable_if_t<
90 && std::is_invocable_r_v<R, const std::decay_t<F>&, Args...>>>
101 explicit operator bool()
const {
return m_invoke !=
nullptr; }
106 throw std::bad_function_call();
117 template <
typename F>
120 using DECAYED = std::decay_t<F>;
121 static_assert(
sizeof( DECAYED ) <= Capacity,
122 "callable too large for INPLACE_FUNCTION; raise its Capacity argument" );
123 static_assert(
alignof( DECAYED ) <=
alignof( std::max_align_t ),
"callable over-aligned" );
124 static_assert( std::is_nothrow_move_constructible_v<DECAYED>,
125 "callable must be nothrow move constructible for INPLACE_FUNCTION" );
127 ::new( &
m_storage ) DECAYED( std::forward<F>( aCallable ) );
129 m_invoke = [](
const void* aStorage, Args&&... aArgs ) -> R
131 return ( *
static_cast<const DECAYED*
>( aStorage ) )( std::forward<Args>( aArgs )... );
134 m_manage = [](
OP aOp,
void* aDst,
const void* aSrc )
139 static_cast<DECAYED*
>( aDst )->~DECAYED();
142 ::new( aDst ) DECAYED( std::move( *
const_cast<DECAYED*
>(
static_cast<const DECAYED*
>( aSrc ) ) ) );
145 ::new( aDst ) DECAYED( *
static_cast<const DECAYED*
>( aSrc ) );
163 if( aOther.m_manage )
176 if( aOther.m_manage )
184 alignas( std::max_align_t )
unsigned char m_storage[Capacity];
INPLACE_FUNCTION()=default
void assign(F &&aCallable)
INPLACE_FUNCTION & operator=(const INPLACE_FUNCTION &aOther)
INPLACE_FUNCTION(INPLACE_FUNCTION &&aOther) noexcept
INPLACE_FUNCTION(const INPLACE_FUNCTION &aOther)
R(*)(const void *, Args &&...) INVOKE_FN
void(*)(OP, void *, const void *) MANAGE_FN
void copyFrom(const INPLACE_FUNCTION &aOther)
INPLACE_FUNCTION & operator=(F &&aCallable)
R operator()(Args... aArgs) const
void moveFrom(INPLACE_FUNCTION &aOther)
unsigned char m_storage[Capacity]
INPLACE_FUNCTION & operator=(INPLACE_FUNCTION &&aOther) noexcept
INPLACE_FUNCTION(F &&aCallable)
A std::function-style callable wrapper that stores the target in a fixed inline buffer and never allo...