123 lines
3.5 KiB
C++
Executable File
123 lines
3.5 KiB
C++
Executable File
// 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
|