Skip to content

Commit 693bb95

Browse files
committed
added function_compose sample for the pre-requisite for Boost.Proto study
1 parent 1999df6 commit 693bb95

File tree

2 files changed

+176
-0
lines changed

2 files changed

+176
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#include <boost/utility/result_of.hpp>
2+
#include <iostream>
3+
4+
struct _;
5+
6+
template<typename Signature>
7+
struct composed_fn;
8+
9+
// An improved composed_fn template that uses the TR1 result_of
10+
// protocol to declare and compute function return types.
11+
template<typename Fn1, typename F>
12+
struct composed_fn<Fn1(F)>
13+
{
14+
// Recursively compose all nested function types to build
15+
// a composed function object out of them.
16+
typedef composed_fn<F> Fn2;
17+
18+
Fn1 fn1;
19+
Fn2 fn2;
20+
21+
explicit composed_fn(Fn1 f1 = Fn1(), Fn2 f2 = Fn2())
22+
: fn1(f1), fn2(f2)
23+
{}
24+
25+
template<typename T>
26+
auto operator()(T x) const -> decltype(fn1(fn2(x)))
27+
{
28+
return fn1(fn2(x));
29+
}
30+
};
31+
32+
// This specialization ends the recursion begun on line 21.
33+
// "composed_fn<Fn(_)> fn; fn(3);" is equivalent to "Fn fn; fn(3);"
34+
template<typename Fn>
35+
struct composed_fn<Fn(_)> : Fn {};
36+
37+
// TRICKSY!!! Read below for why this specialization is necessary.
38+
template<typename Fn>
39+
struct composed_fn<Fn *> : composed_fn<Fn> {};
40+
41+
////////////////////////////////////////////////////////////////////////////////
42+
//
43+
//
44+
//
45+
////////////////////////////////////////////////////////////////////////////////
46+
struct inc_t
47+
{
48+
template <typename T>
49+
T operator()(T x) const
50+
{
51+
return x + 1;
52+
}
53+
};
54+
55+
struct square_t
56+
{
57+
template <typename T>
58+
auto operator()(T x) const -> decltype(x*x)
59+
{
60+
return x * x;
61+
}
62+
};
63+
64+
////////////////////////////////////////////////////////////////////////////////
65+
//
66+
//
67+
//
68+
////////////////////////////////////////////////////////////////////////////////
69+
using namespace std;
70+
71+
int main(int argc, char const* argv[])
72+
{
73+
composed_fn<inc_t(square_t(inc_t(square_t(_))))> fn;
74+
75+
cout << fn(3) << endl;
76+
77+
return 0;
78+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#include <boost/utility/result_of.hpp>
2+
#include <iostream>
3+
4+
struct _;
5+
6+
template<typename Signature>
7+
struct composed_fn;
8+
9+
// An improved composed_fn template that uses the TR1 result_of
10+
// protocol to declare and compute function return types.
11+
template<typename Fn1, typename F>
12+
struct composed_fn<Fn1(F)>
13+
{
14+
// Recursively compose all nested function types to build
15+
// a composed function object out of them.
16+
typedef composed_fn<F> Fn2;
17+
18+
Fn1 fn1;
19+
Fn2 fn2;
20+
21+
explicit composed_fn(Fn1 f1 = Fn1(), Fn2 f2 = Fn2())
22+
: fn1(f1), fn2(f2)
23+
{}
24+
25+
template<typename Signature>
26+
struct result;
27+
28+
template<typename This, typename T>
29+
struct result<This(T)>
30+
{
31+
typedef typename boost::result_of<Fn2(T)>::type U;
32+
typedef typename boost::result_of<Fn1(U)>::type type;
33+
};
34+
35+
template<typename T>
36+
typename result<composed_fn(T)>::type
37+
operator()(T x) const
38+
//auto operator()(T x) const -> decltype(fn1(fn2(x)))
39+
{
40+
return fn1(fn2(x));
41+
}
42+
};
43+
44+
// This specialization ends the recursion begun on line 21.
45+
// "composed_fn<Fn(_)> fn; fn(3);" is equivalent to "Fn fn; fn(3);"
46+
template<typename Fn>
47+
struct composed_fn<Fn(_)> : Fn {};
48+
49+
// TRICKSY!!! Read below for why this specialization is necessary.
50+
template<typename Fn>
51+
struct composed_fn<Fn *> : composed_fn<Fn> {};
52+
53+
////////////////////////////////////////////////////////////////////////////////
54+
//
55+
//
56+
//
57+
////////////////////////////////////////////////////////////////////////////////
58+
struct inc_t
59+
{
60+
template<typename Signature>
61+
struct result;
62+
63+
template<typename This, typename T>
64+
struct result<This(T)> { typedef T type; };
65+
66+
template <typename T>
67+
T operator()(T x) const { return x + 1; }
68+
};
69+
70+
struct square_t
71+
{
72+
template<typename Signature>
73+
struct result;
74+
75+
template<typename This, typename T>
76+
struct result<This(T)> { typedef T type; };
77+
78+
template <typename T>
79+
T operator()(T x) const { return x * x; }
80+
};
81+
82+
////////////////////////////////////////////////////////////////////////////////
83+
//
84+
//
85+
//
86+
////////////////////////////////////////////////////////////////////////////////
87+
88+
using namespace std;
89+
90+
int main(int argc, char const* argv[])
91+
{
92+
composed_fn< inc_t(square_t(inc_t(square_t(_)))) > fn;
93+
//composed_fn< square_t(inc_t(_)) > fn;
94+
95+
cout << fn(3) << endl;
96+
97+
return 0;
98+
}

0 commit comments

Comments
 (0)