26#ifndef JAU_FUNCTIONAL_HPP_
27#define JAU_FUNCTIONAL_HPP_
380 template<
typename R,
typename... A>
388 return std::is_trivially_copyable_v<T> &&
389 sizeof(udata.cache) >=
sizeof(T);
393 return std::is_trivially_copyable_v<T> &&
394 sizeof(udata.cache) <
sizeof(T);
398 return !std::is_trivially_copyable_v<T> ||
399 sizeof(udata.cache) <
sizeof(T);
403 return !std::is_trivially_copyable_v<T> &&
404 std::is_destructible_v<T> &&
405 std::is_copy_constructible_v<T> &&
406 std::is_move_constructible_v<T>;
420 typedef bool(*
equal_op_t)(
const delegate_t& data_lhs,
const delegate_t& data_rhs)
noexcept;
439 union target_data_t {
444 const target_func_t* m_tfunc;
448 constexpr delegate_t(
const target_func_t& tfunc) noexcept
451 assert(tfunc.size <=
sizeof(udata.cache));
455 constexpr delegate_t(
const target_func_t& tfunc,
bool) noexcept
458 udata.heap = ::malloc(m_tfunc->size);
461 constexpr bool useHeap() const noexcept {
462 return m_tfunc->non_trivial ||
static_cast<size_type
>(
sizeof(udata.cache) ) < m_tfunc->size;
465 void clear() noexcept {
466 if( useHeap() && udata.heap ) {
467 if( m_tfunc->non_trivial ) {
468 m_tfunc->non_trivial->dtor(
this);
471 udata.heap =
nullptr;
477 inline __attribute__((always_inline))
478 static delegate_t
make(const target_func_t& tfunc) noexcept
480 delegate_t target(tfunc);
481 std::memset(target.udata.cache, 0,
sizeof(target.udata.cache));
486 template<
typename T,
typename... P,
487 std::enable_if_t<use_trivial_cache<T>(),
bool> =
true>
488 inline __attribute__((always_inline))
489 static delegate_t
make(const target_func_t& tfunc, P&&... params) noexcept
491 delegate_t target(tfunc);
492 new( target.template
data<T>() ) T(std::forward<P>(params)...);
497 template<
typename T,
typename... P,
498 std::enable_if_t<use_trivial_heap<T>(),
bool> =
true>
499 inline __attribute__((always_inline))
500 static delegate_t
make(const target_func_t& tfunc, P&&... params) noexcept
502 delegate_t target(tfunc,
true);
503 new( target.template
data<T>() ) T(std::forward<P>(params)...);
508 template<
typename T,
typename... P,
509 std::enable_if_t<use_nontrivial_heap<T>(),
bool> =
true>
510 inline __attribute__((always_inline))
511 static delegate_t
make(const target_func_t& tfunc, P&&... params) noexcept
513 delegate_t target(tfunc,
true);
514 new( target.template
data<T>() ) T(std::forward<P>(params)...);
520 std::enable_if_t<!use_nontrivial_heap<T>(),
bool> =
true>
525 std::enable_if_t<use_nontrivial_heap<T>(),
bool> =
true>
528 static non_trivial_t nt {
530 [](delegate_t* i) ->
void {
537 [](delegate_t* i,
const delegate_t* o) ->
void {
541 [](delegate_t* i, delegate_t* o) ->
void {
542 new( i->template
data<T>() ) T( std::move( *( o->template
data<T>() ) ) );
551 : m_tfunc( o.m_tfunc )
554 udata.heap = ::malloc(m_tfunc->size);
556 {
jau::unsafe::errPrint(stderr,
"ABORT",
true ,
true , __func__, __FILE__, __LINE__,
"Error: bad_alloc: heap allocation failed"); abort(); }
559 if( m_tfunc->non_trivial ) {
560 m_tfunc->non_trivial->copy_ctor(
this, &o);
562 ::memcpy(udata.heap, o.udata.heap, m_tfunc->size);
565 assert(m_tfunc->size <=
sizeof(udata.cache));
566 ::memcpy(udata.cache, o.udata.cache,
sizeof(udata.cache));
571 : m_tfunc( std::move(o.m_tfunc) )
574 if( m_tfunc->non_trivial ) {
575 udata.heap = ::malloc(m_tfunc->size);
577 {
jau::unsafe::errPrint(stderr,
"ABORT",
true ,
true , __func__, __FILE__, __LINE__,
"Error: bad_alloc: heap allocation failed"); abort(); }
580 m_tfunc->non_trivial->move_ctor(
this, &o);
581 m_tfunc->non_trivial->dtor(&o);
584 udata.heap = std::move( o.udata.heap );
586 o.udata.heap =
nullptr;
588 assert(m_tfunc->size <=
sizeof(udata.cache));
589 ::memcpy(udata.cache, o.udata.cache,
sizeof(udata.cache));
599 if( !useHeap() && !o.useHeap() ) {
603 assert(m_tfunc->size <=
sizeof(udata.cache));
604 ::memcpy(udata.cache, o.udata.cache,
sizeof(udata.cache));
605 }
else if( useHeap() && o.useHeap() && m_tfunc->size >= o.m_tfunc->size ) {
607 if( m_tfunc->non_trivial ) {
608 m_tfunc->non_trivial->dtor(
this);
611 if( m_tfunc->non_trivial ) {
612 m_tfunc->non_trivial->copy_ctor(
this, &o);
614 ::memcpy(udata.heap, o.udata.heap, m_tfunc->size);
622 udata.heap = ::malloc(m_tfunc->size);
624 {
jau::unsafe::errPrint(stderr,
"ABORT",
true ,
true , __func__, __FILE__, __LINE__,
"Error: bad_alloc: heap allocation failed"); abort(); }
627 if( m_tfunc->non_trivial ) {
628 m_tfunc->non_trivial->copy_ctor(
this, &o);
630 ::memcpy(udata.heap, o.udata.heap, m_tfunc->size);
633 assert(m_tfunc->size <=
sizeof(udata.cache));
634 ::memcpy(udata.cache, o.udata.cache,
sizeof(udata.cache));
649 if( m_tfunc->non_trivial ) {
650 udata.heap = ::malloc(m_tfunc->size);
652 {
jau::unsafe::errPrint(stderr,
"ABORT",
true ,
true , __func__, __FILE__, __LINE__,
"Error: bad_alloc: heap allocation failed"); abort(); }
655 m_tfunc->non_trivial->move_ctor(
this, &o);
656 m_tfunc->non_trivial->dtor(&o);
659 udata.heap = std::move( o.udata.heap );
661 o.udata.heap =
nullptr;
663 assert(m_tfunc->size <=
sizeof(udata.cache));
664 ::memcpy(udata.cache, o.udata.cache,
sizeof(udata.cache));
670 std::enable_if_t<use_trivial_cache<T>(),
bool> =
true>
671 constexpr const T*
data() const noexcept {
675 std::enable_if_t<use_trivial_cache<T>(),
bool> =
true>
681 std::enable_if_t<use_any_heap<T>(),
bool> =
true>
682 constexpr const T*
data() const noexcept {
686 std::enable_if_t<use_any_heap<T>(),
bool> =
true>
698 return m_tfunc->cb(
const_cast<delegate_t*
>(
this), std::forward<A>(args)...);
707 constexpr bool operator==(
const delegate_t<R, A...>& rhs)
const noexcept {
708 return m_tfunc->eqop(*
this, rhs);
714 constexpr size_t heap_size() const noexcept {
return useHeap() ? m_tfunc->size : 0; }
715 constexpr size_t cached_size() const noexcept {
return !useHeap() ? m_tfunc->size : 0; }
718 constexpr size_t target_size() const noexcept {
return m_tfunc->size; }
735 template<
typename R,
typename... A>
745 constexpr static bool equal_op_impl(
const delegate_type& lhs,
const delegate_type& rhs)
noexcept {
746 return lhs.type() == rhs.type();
749 constexpr static void dtor(delegate_type* target)
noexcept {
752 static const delegate_type::target_func_t& get() {
753 static typename delegate_type::target_func_t tf { invoke_impl, equal_op_impl,
nullptr, 0, target_type::null };
758 inline __attribute__((always_inline))
760 return delegate_type::make(get());
774 template<
typename R,
typename C0,
typename C1,
typename... A>
781#if defined(__GNUC__) && !defined(__clang__)
789 typedef R(*function_t)(C0*, A...);
795 constexpr data_type(
C1 *_base, R(C0::*_method)(A...)) noexcept
801 function = (function_t)(_base->*_method);
806 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A&&... args) {
808 return ( *(d->function) )(d->base, std::forward<A>(args)...);
811 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
812 const data_type* lhs = lhs_.template data<const data_type>();
813 const data_type* rhs = rhs_.template data<const data_type>();
815 ( lhs_.type() == rhs_.type() &&
816 lhs->base == rhs->base &&
817 lhs->function== rhs->function
833 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A&&... args) {
835 return (d->base->*d->method)(std::forward<A>(args)...);
838 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
839 const data_type* lhs = lhs_.template data<const data_type>();
840 const data_type* rhs = rhs_.template data<const data_type>();
842 ( lhs_.type() == rhs_.type() &&
843 lhs->base == rhs->base &&
844 lhs->method == rhs->method
848 static const delegate_type::target_func_t& get() {
849 static typename delegate_type::target_func_t tf {
850 invoke_impl, equal_op_impl,
851 delegate_type::template getNonTrivialCtor<data_type>(),
852 sizeof(data_type), target_type::member };
866 inline __attribute__((always_inline))
868 std::enable_if_t<
std::is_base_of_v<C0,
C1>,
bool> = true) noexcept
870 return base && method ? delegate_type::template
make<data_type>( get(), base, method ) : func::null_target_t<R, A...>::delegate();
882 template<
typename R,
typename... A>
895 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A&&... args) {
896 return ( *(data->template data<data_type>()->function) )(std::forward<A>(args)...);
899 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
900 const data_type* lhs = lhs_.template data<const data_type>();
901 const data_type* rhs = rhs_.template data<const data_type>();
903 ( lhs_.type() == rhs_.type() &&
904 lhs->function== rhs->function
907 static const delegate_type::target_func_t& get() {
908 static typename delegate_type::target_func_t tf {
909 invoke_impl, equal_op_impl,
910 delegate_type::template getNonTrivialCtor<data_type>(),
911 sizeof(data_type), target_type::free };
916 inline __attribute__((always_inline))
931 template<
typename R,
typename L,
typename...A>
947 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A&&... args) {
948 return ( data->template data<data_type>()->function )(std::forward<A>(args)...);
951 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
952 const data_type* lhs = lhs_.template data<const data_type>();
953 const data_type* rhs = rhs_.template data<const data_type>();
955 ( lhs_.type() == rhs_.type() &&
956 lhs->detail_size() == rhs->detail_size() &&
957 lhs->sig == rhs->sig &&
958 0 == ::memcmp((
void*)&lhs->function, (
void*)&rhs->function,
sizeof(lhs->function))
961 static const delegate_type::target_func_t& get() {
962 static typename delegate_type::target_func_t tf {
963 invoke_impl, equal_op_impl,
964 delegate_type::template getNonTrivialCtor<data_type>(),
965 sizeof(data_type), target_type::lambda };
970 inline __attribute__((always_inline))
1022 template<
typename R,
typename L,
typename...A>
1043 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A&&... args) {
1044 return ( data->template data<data_type>()->function )(*data, std::forward<A>(args)...);
1047 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
1048 const data_type* lhs = lhs_.template data<const data_type>();
1049 const data_type* rhs = rhs_.template data<const data_type>();
1050 return lhs == rhs ||
1051 ( lhs_.type() == rhs_.type() &&
1052 lhs->detail_size() == rhs->detail_size() &&
1053 lhs->sig == rhs->sig &&
1054 0 == ::memcmp((
void*)&lhs->function, (
void*)&rhs->function,
sizeof(lhs->function))
1057 static const delegate_type::target_func_t& get() {
1058 static typename delegate_type::target_func_t tf {
1059 invoke_impl, equal_op_impl,
1060 delegate_type::template getNonTrivialCtor<data_type>(),
1061 sizeof(data_type), target_type::ylambda };
1066 inline __attribute__((always_inline))
1081 template<
typename R,
typename I,
typename... A>
1098 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A&&... args) {
1100 return (*d->function)(d->data, std::forward<A>(args)...);
1103 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
1104 const data_type* lhs = lhs_.template data<const data_type>();
1105 const data_type* rhs = rhs_.template data<const data_type>();
1106 return lhs == rhs ||
1107 ( lhs_.type() == rhs_.type() &&
1108 lhs->function == rhs->function &&
1109 lhs->data == rhs->data
1112 static const delegate_type::target_func_t& get() {
1113 static typename delegate_type::target_func_t tf {
1114 invoke_impl, equal_op_impl,
1115 delegate_type::template getNonTrivialCtor<data_type>(),
1116 sizeof(data_type), target_type::capval };
1121 inline __attribute__((always_inline))
1126 inline __attribute__((always_inline))
1141 template<
typename R,
typename I,
typename... A>
1156 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A&&... args) {
1158 return (*d->function)(d->data_ptr, std::forward<A>(args)...);
1161 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
1162 const data_type* lhs = lhs_.template data<const data_type>();
1163 const data_type* rhs = rhs_.template data<const data_type>();
1164 return lhs == rhs ||
1165 ( lhs_.type() == rhs_.type() &&
1166 lhs->function == rhs->function &&
1167 lhs->data_ptr == rhs->data_ptr
1170 static const delegate_type::target_func_t& get() {
1171 static typename delegate_type::target_func_t tf {
1172 invoke_impl, equal_op_impl,
1173 delegate_type::template getNonTrivialCtor<data_type>(),
1174 sizeof(data_type), target_type::capref };
1179 inline __attribute__((always_inline))
1196 template<
typename R,
typename... A>
1202 typedef std::function<R(A...)> function_t;
1214 constexpr static R invoke_impl(delegate_type*
__restrict_cxx__ const data, A&&... args) {
1217 return d->function(std::forward<A>(args)...);
1223 constexpr static bool equal_op_impl(
const delegate_type& lhs_,
const delegate_type& rhs_)
noexcept {
1224 const data_type* lhs = lhs_.template data<const data_type>();
1225 const data_type* rhs = rhs_.template data<const data_type>();
1226 return lhs == rhs ||
1227 ( lhs_.type() == rhs_.type() &&
1228 lhs->id == rhs->id &&
1229 lhs->detail_size() && rhs->detail_size()
1232 static const delegate_type::target_func_t& get() {
1233 static typename delegate_type::target_func_t tf {
1234 invoke_impl, equal_op_impl,
1235 delegate_type::template getNonTrivialCtor<data_type>(),
1236 sizeof(data_type), target_type::std };
1241 inline __attribute__((always_inline))
1251 return static_cast<uint32_t
>(rhs);
1264 template<
typename Signature>
1277 template<
typename R,
typename... A>
1299 : target(
func::null_target_t<R, A...>::delegate() )
1311 : target( func::null_target_t<R, A...>::delegate() )
1324 : target( std::move(_delegate) )
1336 : target(
func::free_target_t<R, A...>::delegate(
func) )
1350 template<
typename L,
1351 std::enable_if_t<!std::is_same_v<L, std::shared_ptr<delegate_type>> &&
1352 !std::is_pointer_v<L> &&
1353 !std::is_same_v<L, R(A...)> &&
1354 !std::is_same_v<L,
function<R(A...)>>
1357 : target( func::lambda_target_t<R, L, A...>::delegate(
func) )
1371 template<
typename L>
1374 return function<R(A...)>( jau::func::lambda_target_t<R, L, A...>::delegate(
func), 0 );
1392 template<
typename L>
1395 return function<R(A...)>( jau::func::ylambda_target_t<R, L, A...>::delegate(
func), 0 );
1410 template<
typename C0,
typename C1>
1412 : target(
func::member_target_t<R, C0,
C1, A...>::delegate(base, mfunc) )
1432 template<
typename I>
1434 : target(
func::capval_target_t<R, I, A...>::delegate(data,
func) )
1454 template<
typename I>
1456 : target(
func::capval_target_t<R, I, A...>::delegate(
std::forward<I>(data),
func) )
1474 template<
typename I>
1476 : target(
func::capref_target_t<R, I, A...>::delegate(data_ptr,
func) )
1494 : target( func::std_target_t<R, A...>::delegate(
id,
func) )
1509 explicit constexpr operator bool() const noexcept {
return !
is_null(); }
1520 constexpr size_t size() const noexcept {
return target.heap_size() +
sizeof(*this); }
1523 constexpr size_t target_size() const noexcept {
return target.target_size(); }
1530 std::string s(
"function<");
1532 .append(std::to_string(
target_size() )).append(
" / ( delegate_t ")
1533 .append(std::to_string(
sizeof( target ) )).append(
" + target_vdata ")
1534 .append(std::to_string( target.heap_size() )).append(
" -> ")
1535 .append(std::to_string(
size() )).append(
" ), trivial_cpy ")
1536 .append(std::to_string( target.is_trivially_copyable() )).append(
" ) ");
1541 return target(std::forward<A>(args)...);
1544 return target(std::forward<A>(args)...);
1548 return target.operator==(rhs.target);
1570 template<
typename Rl,
typename... Al,
template <
typename...>
class Fl = function,
1571 typename Rr,
typename... Ar,
template <
typename...>
class Fr = function,
1572 std::enable_if_t< !std::is_same_v< Fl<Rl(Al...)>, Fr<Rr(Ar...)> >
1596 template<
typename Rl,
typename... Al,
template <
typename...>
class Fl = function,
1597 typename Rr,
typename... Ar,
template <
typename...>
class Fr = function,
1598 std::enable_if_t< std::is_same_v< Fl<Rl(Al...)>, Fr<Rr(Ar...)> >
1600 bool operator==(
const function<Rl(Al...)>& lhs,
const function<Rr(Ar...)>& rhs)
noexcept
1601 {
return lhs.operator==( rhs ); }
1617 template<
typename Rl,
typename... Al,
template <
typename...>
typename Fl =
function,
1618 typename Rr,
typename... Ar,
template <
typename...>
typename Fr =
function>
1620 {
return !( lhs == rhs ); }
1629 template<
class R,
class... A>
1640 template<
class R,
class... A>
1642 {
return !( lhs == nullptr ); }
1651 template<
class R,
class... A>
1662 template<
class R,
class... A>
1664 {
return !(
nullptr == rhs ); }
1681 template<
typename R,
typename C0,
typename C1,
typename... A>
1684 return function<R(A...)>( func::member_target_t<R, C0, C1, A...>::delegate(base, mfunc), 0 );
1701 template<
typename R,
typename C,
typename... A>
1704 return function<R(A...)>( func::member_target_t<R, C, C, A...>::delegate(base, mfunc), 0 );
1721 template<
typename C0,
typename C1,
typename... A>
1724 return function<void(A...)>( func::member_target_t<void, C0, C1, A...>::delegate(base, mfunc), 0 );
1740 template<
typename C,
typename... A>
1743 return function<void(A...)>( func::member_target_t<void, C, C, A...>::delegate(base, mfunc), 0 );
1758 template<
typename R,
typename... A>
1761 return function<R(A...)>( func::free_target_t<R, A...>::delegate(
func), 0 );
1775 template<
typename... A>
1778 return function<void(A...)>( func::free_target_t<void, A...>::delegate(
func), 0 );
1799 template<
typename R,
typename I,
typename... A>
1802 return function<R(A...)>( func::capval_target_t<R, I, A...>::delegate(data,
func), 0 );
1822 template<
typename I,
typename... A>
1825 return function<void(A...)>( func::capval_target_t<void, I, A...>::delegate(data,
func), 0 );
1846 template<
typename R,
typename I,
typename... A>
1849 return function<R(A...)>( func::capval_target_t<R, I, A...>::delegate(std::forward<I>(data),
func), 0 );
1869 template<
typename I,
typename... A>
1872 return function<void(A...)>( func::capval_target_t<void, I, A...>::delegate(std::forward<I>(data),
func), 0 );
1891 template<
typename R,
typename I,
typename... A>
1894 return function<R(A...)>( func::capref_target_t<R, I, A...>::delegate(data_ptr,
func), 0 );
1912 template<
typename I,
typename... A>
1915 return function<void(A...)>( func::capref_target_t<void, I, A...>::delegate(data_ptr,
func), 0 );
1933 template<
typename R,
typename... A>
1936 return function<R(A...)>( func::std_target_t<R, A...>::delegate(
id, std::move(
func)), 0 );
1953 template<
typename... A>
1956 return function<void(A...)>( func::std_target_t<void, A...>::delegate(
id, std::move(
func)), 0 );
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.
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() noexcept
delegate_t & operator=(delegate_t &&o) 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.
delegate_t(delegate_t &&o) noexcept
constexpr R operator()(A &&... args) const
Delegated fast path target function invocation, see above.
static constexpr bool use_nontrivial_heap()
delegate_t & operator=(const delegate_t &o) 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 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.
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...
std::string_view 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.
constexpr std::string_view name(const Bool v) noexcept
#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.
@ ylambda
Denotes a func::ylambda_target_t.
uint_bytes_t< sizeof(unsigned long int)> nsize_t
Natural 'size_t' alternative using uint<XX>_t with xx = sizeof(unsigned long int)*8 as its natural si...
void errPrint(FILE *out, const char *msg, bool addErrno, bool addBacktrace, const char *func, const char *file, const int line, const char *format,...) noexcept
__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
data_type(L &&_function) 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(I *_data_ptr, R(*_function)(I *, A...)) noexcept
data_type(const I &_data, R(*_function)(I &, A...)) noexcept
constexpr size_t detail_size() const noexcept
data_type(uint64_t id_, function_t &&function_) noexcept
constexpr data_type(C1 *_base, R(C0::*_method)(A...)) noexcept
equal_op_t eqop
Delegated specialization equality operator.
R(* invocation_t)(delegate_t *__restrict_cxx__ const data, A &&... args)
void(* dtor_t)(delegate_t *)
non_trivial_t * non_trivial
void(* copy_ctor_t)(delegate_t *, const delegate_t *)