-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathcompose.cpp
More file actions
98 lines (77 loc) · 2.29 KB
/
compose.cpp
File metadata and controls
98 lines (77 loc) · 2.29 KB
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
#include <boost/utility/result_of.hpp>
#include <iostream>
struct _;
template<typename Signature>
struct composed_fn;
// An improved composed_fn template that uses the TR1 result_of
// protocol to declare and compute function return types.
template<typename Fn1, typename F>
struct composed_fn<Fn1(F)>
{
// Recursively compose all nested function types to build
// a composed function object out of them.
typedef composed_fn<F> Fn2;
Fn1 fn1;
Fn2 fn2;
explicit composed_fn(Fn1 f1 = Fn1(), Fn2 f2 = Fn2())
: fn1(f1), fn2(f2)
{}
template<typename Signature>
struct result;
template<typename This, typename T>
struct result<This(T)>
{
typedef typename boost::result_of<Fn2(T)>::type U;
typedef typename boost::result_of<Fn1(U)>::type type;
};
template<typename T>
typename result<composed_fn(T)>::type
operator()(T x) const
//auto operator()(T x) const -> decltype(fn1(fn2(x)))
{
return fn1(fn2(x));
}
};
// This specialization ends the recursion begun on line 21.
// "composed_fn<Fn(_)> fn; fn(3);" is equivalent to "Fn fn; fn(3);"
template<typename Fn>
struct composed_fn<Fn(_)> : Fn {};
// TRICKSY!!! Read below for why this specialization is necessary.
template<typename Fn>
struct composed_fn<Fn *> : composed_fn<Fn> {};
////////////////////////////////////////////////////////////////////////////////
//
//
//
////////////////////////////////////////////////////////////////////////////////
struct inc_t
{
template<typename Signature>
struct result;
template<typename This, typename T>
struct result<This(T)> { typedef T type; };
template <typename T>
T operator()(T x) const { return x + 1; }
};
struct square_t
{
template<typename Signature>
struct result;
template<typename This, typename T>
struct result<This(T)> { typedef T type; };
template <typename T>
T operator()(T x) const { return x * x; }
};
////////////////////////////////////////////////////////////////////////////////
//
//
//
////////////////////////////////////////////////////////////////////////////////
using namespace std;
int main(int argc, char const* argv[])
{
composed_fn< inc_t(square_t(inc_t(square_t(_)))) > fn;
//composed_fn< square_t(inc_t(_)) > fn;
cout << fn(3) << endl;
return 0;
}