/* Zeta API - Z/classes/Functor.hpp ______ ______________ ___ |__ / | ___|___ ___|/ \ / /__| __| | | / - \ /______|_____| |__| /__/ \__\ Copyright (C) 2006-2024 Manuel Sainz de Baranda y Goñi. Released under the terms of the GNU Lesser General Public License v3. */ #ifndef Z_classes_Functor_HPP #define Z_classes_Functor_HPP #include #if Z_HAS(ObjectMemberFunction) # ifdef Z_WITH_OBJECTIVE_C_RUNTIME # include # include # endif # define Z_HAS_Functor 1 namespace Zeta { template class Functor; template class Functor { private: typedef r (* Call)(const Functor *, typename Type

::to_forwardable...); typedef void (* Destroy)(Functor *); Call call; Destroy destroy; union { r (* function)(p...); struct {r (NaT::* function)(p...); NaT *object; } object_member_function; # if Z_HAS(ObjectSelector) struct {SEL selector; id object; } object_selector; # endif } target; struct Callers { static Z_INLINE Call function() Z_NOTHROW { return [](const Functor *functor, typename Type

::to_forwardable... arguments) -> r {return functor->target.function(arguments...);}; } static Z_INLINE Call object_member_function() Z_NOTHROW { return [](const Functor *functor, typename Type

::to_forwardable... arguments) -> r { return (functor->target.object_member_function.object->* functor->target.object_member_function.function) (arguments...); }; } # if Z_HAS(ObjectSelector) static Z_INLINE Call object_selector() Z_NOTHROW { return [](const Functor *functor, typename Type

::to_forwardable... arguments) { return (cast(ObjectiveC::send()))( functor->target.object_selector.object, functor->target.object_selector.selector, arguments...); }; } # endif }; public: Z_CT(CPP11) Functor() Z_NOTHROW : call(Z_NULL), destroy(Z_NULL) {} # ifdef Z_NULLPTR Z_CT(CPP11) Functor(NullPtr) Z_NOTHROW : call(Z_NULL), destroy(Z_NULL) {} # endif Z_INLINE Functor(r (* function)(p...)) Z_NOTHROW : call(Callers::function()), destroy(Z_NULL) {target.function = function;} template ::is_void || Type::is_class) && Type::is_member_function_pointer && TypeIsSame::flow::to_function::end::to_unqualified, r(p...)>::value >::type> Z_INLINE Functor(o *object, m function) Z_NOTHROW : call(Callers::object_member_function()), destroy(Z_NULL) { target.object_member_function.function = reinterpret_cast(function); target.object_member_function.object = reinterpret_cast(const_cast::to_unqualified *>(object)); } template ::is_class && Type::is_member_function_pointer && TypeIsSame::flow::to_function::end::to_unqualified, r(p...)>::value >::type> Z_INLINE Functor(const o &object, m function) Z_NOTHROW : call(Callers::object_member_function()), destroy(Z_NULL) { target.object_member_function.function = reinterpret_cast(function); target.object_member_function.object = reinterpret_cast(const_cast::to_unqualified *>(&object)); } Z_INLINE Functor(const ObjectMemberFunction &object_member_function) Z_NOTHROW : call(Callers::object_member_function()), destroy(Z_NULL) { target.object_member_function.function = object_member_function.function; target.object_member_function.object = object_member_function.object; } # if Z_HAS(TypeIsConvertible) template ::is_class && TypeIsConvertible::value >::type> Z_INLINE Functor(const o &object) Z_NOTHROW : call(Callers::function()), destroy(Z_NULL) {target.function = (r(*)(p...))object;} // TODO: cast # endif # if Z_HAS(ObjectSelector) Z_INLINE Functor(id object, SEL selector) Z_NOTHROW : call(Callers::object_selector()), destroy(Z_NULL) { target.object_selector.selector = selector; target.object_selector.object = object; } Z_INLINE Functor(const ObjectSelector &object_selector) Z_NOTHROW : call(Callers::object_selector()), destroy(Z_NULL) { target.object_selector.selector = object_selector.selector; target.object_selector.object = object_selector.object; } # endif Z_INLINE ~Functor() {if (destroy) destroy(this);} Z_CT(CPP11) operator Boolean() const Z_NOTHROW {return call != Z_NULL;} Z_INLINE r operator ()(typename Type

::to_forwardable... arguments) const {return call(this, arguments...);} }; } #endif #endif // Z_classes_Functor_HPP