#pragma once #include "fl/type_traits.h" #include "fl/utility.h" namespace fl { template class Ptr; // Forward declare Ptr to avoid header inclusion template class unique_ptr; // Forward declare unique_ptr to avoid header inclusion //---------------------------------------------------------------------------- // invoke implementation - equivalent to std::invoke from C++17 //---------------------------------------------------------------------------- namespace detail { // Helper to detect member data pointers template struct is_member_data_pointer : false_type {}; template struct is_member_data_pointer : integral_constant::value> {}; // Helper to detect if T is a pointer type template struct is_pointer_like : false_type {}; template struct is_pointer_like : true_type {}; template struct is_pointer_like> : true_type {}; template struct is_pointer_like> : true_type {}; // Helper to detect if we should use pointer-to-member syntax template struct use_pointer_syntax : is_pointer_like::type> {}; } // namespace detail // Main invoke function overloads // 1a. Member function pointer with object reference template auto invoke(F&& f, T1&& t1, Args&&... args) -> enable_if_t::type>::value && !detail::use_pointer_syntax::value, decltype((fl::forward(t1).*f)(fl::forward(args)...))> { return (fl::forward(t1).*f)(fl::forward(args)...); } // 1b. Member function pointer with pointer-like object template auto invoke(F&& f, T1&& t1, Args&&... args) -> enable_if_t::type>::value && detail::use_pointer_syntax::value, decltype(((*fl::forward(t1)).*f)(fl::forward(args)...))> { return ((*fl::forward(t1)).*f)(fl::forward(args)...); } // 2a. Member data pointer with object reference template auto invoke(F&& f, T1&& t1) -> enable_if_t::type>::value && !detail::use_pointer_syntax::value, decltype(fl::forward(t1).*f)> { return fl::forward(t1).*f; } // 2b. Member data pointer with pointer-like object template auto invoke(F&& f, T1&& t1) -> enable_if_t::type>::value && detail::use_pointer_syntax::value, decltype((*fl::forward(t1)).*f)> { return (*fl::forward(t1)).*f; } // 3. Regular callable (function pointer, lambda, functor) template auto invoke(F&& f, Args&&... args) -> enable_if_t::type>::value && !detail::is_member_data_pointer::type>::value, decltype(fl::forward(f)(fl::forward(args)...))> { return fl::forward(f)(fl::forward(args)...); } } // namespace fl