File: fwd.hpp

package info (click to toggle)
libfplus 0.2.13-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,904 kB
  • sloc: cpp: 27,543; javascript: 634; sh: 105; python: 103; makefile: 6
file content (122 lines) | stat: -rw-r--r-- 3,556 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// 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