// Copyright 2015, Tobias Hermann and the FunctionalPlus contributors. // https://github.com/Dobiasd/FunctionalPlus // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #pragma once namespace fplus { namespace fwd { // Partial currying. // Allow to generically bind all but parameters except the last one. // The lambda paramter ist named fplus_fwd_x instead of x // because gcc can produce unjustified shadow warnings. see: // http://stackoverflow.com/questions/41208811/parameter-of-returned-generic-lambda-allegedly-shadows-parameter-of-free-functio #define fplus_fwd_define_fn_0(fplus_fwd_define_fn_0_name) \ inline auto fplus_fwd_define_fn_0_name() \ { \ return [](auto&& fplus_fwd_x) \ { \ return fplus::fplus_fwd_define_fn_0_name(std::forward(fplus_fwd_x)); \ }; \ } #define fplus_fwd_define_fn_1(fplus_fwd_define_fn_1_name) \ template \ auto fplus_fwd_define_fn_1_name(P1 p1) \ { \ return [p1](auto&& fplus_fwd_x) \ { \ return fplus::fplus_fwd_define_fn_1_name(p1, std::forward(fplus_fwd_x)); \ }; \ } #define fplus_fwd_define_fn_2(fplus_fwd_define_fn_2_name) \ template \ auto fplus_fwd_define_fn_2_name(P1 p1, P2 p2) \ { \ return [p1, p2](auto&& fplus_fwd_x) \ { \ return fplus::fplus_fwd_define_fn_2_name(p1, p2, std::forward(fplus_fwd_x)); \ }; \ } #define fplus_fwd_define_fn_3(fplus_fwd_define_fn_3_name) \ template \ auto fplus_fwd_define_fn_3_name(P1 p1, P2 p2, P3 p3) \ { \ return [p1, p2, p3](auto&& fplus_fwd_x) \ { \ return fplus::fplus_fwd_define_fn_3_name(p1, p2, p3, std::forward(fplus_fwd_x)); \ }; \ } #define fplus_fwd_define_fn_4(fplus_fwd_define_fn_4_name) \ template \ auto fplus_fwd_define_fn_4_name(P1 p1, P2 p2, P3 p3, P4 p4) \ { \ return [p1, p2, p3, p4](auto&& fplus_fwd_x) \ { \ return fplus::fplus_fwd_define_fn_4_name(p1, p2, p3, p4, std::forward(fplus_fwd_x)); \ }; \ } #define fplus_fwd_flip_define_fn_1(fplus_fwd_flip_define_fn_1_name) \ namespace flip \ { \ template \ auto fplus_fwd_flip_define_fn_1_name(P2 p2) \ { \ return [p2](auto&& fplus_fwd_flip_x) \ { \ return fplus::fplus_fwd_flip_define_fn_1_name(std::forward(fplus_fwd_flip_x), p2); \ }; \ } \ } // namespace flip namespace internal { template struct compose_helper{ compose_helper(F f, G g) : f_(f), g_(g) {} template decltype(auto) operator()(X&& x) const { return g_(f_(std::forward(x))); } private: F f_; G g_; }; } // namespace internal template auto compose(F f, G g) { return internal::compose_helper {f, g}; } template auto compose(F1 f, Fs ... args) { return compose(f, compose(args...)); } template auto apply(X&& x, Fs ... args) { return compose(args...)(std::forward(x)); } template auto apply(X&& x, F f) { return f(std::forward(x)); } #include "fwd_instances.autogenerated_defines" } // namespace fwd } // namespace fplus