rec/fplus/fwd.hpp

123 lines
3.5 KiB
C++
Raw Normal View History

2020-03-18 06:42:46 +00:00
// 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<decltype(fplus_fwd_x)>(fplus_fwd_x)); \
}; \
}
#define fplus_fwd_define_fn_1(fplus_fwd_define_fn_1_name) \
template <typename P1> \
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<decltype(fplus_fwd_x)>(fplus_fwd_x)); \
}; \
}
#define fplus_fwd_define_fn_2(fplus_fwd_define_fn_2_name) \
template <typename P1, typename P2> \
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<decltype(fplus_fwd_x)>(fplus_fwd_x)); \
}; \
}
#define fplus_fwd_define_fn_3(fplus_fwd_define_fn_3_name) \
template <typename P1, typename P2, typename P3> \
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<decltype(fplus_fwd_x)>(fplus_fwd_x)); \
}; \
}
#define fplus_fwd_define_fn_4(fplus_fwd_define_fn_4_name) \
template <typename P1, typename P2, typename P3, typename P4> \
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<decltype(fplus_fwd_x)>(fplus_fwd_x)); \
}; \
}
#define fplus_fwd_flip_define_fn_1(fplus_fwd_flip_define_fn_1_name) \
namespace flip \
{ \
template <typename P2> \
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<decltype(fplus_fwd_flip_x)>(fplus_fwd_flip_x), p2); \
}; \
} \
} // namespace flip
namespace internal
{
template<typename F, typename G>
struct compose_helper{
compose_helper(F f, G g) : f_(f), g_(g) {}
template<typename X>
decltype(auto) operator()(X&& x) const
{
return g_(f_(std::forward<X>(x)));
}
private:
F f_;
G g_;
};
} // namespace internal
template<typename F, typename G>
auto compose(F f, G g) {
return internal::compose_helper<F, G> {f, g};
}
template<typename F1, typename... Fs>
auto compose(F1 f, Fs ... args)
{
return compose(f, compose(args...));
}
template<typename X, typename... Fs>
auto apply(X&& x, Fs ... args)
{
return compose(args...)(std::forward<X>(x));
}
template<typename X, typename F>
auto apply(X&& x, F f)
{
return f(std::forward<X>(x));
}
#include "fwd_instances.autogenerated_defines"
} // namespace fwd
} // namespace fplus