• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2017 Paul Fultz II
3     sequence.cpp
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 /*=============================================================================
8     Copyright (c) 2016 Paul Fultz II
9     print.cpp
10     Distributed under the Boost Software License, Version 1.0. (See accompanying
11     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
12 ==============================================================================*/
13 
14 #include "example.h"
15 #include <tuple>
16 
17 using namespace boost::hof;
18 
19 // Transform each element of a tuple by calling f
20 BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_transform) = [](auto&& sequence, auto f)
__anonfe6e5b820102(auto&& sequence, auto f) 21 {
22     return unpack(proj(f, construct<std::tuple>()))(std::forward<decltype(sequence)>(sequence));
23 };
24 // Call f on each element of tuple
25 BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_for_each) = [](auto&& sequence, auto f)
__anonfe6e5b820202(auto&& sequence, auto f) 26 {
27     return unpack(proj(f))(std::forward<decltype(sequence)>(sequence));
28 };
29 // Fold over tuple using a f as the binary operator
30 BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_fold) = [](auto&& sequence, auto f)
__anonfe6e5b820302(auto&& sequence, auto f) 31 {
32     return unpack(fold(f))(std::forward<decltype(sequence)>(sequence));
33 };
34 // Concat multiple tuples
35 BOOST_HOF_STATIC_FUNCTION(tuple_cat) = unpack(construct<std::tuple>());
36 // Join a tuple of tuples into just a tuple
37 BOOST_HOF_STATIC_FUNCTION(tuple_join) = unpack(tuple_cat);
38 // Filter elements in a tuple using a predicate
39 BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_filter) = [](auto&& sequence, auto predicate)
__anonfe6e5b820402(auto&& sequence, auto predicate) 40 {
41     return compose(tuple_join, tuple_transform)(
42         std::forward<decltype(sequence)>(sequence),
43         [&](auto&& x)
44         {
45             return first_of(
46                 if_(predicate(std::forward<decltype(x)>(x)))(pack),
47                 always(pack())
48             )(std::forward<decltype(x)>(x));
49         }
50     );
51 };
52 // Zip two tuples together
53 BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_zip_with) = [](auto&& sequence1, auto&& sequence2, auto f)
__anonfe6e5b820602(auto&& sequence1, auto&& sequence2, auto f) 54 {
55     auto&& functions = tuple_transform(
56         std::forward<decltype(sequence1)>(sequence1),
57         [&](auto&& x)
58         {
59             return [&](auto&& y)
60             {
61                 return f(std::forward<decltype(x)>(x), std::forward<decltype(y)>(y));
62             };
63         }
64     );
65     auto combined = unpack(capture(construct<std::tuple>())(combine))(functions);
66     return unpack(combined)(std::forward<decltype(sequence2)>(sequence2));
67 };
68 // Dot product of a tuple
69 BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_dot) = [](auto&& a, auto&& b)
__anonfe6e5b820902(auto&& a, auto&& b) 70 {
71     auto product = tuple_zip_with(a, b, [](auto x, auto y) { return x*y; });
72     return tuple_fold(product, [](auto x, auto y) { return x+y; });
73 };
74 
run_each()75 void run_each()
76 {
77     auto t = std::make_tuple(1, 2);
78     tuple_for_each(t, [](int i) { std::cout << i << std::endl; });
79 }
80 
run_transform()81 void run_transform()
82 {
83     auto t = std::make_tuple(1, 2);
84     auto r = tuple_transform(t, [](int i) { return i*i; });
85     assert(r == std::make_tuple(1, 4));
86     (void)r;
87 }
88 
run_filter()89 void run_filter()
90 {
91     auto t = std::make_tuple(1, 2, 'x', 3);
92     auto r = tuple_filter(t, [](auto x) { return std::is_same<int, decltype(x)>(); });
93     assert(r == std::make_tuple(1, 2, 3));
94     (void)r;
95 }
96 
run_zip()97 void run_zip()
98 {
99     auto t1 = std::make_tuple(1, 2);
100     auto t2 = std::make_tuple(3, 4);
101     auto p = tuple_zip_with(t1, t2, [](auto x, auto y) { return x*y; });
102     int r = tuple_fold(p, [](auto x, auto y) { return x+y; });
103     assert(r == (1*3 + 4*2));
104     (void)r;
105 }
106 
run_dot()107 void run_dot()
108 {
109     auto t1 = std::make_tuple(1, 2);
110     auto t2 = std::make_tuple(3, 4);
111     int r = tuple_dot(t1, t2);
112     assert(r == (1*3 + 4*2));
113     (void)r;
114 }
115 
main()116 int main()
117 {
118     run_transform();
119     run_filter();
120     run_zip();
121 }
122 
123