summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hof/example/sequence.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/hof/example/sequence.cpp')
-rw-r--r--src/boost/libs/hof/example/sequence.cpp122
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();
+}
+