diff options
Diffstat (limited to 'src/boost/libs/hof/example/sequence.cpp')
-rw-r--r-- | src/boost/libs/hof/example/sequence.cpp | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/src/boost/libs/hof/example/sequence.cpp b/src/boost/libs/hof/example/sequence.cpp new file mode 100644 index 00000000..3ecdd659 --- /dev/null +++ b/src/boost/libs/hof/example/sequence.cpp @@ -0,0 +1,122 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + sequence.cpp + 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) +==============================================================================*/ +/*============================================================================= + Copyright (c) 2016 Paul Fultz II + print.cpp + 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) +==============================================================================*/ + +#include "example.h" +#include <tuple> + +using namespace boost::hof; + +// Transform each element of a tuple by calling f +BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_transform) = [](auto&& sequence, auto f) +{ + return unpack(proj(f, construct<std::tuple>()))(std::forward<decltype(sequence)>(sequence)); +}; +// Call f on each element of tuple +BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_for_each) = [](auto&& sequence, auto f) +{ + return unpack(proj(f))(std::forward<decltype(sequence)>(sequence)); +}; +// Fold over tuple using a f as the binary operator +BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_fold) = [](auto&& sequence, auto f) +{ + return unpack(fold(f))(std::forward<decltype(sequence)>(sequence)); +}; +// Concat multiple tuples +BOOST_HOF_STATIC_FUNCTION(tuple_cat) = unpack(construct<std::tuple>()); +// Join a tuple of tuples into just a tuple +BOOST_HOF_STATIC_FUNCTION(tuple_join) = unpack(tuple_cat); +// Filter elements in a tuple using a predicate +BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_filter) = [](auto&& sequence, auto predicate) +{ + return compose(tuple_join, tuple_transform)( + std::forward<decltype(sequence)>(sequence), + [&](auto&& x) + { + return first_of( + if_(predicate(std::forward<decltype(x)>(x)))(pack), + always(pack()) + )(std::forward<decltype(x)>(x)); + } + ); +}; +// Zip two tuples together +BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_zip_with) = [](auto&& sequence1, auto&& sequence2, auto f) +{ + auto&& functions = tuple_transform( + std::forward<decltype(sequence1)>(sequence1), + [&](auto&& x) + { + return [&](auto&& y) + { + return f(std::forward<decltype(x)>(x), std::forward<decltype(y)>(y)); + }; + } + ); + auto combined = unpack(capture(construct<std::tuple>())(combine))(functions); + return unpack(combined)(std::forward<decltype(sequence2)>(sequence2)); +}; +// Dot product of a tuple +BOOST_HOF_STATIC_LAMBDA_FUNCTION(tuple_dot) = [](auto&& a, auto&& b) +{ + auto product = tuple_zip_with(a, b, [](auto x, auto y) { return x*y; }); + return tuple_fold(product, [](auto x, auto y) { return x+y; }); +}; + +void run_each() +{ + auto t = std::make_tuple(1, 2); + tuple_for_each(t, [](int i) { std::cout << i << std::endl; }); +} + +void run_transform() +{ + auto t = std::make_tuple(1, 2); + auto r = tuple_transform(t, [](int i) { return i*i; }); + assert(r == std::make_tuple(1, 4)); + (void)r; +} + +void run_filter() +{ + auto t = std::make_tuple(1, 2, 'x', 3); + auto r = tuple_filter(t, [](auto x) { return std::is_same<int, decltype(x)>(); }); + assert(r == std::make_tuple(1, 2, 3)); + (void)r; +} + +void run_zip() +{ + auto t1 = std::make_tuple(1, 2); + auto t2 = std::make_tuple(3, 4); + auto p = tuple_zip_with(t1, t2, [](auto x, auto y) { return x*y; }); + int r = tuple_fold(p, [](auto x, auto y) { return x+y; }); + assert(r == (1*3 + 4*2)); + (void)r; +} + +void run_dot() +{ + auto t1 = std::make_tuple(1, 2); + auto t2 = std::make_tuple(3, 4); + int r = tuple_dot(t1, t2); + assert(r == (1*3 + 4*2)); + (void)r; +} + +int main() +{ + run_transform(); + run_filter(); + run_zip(); +} + |