static_assert( __cplusplus >= 2023'02 ); #pragma once #include #include #include namespace Alepha::Hydrogen::Functional ::detail:: reverse_arguments_m { inline namespace exports { auto reverse_arguments( Concepts::Functional auto func ); } template< typename Result, typename ... Arguments > auto build_reverse_tuple_lambda( std::function< Result ( Arguments... ) > func ) { return std::function { [func]( decltype( Utility::tuple::reverse( std::declval< std::tuple< Arguments... > >() ) ) params ) { return std::apply( func, Utility::tuple::reverse( params ) ); } }; } template< typename ReturnType, typename ... Arguments > auto bind_args_to_tuple_function( std::function< ReturnType ( std::tuple< Arguments... > ) > func ) { return std::function { [func]( Arguments... args ) -> ReturnType { return func( std::tuple{ args... } ); } }; } auto exports::reverse_arguments( Concepts::Functional auto func ) { return bind_args_to_tuple_function( build_reverse_tuple_lambda( std::function{ func } ) ); } } namespace Alepha::Hydrogen::Functional::inline exports::inline reverse_arguments_m { using namespace detail::reverse_arguments_m::exports; }