summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hof/example
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/hof/example')
-rw-r--r--src/boost/libs/hof/example/example.h67
-rw-r--r--src/boost/libs/hof/example/in.cpp81
-rw-r--r--src/boost/libs/hof/example/pointfree.cpp33
-rw-r--r--src/boost/libs/hof/example/print.cpp96
-rw-r--r--src/boost/libs/hof/example/sequence.cpp122
-rw-r--r--src/boost/libs/hof/example/static_if.cpp43
6 files changed, 442 insertions, 0 deletions
diff --git a/src/boost/libs/hof/example/example.h b/src/boost/libs/hof/example/example.h
new file mode 100644
index 000000000..0d88b1727
--- /dev/null
+++ b/src/boost/libs/hof/example/example.h
@@ -0,0 +1,67 @@
+/*=============================================================================
+ Copyright (c) 2016 Paul Fultz II
+ example.h
+ 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)
+==============================================================================*/
+
+#ifndef BOOST_HOF_GUARD_EXAMPLE_H
+#define BOOST_HOF_GUARD_EXAMPLE_H
+
+#include <boost/hof/alias.hpp>
+#include <boost/hof/always.hpp>
+#include <boost/hof/apply_eval.hpp>
+#include <boost/hof/apply.hpp>
+#include <boost/hof/arg.hpp>
+#include <boost/hof/proj.hpp>
+#include <boost/hof/capture.hpp>
+#include <boost/hof/combine.hpp>
+#include <boost/hof/compose.hpp>
+#include <boost/hof/fold.hpp>
+#include <boost/hof/first_of.hpp>
+#include <boost/hof/construct.hpp>
+#include <boost/hof/decay.hpp>
+#include <boost/hof/decorate.hpp>
+#include <boost/hof/eval.hpp>
+#include <boost/hof/fix.hpp>
+#include <boost/hof/flip.hpp>
+#include <boost/hof/flow.hpp>
+#include <boost/hof/function.hpp>
+#include <boost/hof/identity.hpp>
+#include <boost/hof/if.hpp>
+#include <boost/hof/implicit.hpp>
+#include <boost/hof/indirect.hpp>
+#include <boost/hof/infix.hpp>
+#include <boost/hof/is_invocable.hpp>
+#include <boost/hof/lambda.hpp>
+#include <boost/hof/lazy.hpp>
+#include <boost/hof/lift.hpp>
+#include <boost/hof/limit.hpp>
+#include <boost/hof/match.hpp>
+#include <boost/hof/mutable.hpp>
+#include <boost/hof/pack.hpp>
+#include <boost/hof/partial.hpp>
+#include <boost/hof/pipable.hpp>
+#include <boost/hof/placeholders.hpp>
+#include <boost/hof/protect.hpp>
+#include <boost/hof/repeat.hpp>
+#include <boost/hof/repeat_while.hpp>
+#include <boost/hof/result.hpp>
+#include <boost/hof/returns.hpp>
+#include <boost/hof/reveal.hpp>
+#include <boost/hof/reverse_fold.hpp>
+#include <boost/hof/rotate.hpp>
+#include <boost/hof/static.hpp>
+#include <boost/hof/tap.hpp>
+#include <boost/hof/unpack.hpp>
+
+#include <algorithm>
+#include <vector>
+#include <map>
+#include <memory>
+#include <iostream>
+#include <string>
+#include <cassert>
+#include <iso646.h>
+
+#endif
diff --git a/src/boost/libs/hof/example/in.cpp b/src/boost/libs/hof/example/in.cpp
new file mode 100644
index 000000000..a89541403
--- /dev/null
+++ b/src/boost/libs/hof/example/in.cpp
@@ -0,0 +1,81 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ in.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
+ in.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"
+
+using namespace boost::hof;
+
+#ifdef _MSC_VER
+template<class R, class T>
+auto member_find(const R& r, const T& x) BOOST_HOF_RETURNS(r.find(x));
+#endif
+
+// Function to find an iterator using a containers built-in find if available
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(find_iterator) = first_of(
+ [](const std::string& s, const auto& x)
+ {
+ auto index = s.find(x);
+ if (index == std::string::npos) return s.end();
+ else return s.begin() + index;
+ },
+#ifdef _MSC_VER
+ // On MSVC, trailing decltype doesn't work with generic lambdas, so a
+ // seperate function can be used instead.
+ BOOST_HOF_LIFT(member_find),
+#else
+ [](const auto& r, const auto& x) BOOST_HOF_RETURNS(r.find(x)),
+#endif
+ [](const auto& r, const auto& x)
+ {
+ using std::begin;
+ using std::end;
+ return std::find(begin(r), end(r), x);
+ }
+);
+// Implement an infix `in` operator to check if a range contains an element
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(in) = infix(
+ [](const auto& x, const auto& r)
+ {
+ using std::end;
+ return find_iterator(r, x) != end(r);
+ }
+);
+// Negate version of `in`
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(not_in) = infix(compose(not _, in));
+
+int main()
+{
+ // Check if vector contains element
+ std::vector<int> numbers = { 1, 2, 3, 4, 5 };
+ if (5 <in> numbers) std::cout << "Yes" << std::endl;
+
+ // Check if string contains element
+ std::string s = "hello world";
+ if ("hello" <in> s) std::cout << "Yes" << std::endl;
+
+ // Check if map contains element
+ std::map<int, std::string> number_map = {
+ { 1, "1" },
+ { 2, "2" },
+ { 3, "3" },
+ { 4, "4" }
+ };
+
+ if (4 <in> number_map) std::cout << "Yes" << std::endl;
+
+ // Check if map doesn't contains element
+ if (not (8 <in> numbers)) std::cout << "No" << std::endl;
+ if (8 <not_in> numbers) std::cout << "No" << std::endl;
+
+}
+
diff --git a/src/boost/libs/hof/example/pointfree.cpp b/src/boost/libs/hof/example/pointfree.cpp
new file mode 100644
index 000000000..6aa136479
--- /dev/null
+++ b/src/boost/libs/hof/example/pointfree.cpp
@@ -0,0 +1,33 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ pointfree.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
+ pointfree.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"
+
+using namespace boost::hof;
+
+BOOST_HOF_STATIC_FUNCTION(simple_print) = BOOST_HOF_LIFT(std::ref(std::cout) << _);
+BOOST_HOF_STATIC_FUNCTION(print) = proj(simple_print);
+BOOST_HOF_STATIC_FUNCTION(print_lines) = proj(flow(simple_print, _ << std::integral_constant<char, '\n'>{}));
+BOOST_HOF_STATIC_FUNCTION(max) = fold(BOOST_HOF_LIFT(std::max));
+
+int main()
+{
+ simple_print("Hello\n");
+ print("Hello", "World\n");
+ print_lines("Hello", "World");
+
+ auto n = max(1, 2, 4, 3); // Returns 4
+ auto m = max(0.1, 0.2, 0.5, 0.4); // Returns 0.5
+
+ print_lines(n, m);
+}
diff --git a/src/boost/libs/hof/example/print.cpp b/src/boost/libs/hof/example/print.cpp
new file mode 100644
index 000000000..0149c8708
--- /dev/null
+++ b/src/boost/libs/hof/example/print.cpp
@@ -0,0 +1,96 @@
+/*=============================================================================
+ Copyright (c) 2017 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)
+==============================================================================*/
+/*=============================================================================
+ 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"
+
+using namespace boost::hof;
+
+// ADL Lookup for ranges
+namespace adl {
+
+using std::begin;
+using std::end;
+
+template<class R>
+auto adl_begin(R&& r) BOOST_HOF_RETURNS(begin(r));
+template<class R>
+auto adl_end(R&& r) BOOST_HOF_RETURNS(end(r));
+}
+
+// Iterate over a tuple
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(for_each_tuple) = [](const auto& sequence, auto f)
+{
+ return unpack(proj(f))(sequence);
+};
+
+#ifdef _MSC_VER
+// On MSVC, trailing decltype doesn't work with generic lambdas, so seperate
+// functions can be used instead.
+template<class Self, class T>
+auto print_with_cout(Self, const T& x) -> decltype(std::cout << x, void())
+{
+ std::cout << x << std::endl;
+}
+
+template<class Self, class T>
+auto print_with_range(Self self, const T& range) -> decltype(self(*adl::adl_begin(range)), void())
+{
+ for(const auto& x:range) self(x);
+}
+
+template<class Self, class T>
+auto print_with_tuple(Self self, const T& tuple) -> decltype(for_each_tuple(tuple, self), void())
+{
+ for_each_tuple(tuple, self);
+}
+
+// Recursively print everything
+BOOST_HOF_STATIC_FUNCTION(simple_print) = fix(first_of(
+ BOOST_HOF_LIFT(print_with_cout),
+ BOOST_HOF_LIFT(print_with_range),
+ BOOST_HOF_LIFT(print_with_tuple)
+));
+#else
+// Recursively print everything
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(simple_print) = fix(first_of(
+ [](auto, const auto& x) -> decltype(std::cout << x, void())
+ {
+ std::cout << x << std::endl;
+ },
+ [](auto self, const auto& range) -> decltype(self(*adl::adl_begin(range)), void())
+ {
+ for(const auto& x:range) self(x);
+ },
+ [](auto self, const auto& tuple) -> decltype(for_each_tuple(tuple, self), void())
+ {
+ for_each_tuple(tuple, self);
+ }
+));
+#endif
+
+// Make print function varidiac
+BOOST_HOF_STATIC_LAMBDA_FUNCTION(print) = proj(simple_print);
+
+int main()
+{
+ print(5, "Hello world");
+ print(5);
+ std::vector<int> v = { 1, 2, 3, 4 };
+ print(v);
+
+ auto t = std::make_tuple(1, 2, 3, 4);
+ print(t);
+
+ auto m = std::make_tuple(3, v, t);
+ print(m);
+}
diff --git a/src/boost/libs/hof/example/sequence.cpp b/src/boost/libs/hof/example/sequence.cpp
new file mode 100644
index 000000000..3ecdd659f
--- /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();
+}
+
diff --git a/src/boost/libs/hof/example/static_if.cpp b/src/boost/libs/hof/example/static_if.cpp
new file mode 100644
index 000000000..898e66213
--- /dev/null
+++ b/src/boost/libs/hof/example/static_if.cpp
@@ -0,0 +1,43 @@
+/*=============================================================================
+ Copyright (c) 2017 Paul Fultz II
+ static_if.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
+ static_if.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"
+
+using namespace boost::hof;
+
+// static_if example taken from Baptiste Wicht:
+// http://baptiste-wicht.com/posts/2015/07/simulate-static_if-with-c11c14.html
+
+template<typename T>
+void decrement_kindof(T& value)
+{
+ eval(first_of(
+ if_(std::is_same<std::string, T>())([&](auto id){
+ id(value).pop_back();
+ }),
+ [&](auto id){
+ --id(value);
+ }
+ ));
+}
+
+int main()
+{
+ std::string s = "hello!";
+ decrement_kindof(s);
+ assert(s == "hello");
+
+ int i = 4;
+ decrement_kindof(i);
+ assert(i == 3);
+}