def sum3(x: int, y: int, z: int): int // { x + y + z; }; def sum3y = sum3(_, 5, _); // def sum3yz = sum3y(_, 5); // def sum3yzx = sum3yz(5); // … , 15
sum3 xyz = x + y + z -- sum3x = sum3 5 -- sum3xy = sum3x 5 -- sum3xyz = sum3xy 5 -- … , 15
std::function< int(int, int, int) > f = [] ( int x, int y, int z ) { return x + y + z; }; auto f1 = carry(f); auto f2 = f1(5, 5); auto v15 = f2(5);
template< class, class, class > class CarryHolder; template< class OUT_TYPE, class... IN_TYPES, uint32_t... CAP_INDEXES, uint32_t... RES_INDEXES > class CarryHolder< std::function< OUT_TYPE ( IN_TYPES... ) >, UintContainer< CAP_INDEXES... >, // UintContainer< RES_INDEXES... > > // { public: typedef std::function< OUT_TYPE ( IN_TYPES... ) > FuncType; // typedef std::tuple< typename UnQualify< // const & typename GetNthType< CAP_INDEXES, TypeContainer<IN_TYPES...> >::Result >::Result... > CleanCapTupleType; // typedef std::function< OUT_TYPE ( typename GetNthType< RES_INDEXES, TypeContainer<IN_TYPES...> >::Result... ) > ReturnFuncType; // public: CarryHolder( FuncType const& f, typename UnQualify< typename GetNthType< CAP_INDEXES, TypeContainer<IN_TYPES...> >::Result >::Result const&... capturedValues ): _function(f), _capturedData( capturedValues... ) { }; CarryHolder( CarryHolder const& other ): _function(other._function), _capturedData( other._capturedData ) { }; // inline OUT_TYPE operator()( typename GetNthType< RES_INDEXES, TypeContainer<IN_TYPES...> >::Result... other_values ) { // return _function( std::get< CAP_INDEXES > (_capturedData)..., other_values ... ); }; private: CarryHolder(); FuncType _function; CleanCapTupleType _capturedData; }; template< class > class Carry; template< class OUT_TYPE, class... IN_TYPES > class Carry< std::function< OUT_TYPE (IN_TYPES...) > > { public: typedef typename std::function< OUT_TYPE (IN_TYPES...) > FuncType; constexpr static uint32_t ArgsCount = GetTypesLength< TypeContainer<IN_TYPES...> >::Result; Carry( Carry const& carry ): _function( carry._function ) { }; Carry( FuncType const& f ): _function( f ) { }; template< class... INNER_IN_TYPES > inline auto operator()( INNER_IN_TYPES const& ... values ) -> typename CarryHolder< FuncType, // typename UintRange< GetTypesLength< TypeContainer<INNER_IN_TYPES...> >::Result >::Result, // typename UintRangeFromTo< GetTypesLength< TypeContainer<INNER_IN_TYPES...> >::Result, ArgsCount >::Result >::ReturnFuncType // CarryHolder std::function { typedef CarryHolder< FuncType, typename UintRange< GetTypesLength< TypeContainer<INNER_IN_TYPES...> >::Result >::Result, typename UintRangeFromTo< GetTypesLength< TypeContainer<INNER_IN_TYPES...> >::Result, ArgsCount >::Result > CarryHolderSpec; return CarryHolderSpec( _function, values... ); }; private: Carry(); FuncType _function; }; template< class FUNC_TYPE > Carry<FUNC_TYPE> carry( FUNC_TYPE const& f ) // { return Carry<FUNC_TYPE>(f); };
std::function< int(int, int, int) > f = [] ( int x, int y, int z ) { return x + y + z; }; auto f1 = permute<2, 1, 0>(f);
template< class, class > class Permutation; template< class OUT_TYPE, class... IN_TYPES, uint32_t... INDEXES > class Permutation< std::function< OUT_TYPE (IN_TYPES...) >, // UintContainer< INDEXES... > > // { public: typedef std::function< OUT_TYPE (IN_TYPES...) > FuncType; typedef std::function< OUT_TYPE (typename GetNthType< INDEXES, TypeContainer<IN_TYPES...> >::Result...) > NewFuncType; Permutation( Permutation const& perm ): _function( perm._function ) { }; Permutation( FuncType const& f ): _function( f ) { }; private: // template< uint32_t... INVERSE > inline OUT_TYPE apply( UintContainer< INVERSE... >, // , .. typename GetNthType< INDEXES, TypeContainer<IN_TYPES...> >::Result... values ) { // std::tuple std::tuple< typename GetNthType< INDEXES, TypeContainer<IN_TYPES...> >::Result... > data( values... ); // std::tuple return _function( std::get< INVERSE > (data)... ); }; public: inline OUT_TYPE operator()( typename GetNthType< INDEXES, TypeContainer<IN_TYPES...> >::Result... values ) { // typename InversePermutation< UintContainer<INDEXES...> >::Result inverse; return apply( inverse, values... ); }; private: Permutation(); FuncType _function; }; // ; Permutation std::function template< uint32_t... INDEXES, class FUNC_TYPE > auto permute( FUNC_TYPE const& f ) -> typename Permutation<FUNC_TYPE, // , .. typename ComplementRange< GetArgumentsCount<FUNC_TYPE>::Result, UintContainer < INDEXES... > >::Result >::NewFuncType { typedef Permutation<FUNC_TYPE, typename ComplementRange< GetArgumentsCount<FUNC_TYPE>::Result, UintContainer < INDEXES... > >::Result > PermutationType; return PermutationType(f); };
template< uint32_t... INDEXES, class FUNC_TYPE > auto partApply( FUNC_TYPE const& f ) -> decltype(carry(permute<INDEXES...>(f))) { return carry(permute<INDEXES...>(f)); };
std::function< int(int, int, int) > f = [] ( int x, int y, int z ) { return x + y + z; }; auto f1 = permute<2>(f); // <2, 0, 1> - " "
Source: https://habr.com/ru/post/133084/
All Articles