diff options
Diffstat (limited to 'src/boost/libs/hof/example')
-rw-r--r-- | src/boost/libs/hof/example/example.h | 67 | ||||
-rw-r--r-- | src/boost/libs/hof/example/in.cpp | 81 | ||||
-rw-r--r-- | src/boost/libs/hof/example/pointfree.cpp | 33 | ||||
-rw-r--r-- | src/boost/libs/hof/example/print.cpp | 96 | ||||
-rw-r--r-- | src/boost/libs/hof/example/sequence.cpp | 122 | ||||
-rw-r--r-- | src/boost/libs/hof/example/static_if.cpp | 43 |
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); +} |