26#ifndef JAU_FUNCTIONAL_HPP_
27#define JAU_FUNCTIONAL_HPP_
379 template<
typename R,
typename... A>
387 return std::is_trivially_copyable_v<T> &&
388 sizeof(udata.cache) >=
sizeof(T);
392 return std::is_trivially_copyable_v<T> &&
393 sizeof(udata.cache) <
sizeof(T);
397 return !std::is_trivially_copyable_v<T> ||
398 sizeof(udata.cache) <
sizeof(T);
402 return !std::is_trivially_copyable_v<T> &&
403 std::is_destructible_v<T> &&
404 std::is_copy_constructible_v<T> &&
405 std::is_move_constructible_v<T>;
419 typedef bool(*
equal_op_t)(
const delegate_t& data_lhs,
const delegate_t& data_rhs)
noexcept;
438 union target_data_t {
443 const target_func_t* m_tfunc;
447 constexpr delegate_t(
const target_func_t& tfunc) noexcept
452 constexpr delegate_t(
const target_func_t& tfunc,
bool) noexcept
455 udata.heap = ::malloc(m_tfunc->size);
458 constexpr bool useHeap() const noexcept {
459 return m_tfunc->non_trivial ||
static_cast<size_type
>(
sizeof(udata.cache) ) < m_tfunc->size;
462 void clear() noexcept {
463 if( useHeap() && udata.heap ) {
464 if( m_tfunc->non_trivial ) {
465 m_tfunc->non_trivial->dtor(
this);
468 udata.heap =
nullptr;
474 static delegate_t
make(
const target_func_t& tfunc)
noexcept
476 return delegate_t(tfunc);
480 template<
typename T,
typename... P,
481 std::enable_if_t<use_trivial_cache<T>(),
bool> =
true>
482 static delegate_t
make(
const target_func_t& tfunc, P... params)
noexcept
484 delegate_t target(tfunc);
485 new( target.template
data<T>() ) T(params...);
490 template<
typename T,
typename... P,
491 std::enable_if_t<use_trivial_heap<T>(),
bool> =
true>
492 static delegate_t
make(
const target_func_t& tfunc, P... params)
noexcept
494 delegate_t target(tfunc,
true);
495 new( target.template
data<T>() ) T(params...);
500 template<
typename T,
typename... P,
501 std::enable_if_t<use_nontrivial_heap<T>(),
bool> =
true>
502 static delegate_t
make(
const target_func_t& tfunc, P... params)
noexcept
504 delegate_t target(tfunc,
true);
505 new( target.template
data<T>() ) T(params...);
511 std::enable_if_t<!use_nontrivial_heap<T>(),
bool> =
true>
516 std::enable_if_t<use_nontrivial_heap<T>(),
bool> =
true>
519 static non_trivial_t nt {
521 [](delegate_t* i) ->
void {
528 [](delegate_t* i,
const delegate_t* o) ->
void {
532 [](delegate_t* i, delegate_t* o) ->
void {
533 new( i->template
data<T>() ) T( std::move( *( o->template
data<T>() ) ) );
542 : m_tfunc( o.m_tfunc )
545 udata.heap = ::malloc(m_tfunc->size);
547 ABORT(
"Error: bad_alloc: heap allocation failed");
550 if( m_tfunc->non_trivial ) {
551 m_tfunc->non_trivial->copy_ctor(
this, &o);
553 ::memcpy(udata.heap, o.udata.heap, m_tfunc->size);
556 ::memcpy(udata.cache, o.udata.cache, m_tfunc->size);
561 : m_tfunc( std::move(o.m_tfunc) )
564 if( m_tfunc->non_trivial ) {
565 udata.heap = ::malloc(m_tfunc->size);
567 ABORT(
"Error: bad_alloc: heap allocation failed");
570 m_tfunc->non_trivial->move_ctor(
this, &o);
571 m_tfunc->non_trivial->dtor(&o);
574 udata.heap = std::move( o.udata.heap );
576 o.udata.heap =
nullptr;
578 ::memcpy(udata.cache, o.udata.cache, m_tfunc->size);
588 if( !useHeap() && !o.useHeap() ) {
592 ::memcpy(udata.cache, o.udata.cache, m_tfunc->size);
593 }
else if( useHeap() && o.useHeap() && m_tfunc->size >= o.m_tfunc->size ) {
595 if( m_tfunc->non_trivial ) {
596 m_tfunc->non_trivial->dtor(
this);
599 if( m_tfunc->non_trivial ) {
600 m_tfunc->non_trivial->copy_ctor(
this, &o);
602 ::memcpy(udata.heap, o.udata.heap, m_tfunc->size);
610 udata.heap = ::malloc(m_tfunc->size);
612 ABORT(
"Error: bad_alloc: heap allocation failed");
615 if( m_tfunc->non_trivial ) {
616 m_tfunc->non_trivial->copy_ctor(
this, &o);
618 ::memcpy(udata.heap, o.udata.heap, m_tfunc->size);
621 ::memcpy(udata.cache, o.udata.cache, m_tfunc->size);
636 if( m_tfunc->non_trivial ) {
637 udata.heap = ::malloc(m_tfunc->size);
639 ABORT(
"Error: bad_alloc: heap allocation failed");
642 m_tfunc->non_trivial->move_ctor(
this, &o);
643 m_tfunc->non_trivial->dtor(&o);
646 udata.heap = std::move( o.udata.heap );
648 o.udata.heap =
nullptr;
650 ::memcpy(udata.cache, o.udata.cache, m_tfunc->size);
656 std::enable_if_t<use_trivial_cache<T>(),
bool> =
true>
657 constexpr const T*
data() const noexcept {
661 std::enable_if_t<use_trivial_cache<T>(),
bool> =
true>
667 std::enable_if_t<use_any_heap<T>(),
bool> =
true>
668 constexpr const T*
data() const noexcept {
672 std::enable_if_t<use_any_heap<T>(),
bool> =
true>
684 return m_tfunc->cb(
const_cast<delegate_t*
>(
this), args...);
693 constexpr bool operator==(
const delegate_t<R, A...>& rhs)
const noexcept {
694 return m_tfunc->eqop(*
this, rhs);
700 constexpr size_t heap_size() const noexcept {
return useHeap() ? m_tfunc->size : 0; }
701 constexpr size_t cached_size() const noexcept {
return !useHeap() ? m_tfunc->size : 0; }
704 constexpr size_t target_size() const noexcept {
return m_tfunc->size; }
721 template<
typename R,
typename... A>
731 constexpr static bool equal_op_impl(
const delegate_type& lhs,
const delegate_type& rhs)
noexcept {
732 return lhs.type() == rhs.type();
735 constexpr static void dtor(delegate_type* target)
noexcept {
738 static const delegate_type::target_func_t& get() {
739 static typename delegate_type::target_func_t tf { invoke_impl, equal_op_impl,
nullptr, 0,
target_type::null };
745 return delegate_type::make(get());
759 template<
typename R,
typename C0,
typename C1,
typename... A>
766#if defined(__GNUC__) && !defined(__clang__)
774 typedef R(*function_t)(C0*, A...);
780 constexpr data_type(
C1 *_base, R(C0::*_method)(A...)) noexcept
786 function = (function_t)(_base->*_method);
791 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A... args) {
793 return ( *(d->function) )(d->base, args...);
796 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
797 const data_type* lhs = lhs_.template data<const data_type>();
798 const data_type* rhs = rhs_.template data<const data_type>();
800 ( lhs_.type() == rhs_.type() &&
801 lhs->base == rhs->base &&
802 lhs->function== rhs->function
818 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A... args) {
820 return (d->base->*d->method)(args...);
823 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
824 const data_type* lhs = lhs_.template data<const data_type>();
825 const data_type* rhs = rhs_.template data<const data_type>();
827 ( lhs_.type() == rhs_.type() &&
828 lhs->base == rhs->base &&
829 lhs->method == rhs->method
833 static const delegate_type::target_func_t& get() {
834 static typename delegate_type::target_func_t tf {
835 invoke_impl, equal_op_impl,
836 delegate_type::template getNonTrivialCtor<data_type>(),
852 std::enable_if_t<std::is_base_of_v<C0, C1>,
bool> =
true) noexcept
866 template<
typename R,
typename... A>
879 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A... args) {
880 return ( *(data->template data<data_type>()->function) )(args...);
883 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
884 const data_type* lhs = lhs_.template data<const data_type>();
885 const data_type* rhs = rhs_.template data<const data_type>();
887 ( lhs_.type() == rhs_.type() &&
888 lhs->function== rhs->function
891 static const delegate_type::target_func_t& get() {
892 static typename delegate_type::target_func_t tf {
893 invoke_impl, equal_op_impl,
894 delegate_type::template getNonTrivialCtor<data_type>(),
914 template<
typename R,
typename L,
typename...A>
930 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A... args) {
931 return ( data->template data<data_type>()->function )(args...);
934 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
935 const data_type* lhs = lhs_.template data<const data_type>();
936 const data_type* rhs = rhs_.template data<const data_type>();
938 ( lhs_.type() == rhs_.type() &&
939 lhs->detail_size() == rhs->detail_size() &&
940 lhs->sig == rhs->sig &&
941 0 == ::memcmp((
void*)&lhs->function, (
void*)&rhs->function,
sizeof(lhs->function))
944 static const delegate_type::target_func_t& get() {
945 static typename delegate_type::target_func_t tf {
946 invoke_impl, equal_op_impl,
947 delegate_type::template getNonTrivialCtor<data_type>(),
1004 template<
typename R,
typename L,
typename...A>
1025 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A... args) {
1026 return ( data->template data<data_type>()->function )(*data, args...);
1029 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
1030 const data_type* lhs = lhs_.template data<const data_type>();
1031 const data_type* rhs = rhs_.template data<const data_type>();
1032 return lhs == rhs ||
1033 ( lhs_.type() == rhs_.type() &&
1034 lhs->detail_size() == rhs->detail_size() &&
1035 lhs->sig == rhs->sig &&
1036 0 == ::memcmp((
void*)&lhs->function, (
void*)&rhs->function,
sizeof(lhs->function))
1039 static const delegate_type::target_func_t& get() {
1040 static typename delegate_type::target_func_t tf {
1041 invoke_impl, equal_op_impl,
1042 delegate_type::template getNonTrivialCtor<data_type>(),
1043 sizeof(data_type), target_type::ylambda };
1062 template<
typename R,
typename I,
typename... A>
1079 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A... args) {
1081 return (*d->function)(d->data, args...);
1084 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
1085 const data_type* lhs = lhs_.template data<const data_type>();
1086 const data_type* rhs = rhs_.template data<const data_type>();
1087 return lhs == rhs ||
1088 ( lhs_.type() == rhs_.type() &&
1089 lhs->function == rhs->function &&
1090 lhs->data == rhs->data
1093 static const delegate_type::target_func_t& get() {
1094 static typename delegate_type::target_func_t tf {
1095 invoke_impl, equal_op_impl,
1096 delegate_type::template getNonTrivialCtor<data_type>(),
1120 template<
typename R,
typename I,
typename... A>
1135 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A... args) {
1137 return (*d->function)(d->data_ptr, args...);
1140 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
1141 const data_type* lhs = lhs_.template data<const data_type>();
1142 const data_type* rhs = rhs_.template data<const data_type>();
1143 return lhs == rhs ||
1144 ( lhs_.type() == rhs_.type() &&
1145 lhs->function == rhs->function &&
1146 lhs->data_ptr == rhs->data_ptr
1149 static const delegate_type::target_func_t& get() {
1150 static typename delegate_type::target_func_t tf {
1151 invoke_impl, equal_op_impl,
1152 delegate_type::template getNonTrivialCtor<data_type>(),
1174 template<
typename R,
typename... A>
1184 data_type(uint64_t id_, std::function<R(A...)> function_) noexcept
1190 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A... args) {
1193 return d->function(args...);
1199 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
1200 const data_type* lhs = lhs_.template data<const data_type>();
1201 const data_type* rhs = rhs_.template data<const data_type>();
1202 return lhs == rhs ||
1203 ( lhs_.type() == rhs_.type() &&
1204 lhs->id == rhs->id &&
1205 lhs->detail_size() && rhs->detail_size()
1208 static const delegate_type::target_func_t& get() {
1209 static typename delegate_type::target_func_t tf {
1210 invoke_impl, equal_op_impl,
1211 delegate_type::template getNonTrivialCtor<data_type>(),
1226 return static_cast<uint32_t
>(rhs);
1239 template<
typename Signature>
1252 template<
typename R,
typename... A>
1274 : target(
func::null_target_t<R, A...>::delegate() )
1299 : target( std::move(_delegate) )
1311 : target(
func::free_target_t<R, A...>::delegate(
func) )
1325 template<
typename L,
1326 std::enable_if_t<!std::is_same_v<L, std::shared_ptr<delegate_type>> &&
1327 !std::is_pointer_v<L> &&
1328 !std::is_same_v<L, R(A...)> &&
1329 !std::is_same_v<L,
function<R(A...)>>
1346 template<
typename L>
1367 template<
typename L>
1370 return function<R(A...)>( jau::func::ylambda_target_t<R, L, A...>::delegate(
func), 0 );
1385 template<
typename C0,
typename C1>
1387 : target(
func::member_target_t<R, C0,
C1, A...>::delegate(base, mfunc) )
1407 template<
typename I>
1409 : target(
func::capval_target_t<R, I, A...>::delegate(data,
func) )
1429 template<
typename I>
1431 : target(
func::capval_target_t<R, I, A...>::delegate(
std::forward<I>(data),
func) )
1449 template<
typename I>
1451 : target(
func::capref_target_t<R, I, A...>::delegate(data_ptr,
func) )
1484 explicit constexpr operator bool() const noexcept {
return !
is_null(); }
1495 constexpr size_t size() const noexcept {
return target.heap_size() +
sizeof(*this); }
1498 constexpr size_t target_size() const noexcept {
return target.target_size(); }
1506 std::to_string(
target_size() ) +
" / ( delegate_t " +
1507 std::to_string(
sizeof( target ) ) +
" + target_vdata " +
1508 std::to_string( target.heap_size() ) +
" -> "+
1509 std::to_string(
size() ) +
" ), trivial_cpy "+
1510 std::to_string( target.is_trivially_copyable() ) +
" ) ";
1514 return target(args...);
1517 return target(args...);
1521 return target.operator==(rhs.target);
1543 template<
typename Rl,
typename... Al,
template <
typename...>
class Fl = function,
1544 typename Rr,
typename... Ar,
template <
typename...>
class Fr = function,
1545 std::enable_if_t< !std::is_same_v< Fl<Rl(Al...)>, Fr<Rr(Ar...)> >
1569 template<
typename Rl,
typename... Al,
template <
typename...>
class Fl = function,
1570 typename Rr,
typename... Ar,
template <
typename...>
class Fr = function,
1571 std::enable_if_t< std::is_same_v< Fl<Rl(Al...)>, Fr<Rr(Ar...)> >
1573 bool operator==(
const function<Rl(Al...)>& lhs,
const function<Rr(Ar...)>& rhs)
noexcept
1574 {
return lhs.operator==( rhs ); }
1590 template<
typename Rl,
typename... Al,
template <
typename...>
typename Fl =
function,
1591 typename Rr,
typename... Ar,
template <
typename...>
typename Fr =
function>
1593 {
return !( lhs == rhs ); }
1602 template<
class R,
class... A>
1613 template<
class R,
class... A>
1615 {
return !( lhs == nullptr ); }
1624 template<
class R,
class... A>
1635 template<
class R,
class... A>
1637 {
return !(
nullptr == rhs ); }
1654 template<
typename R,
typename C0,
typename C1,
typename... A>
1674 template<
typename R,
typename C,
typename... A>
1694 template<
typename C0,
typename C1,
typename... A>
1713 template<
typename C,
typename... A>
1731 template<
typename R,
typename... A>
1748 template<
typename... A>
1772 template<
typename R,
typename I,
typename... A>
1795 template<
typename I,
typename... A>
1819 template<
typename R,
typename I,
typename... A>
1842 template<
typename I,
typename... A>
1864 template<
typename R,
typename I,
typename... A>
1885 template<
typename I,
typename... A>
1906 template<
typename R,
typename... A>
1926 template<
typename... A>
Class template jau::function is a general-purpose static-polymorphic function wrapper.
function(delegate_type _delegate, int dummy) noexcept
Internally used delegate_t<R(A...)> constructor.
constexpr R operator()(A... args) const
function(function &&o) noexcept=default
constexpr bool operator!=(const function< R(A...)> &rhs) const noexcept
function(I &&data, R(*func)(I &, A...)) noexcept
Capture by value (move) function constructor.
function(C1 *base, R(C0::*mfunc)(A...)) noexcept
Member function constructor.
std::string toString() const
Return a string representation of this instance.
constexpr func::target_type type() const noexcept
Return the jau::func::type of this instance.
function(R(*func)(A...)) noexcept
Free function constructor.
constexpr R operator()(A... args)
function(const function &o) noexcept=default
function() noexcept
Null function constructor.
function(I *data_ptr, R(*func)(I *, A...)) noexcept
Capture by-reference function constructor.
constexpr bool is_null() const noexcept
Returns true if this instance does not hold a callable target function, i.e.
function(const I &data, R(*func)(I &, A...)) noexcept
Capture by value (copy) function constructor.
function(std::nullptr_t) noexcept
Null function constructor.
static function< R(A...)> bind_ylambda(L func) noexcept
Y combinator Lambda function bind factory.
func::delegate_t< R, A... > delegate_type
The delegated target function type, i.e.
constexpr bool operator==(const function< R(A...)> &rhs) const noexcept
constexpr size_t target_size() const noexcept
Returns the size of underlying target function.
R result_type
The target function return type R.
constexpr bool is_target_trivially_copyable() const noexcept
Returns true if the underlying target function is TriviallyCopyable.
function & operator=(function &&o) noexcept=default
function(L func) noexcept
Lambda function constructor.
jau::type_info signature() const noexcept
Returns signature of this function prototype R(A...) w/o underlying target function object.
function & operator=(const function &o) noexcept=default
constexpr size_t size() const noexcept
Return the total size of this instance, may include heap allocated by delegate for bigger target func...
function(uint64_t id, std::function< R(A...)> func) noexcept
std::function constructor
static function< R(A...)> bind_lambda(L func) noexcept
Lambda function bind factory.
func::capref_target_t implementation for functions using a reference to a captured value,...
func::capval_target_t implementation for functions using a copy of a captured value,...
constexpr size_t cached_size() const noexcept
constexpr bool operator==(const delegate_t< R, A... > &rhs) const noexcept
Delegated fast path target function equality operator.
static delegate_t make(const target_func_t &tfunc) noexcept
constexpr T * data() noexcept
static non_trivial_t * getNonTrivialCtor() noexcept
constexpr size_t heap_size() const noexcept
constexpr bool is_trivially_copyable() const noexcept
Returns true if the underlying target function is TriviallyCopyable.
static delegate_type delegate(const I &data, R(*function)(I &, A...)) noexcept
static delegate_type delegate() noexcept
static delegate_type delegate(L function) noexcept
delegate_t & operator=(delegate_t &&o) noexcept
static delegate_t make(const target_func_t &tfunc, P... params) noexcept
constexpr size_t target_size() const noexcept
Returns the size of underlying target function.
jau::nsize_t size_type
Utilize a natural size type jau::nsize_t.
static delegate_type delegate(R(*function)(A...)) noexcept
static delegate_type delegate(I *data_ptr, R(*function)(I *, A...)) noexcept
delegate_t(delegate_t &&o) noexcept
static constexpr bool use_nontrivial_heap()
static delegate_type delegate(C1 *base, R(C0::*method)(A...), std::enable_if_t< std::is_base_of_v< C0, C1 >, bool >=true) noexcept
Construct a delegate_t<R, A...> instance from given this base-pointer and member-function.
delegate_t & operator=(const delegate_t &o) noexcept
static delegate_type delegate(uint64_t id, std::function< R(A...)> function) noexcept
constexpr const T * data() const noexcept
static constexpr bool use_trivial_heap()
static constexpr bool use_trivial_cache()
delegate_t< R, A... > delegate_type
static delegate_type delegate(I &&data, R(*function)(I &, A...)) noexcept
static constexpr bool use_any_heap()
delegate_t(const delegate_t &o) noexcept
constexpr target_type type() const noexcept
Return the func::target_type of this invocation function wrapper.
constexpr R operator()(A... args) const
Delegated fast path target function invocation, see above.
func::free_target_t implementation for free functions, identifiable as func::target_type::free via ja...
func::lambda_target_t implementation for lambda closures, identifiable as func::target_type::lambda v...
func::member_target_t implementation for class member functions, identifiable as func::target_type::m...
func::null_target_t implementation for no function.
func::std_target_t implementation for std::function instances, identifiable as func::target_type::std...
Class template jau::function is a general-purpose static-polymorphic function wrapper.
Generic type information using either Runtime type information (RTTI) or Compile time type informatio...
#define ABORT(...)
Use for unconditional ::abort() call with given messages, prefix '[elapsed_time] ABORT @ file:line fu...
std::string to_string(const endian_t v) noexcept
Return std::string representation of the given endian.
#define PRAGMA_DISABLE_WARNING_PMF_CONVERSIONS
#define PRAGMA_DISABLE_WARNING_PEDANTIC
#define PRAGMA_DISABLE_WARNING_PUSH
#define final_opt
Optional generic usage of final keyword w/o negative performance impact.
constexpr std::enable_if_t< sizeof(Dest)==sizeof(Source) &&std::is_pointer_v< Source > &&std::is_pointer_v< Dest >, Dest > pointer_cast(const Source &src) noexcept
A constexpr pointer cast implementation for C++17, inspired by C++20 bit_cast<>(arg).
#define __restrict_cxx__
Wrap C++ extension __restrict__ covering C99's restrict feature keyword.
#define PRAGMA_DISABLE_WARNING_POP
jau::type_info make_ctti(bool identity_instance=false) noexcept
Constructs a jau::type_info instance based on given type T using template Compile Time Type Informati...
jau::function< R(A...)> bind_member(C1 *base, R(C0::*mfunc)(A...)) noexcept
Bind given class instance and non-void member function to an anonymous function using func_member_tar...
jau::function< R(A...)> bind_free(R(*func)(A...)) noexcept
Bind given non-void free-function to an anonymous function using func::free_target_t.
jau::function< R(A...)> bind_std(uint64_t id, std::function< R(A...)> func) noexcept
Bind given non-void std::function to an anonymous function using func::std_target_t.
target_type
func::target_type identifier for the target function delegate_t<R, A...> object, exposed by jau::func...
jau::function< R(A...)> bind_capval(const I &data, R(*func)(I &, A...)) noexcept
Bind given data by copying the captured value and the given non-void function to an anonymous functio...
jau::function< R(A...)> bind_capref(I *data_ptr, R(*func)(I *, A...)) noexcept
Bind given data by passing the captured reference (pointer) to the value and non-void function to an ...
constexpr uint32_t number(const func::target_type rhs) noexcept
@ null
Denotes a func::null_target_t.
@ lambda
Denotes a func::lambda_target_t.
@ capval
Denotes a func::capval_target_t.
@ capref
Denotes a func::capref_target_t.
@ member
Denotes a func::member_target_t.
@ free
Denotes a func::free_target_t.
@ std
Denotes a func::std_target_t.
@ ylambda
Denotes a func::ylambda_target_t.
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
bool operator==(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
bool operator!=(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
C++ conform Pointer to Member Function (PMF)
data_type(R(*_function)(A...)) noexcept
bool(* equal_op_t)(const delegate_t &data_lhs, const delegate_t &data_rhs) noexcept
invocation_t cb
Delegated specialization callback.
void(* move_ctor_t)(delegate_t *, delegate_t *)
data_type(I &&_data, R(*_function)(I &, A...)) noexcept
data_type(uint64_t id_, std::function< R(A...)> function_) noexcept
data_type(I *_data_ptr, R(*_function)(I *, A...)) noexcept
R(* invocation_t)(delegate_t *__restrict_cxx__ const data, A... args)
data_type(const I &_data, R(*_function)(I &, A...)) noexcept
constexpr size_t detail_size() const noexcept
data_type(L _function) noexcept
constexpr data_type(C1 *_base, R(C0::*_method)(A...)) noexcept
equal_op_t eqop
Delegated specialization equality operator.
void(* dtor_t)(delegate_t *)
non_trivial_t * non_trivial
void(* copy_ctor_t)(delegate_t *, const delegate_t *)