123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- /*=============================================================================
- 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();
- }
|