diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/hof/test | |
parent | Initial commit. (diff) | |
download | ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.tar.xz ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/hof/test')
63 files changed, 7654 insertions, 0 deletions
diff --git a/src/boost/libs/hof/test/Jamfile.v2 b/src/boost/libs/hof/test/Jamfile.v2 new file mode 100644 index 000000000..198de5bd3 --- /dev/null +++ b/src/boost/libs/hof/test/Jamfile.v2 @@ -0,0 +1,31 @@ +#============================================================================= +# Copyright (c) 2017 Paul Fultz II +# Jamfile.v2 +# 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) +#============================================================================== +import testing ; +import ../../config/checks/config : requires ; + +project hof + : requirements [ requires cxx11_variadic_templates cxx11_constexpr ] + <include>../include/ + ; + +rule test_all +{ + local all_rules = ; + + for local fileb in [ glob *.cpp ] + { + all_rules += [ run $(fileb) + : # additional args + : # test-files + : # requirements + ] ; + } + + return $(all_rules) ; +} + +test-suite hof : [ test_all r ] : ; diff --git a/src/boost/libs/hof/test/alias.cpp b/src/boost/libs/hof/test/alias.cpp new file mode 100644 index 000000000..d6f94c2cd --- /dev/null +++ b/src/boost/libs/hof/test/alias.cpp @@ -0,0 +1,24 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + alias.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 <boost/hof/alias.hpp> +#include "test.hpp" + +struct foo +{ + int i; + foo(int i_) : i(i_) + {} +}; + +BOOST_HOF_TEST_CASE() +{ + boost::hof::alias<int> ai = 5; + BOOST_HOF_TEST_CHECK(boost::hof::alias_value(ai) == 5); + boost::hof::alias_inherit<foo> af = foo{5}; + BOOST_HOF_TEST_CHECK(boost::hof::alias_value(af).i == 5); +} + diff --git a/src/boost/libs/hof/test/always.cpp b/src/boost/libs/hof/test/always.cpp new file mode 100644 index 000000000..8acb08a9f --- /dev/null +++ b/src/boost/libs/hof/test/always.cpp @@ -0,0 +1,65 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + always.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 <boost/hof/always.hpp> +#include <boost/hof/function.hpp> +#include <memory> +#include "test.hpp" + +BOOST_HOF_TEST_CASE() +{ + static const int ten = 10; + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::always(ten)(1,2,3,4,5) == 10); + BOOST_HOF_TEST_CHECK( boost::hof::always(ten)(1,2,3,4,5) == 10 ); + + int i = 10; + BOOST_HOF_TEST_CHECK( boost::hof::always(std::ref(i))(1,2,3,4,5) == 10 ); + BOOST_HOF_TEST_CHECK( &boost::hof::always(std::ref(i))(1,2,3,4,5) == &i ); + + boost::hof::always()(1, 2); + static_assert(std::is_same<decltype(boost::hof::always()(1, 2)), BOOST_HOF_ALWAYS_VOID_RETURN>::value, "Failed"); +} + +BOOST_HOF_TEST_CASE() +{ + int i = 10; + BOOST_HOF_TEST_CHECK( boost::hof::always_ref(i)(1,2,3,4,5) == 10 ); + BOOST_HOF_TEST_CHECK( &boost::hof::always_ref(i)(1,2,3,4,5) == &i ); +} + +BOOST_HOF_STATIC_FUNCTION(gten) = boost::hof::always(std::integral_constant<int, 10>{}); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(gten(1,2,3,4,5) == 10); + BOOST_HOF_TEST_CHECK(gten(1,2,3,4,5) == 10); +} + +BOOST_HOF_TEST_CASE() +{ + auto f = boost::hof::always(10); + STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(decltype(f)); + BOOST_HOF_TEST_CHECK(f(1,2,3,4,5) == 10); +} + +struct copy_throws +{ + copy_throws() {} + copy_throws(copy_throws const&) {} + copy_throws(copy_throws&&) noexcept {} +}; + +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::always()()), "noexcept always"); + static_assert(noexcept(boost::hof::always(1)()), "noexcept always"); + static_assert(!noexcept(boost::hof::always(copy_throws{})()), "noexcept always"); + copy_throws ct{}; + static_assert(!noexcept(boost::hof::always(ct)()), "noexcept always"); + static_assert(noexcept(boost::hof::always(std::ref(ct))()) == BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(std::reference_wrapper<copy_throws>), "noexcept always"); + auto ctf = boost::hof::always(copy_throws{}); + static_assert(!noexcept(ctf()), "noexcept always"); +} diff --git a/src/boost/libs/hof/test/apply.cpp b/src/boost/libs/hof/test/apply.cpp new file mode 100644 index 000000000..e85eb915f --- /dev/null +++ b/src/boost/libs/hof/test/apply.cpp @@ -0,0 +1,467 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + apply.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 <boost/hof/apply.hpp> +#include "test.hpp" + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(binary_class(), 1, 2) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::apply(binary_class(), 1, 2) == 3); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::apply(boost::hof::apply, binary_class(), 1, 2) == 3); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(boost::hof::apply, binary_class(), 1, 2) == 3); +} + +struct member_sum_f +{ + int i; + constexpr member_sum_f(int x) : i(x) + {} + + constexpr int add(int x) const + { + return i+x; + } +}; + +struct member_sum_f_derived +: member_sum_f +{ + constexpr member_sum_f_derived(int x) : member_sum_f(x) + {} +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f(1), 2) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3); + +#ifdef __clang__ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f(1), 2) == 3); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::add, member_sum_f_derived(1), 2) == 3); +#endif + + static_assert(std::is_base_of<member_sum_f, member_sum_f>::value, "Base of failed"); + std::unique_ptr<member_sum_f> msp(new member_sum_f(1)); + BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, msp, 2) == 3); + + std::unique_ptr<member_sum_f_derived> mspd(new member_sum_f_derived(1)); + BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::add, mspd, 2) == 3); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f(3)) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f_derived(3)) == 3); + +#ifdef __clang__ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f(3)) == 3); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply(&member_sum_f::i, member_sum_f_derived(3)) == 3); +#endif + + std::unique_ptr<member_sum_f> msp(new member_sum_f(3)); + BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, msp) == 3); + + std::unique_ptr<member_sum_f_derived> mspd(new member_sum_f_derived(3)); + BOOST_HOF_TEST_CHECK(boost::hof::apply(&member_sum_f::i, mspd) == 3); +} + + +struct mem_hash +{ + mutable unsigned int hash; + + mem_hash(): hash(0) {} + + int f0() { f1(17); return 0; } + int g0() const { g1(17); return 0; } + + int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; } + int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; } + + int f2(int a1, int a2) { f1(a1); f1(a2); return 0; } + int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; } + + int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; } + int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; } + + int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; } + int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; } + + int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; } + int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; } + + int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; } + int g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); return 0; } + + int f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); return 0; } + int g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); return 0; } + + int f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); return 0; } + int g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); return 0; } +}; + +BOOST_HOF_TEST_CASE() +{ + + mem_hash x; + + mem_hash const & rcx = x; + mem_hash const * pcx = &x; + + std::shared_ptr<mem_hash> sp(new mem_hash); + + boost::hof::apply(&mem_hash::f0, x); + boost::hof::apply(&mem_hash::f0, &x); + boost::hof::apply(&mem_hash::f0, sp); + + boost::hof::apply(&mem_hash::g0, x); + boost::hof::apply(&mem_hash::g0, rcx); + boost::hof::apply(&mem_hash::g0, &x); + boost::hof::apply(&mem_hash::g0, pcx); + boost::hof::apply(&mem_hash::g0, sp); + + boost::hof::apply(&mem_hash::f1, x, 1); + boost::hof::apply(&mem_hash::f1, &x, 1); + boost::hof::apply(&mem_hash::f1, sp, 1); + + boost::hof::apply(&mem_hash::g1, x, 1); + boost::hof::apply(&mem_hash::g1, rcx, 1); + boost::hof::apply(&mem_hash::g1, &x, 1); + boost::hof::apply(&mem_hash::g1, pcx, 1); + boost::hof::apply(&mem_hash::g1, sp, 1); + + boost::hof::apply(&mem_hash::f2, x, 1, 2); + boost::hof::apply(&mem_hash::f2, &x, 1, 2); + boost::hof::apply(&mem_hash::f2, sp, 1, 2); + + boost::hof::apply(&mem_hash::g2, x, 1, 2); + boost::hof::apply(&mem_hash::g2, rcx, 1, 2); + boost::hof::apply(&mem_hash::g2, &x, 1, 2); + boost::hof::apply(&mem_hash::g2, pcx, 1, 2); + boost::hof::apply(&mem_hash::g2, sp, 1, 2); + + boost::hof::apply(&mem_hash::f3, x, 1, 2, 3); + boost::hof::apply(&mem_hash::f3, &x, 1, 2, 3); + boost::hof::apply(&mem_hash::f3, sp, 1, 2, 3); + + boost::hof::apply(&mem_hash::g3, x, 1, 2, 3); + boost::hof::apply(&mem_hash::g3, rcx, 1, 2, 3); + boost::hof::apply(&mem_hash::g3, &x, 1, 2, 3); + boost::hof::apply(&mem_hash::g3, pcx, 1, 2, 3); + boost::hof::apply(&mem_hash::g3, sp, 1, 2, 3); + + boost::hof::apply(&mem_hash::f4, x, 1, 2, 3, 4); + boost::hof::apply(&mem_hash::f4, &x, 1, 2, 3, 4); + boost::hof::apply(&mem_hash::f4, sp, 1, 2, 3, 4); + + boost::hof::apply(&mem_hash::g4, x, 1, 2, 3, 4); + boost::hof::apply(&mem_hash::g4, rcx, 1, 2, 3, 4); + boost::hof::apply(&mem_hash::g4, &x, 1, 2, 3, 4); + boost::hof::apply(&mem_hash::g4, pcx, 1, 2, 3, 4); + boost::hof::apply(&mem_hash::g4, sp, 1, 2, 3, 4); + + boost::hof::apply(&mem_hash::f5, x, 1, 2, 3, 4, 5); + boost::hof::apply(&mem_hash::f5, &x, 1, 2, 3, 4, 5); + boost::hof::apply(&mem_hash::f5, sp, 1, 2, 3, 4, 5); + + boost::hof::apply(&mem_hash::g5, x, 1, 2, 3, 4, 5); + boost::hof::apply(&mem_hash::g5, rcx, 1, 2, 3, 4, 5); + boost::hof::apply(&mem_hash::g5, &x, 1, 2, 3, 4, 5); + boost::hof::apply(&mem_hash::g5, pcx, 1, 2, 3, 4, 5); + boost::hof::apply(&mem_hash::g5, sp, 1, 2, 3, 4, 5); + + boost::hof::apply(&mem_hash::f6, x, 1, 2, 3, 4, 5, 6); + boost::hof::apply(&mem_hash::f6, &x, 1, 2, 3, 4, 5, 6); + boost::hof::apply(&mem_hash::f6, sp, 1, 2, 3, 4, 5, 6); + + boost::hof::apply(&mem_hash::g6, x, 1, 2, 3, 4, 5, 6); + boost::hof::apply(&mem_hash::g6, rcx, 1, 2, 3, 4, 5, 6); + boost::hof::apply(&mem_hash::g6, &x, 1, 2, 3, 4, 5, 6); + boost::hof::apply(&mem_hash::g6, pcx, 1, 2, 3, 4, 5, 6); + boost::hof::apply(&mem_hash::g6, sp, 1, 2, 3, 4, 5, 6); + + boost::hof::apply(&mem_hash::f7, x, 1, 2, 3, 4, 5, 6, 7); + boost::hof::apply(&mem_hash::f7, &x, 1, 2, 3, 4, 5, 6, 7); + boost::hof::apply(&mem_hash::f7, sp, 1, 2, 3, 4, 5, 6, 7); + + boost::hof::apply(&mem_hash::g7, x, 1, 2, 3, 4, 5, 6, 7); + boost::hof::apply(&mem_hash::g7, rcx, 1, 2, 3, 4, 5, 6, 7); + boost::hof::apply(&mem_hash::g7, &x, 1, 2, 3, 4, 5, 6, 7); + boost::hof::apply(&mem_hash::g7, pcx, 1, 2, 3, 4, 5, 6, 7); + boost::hof::apply(&mem_hash::g7, sp, 1, 2, 3, 4, 5, 6, 7); + + boost::hof::apply(&mem_hash::f8, x, 1, 2, 3, 4, 5, 6, 7, 8); + boost::hof::apply(&mem_hash::f8, &x, 1, 2, 3, 4, 5, 6, 7, 8); + boost::hof::apply(&mem_hash::f8, sp, 1, 2, 3, 4, 5, 6, 7, 8); + + boost::hof::apply(&mem_hash::g8, x, 1, 2, 3, 4, 5, 6, 7, 8); + boost::hof::apply(&mem_hash::g8, rcx, 1, 2, 3, 4, 5, 6, 7, 8); + boost::hof::apply(&mem_hash::g8, &x, 1, 2, 3, 4, 5, 6, 7, 8); + boost::hof::apply(&mem_hash::g8, pcx, 1, 2, 3, 4, 5, 6, 7, 8); + boost::hof::apply(&mem_hash::g8, sp, 1, 2, 3, 4, 5, 6, 7, 8); + + BOOST_HOF_TEST_CHECK(boost::hof::apply(&mem_hash::hash, x) == 17610 && boost::hof::apply(&mem_hash::hash, sp) == 2155); +} + +struct hash_base +{ + mutable unsigned int hash; + + hash_base(): hash(0) {} + + int f0() { f1(17); return 0; } + int g0() const { g1(17); return 0; } + + int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; } + int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; } + + int f2(int a1, int a2) { f1(a1); f1(a2); return 0; } + int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; } + + int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; } + int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; } + + int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; } + int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; } + + int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; } + int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; } + + int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; } + int g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); return 0; } + + int f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); return 0; } + int g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); return 0; } + + int f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); return 0; } + int g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); return 0; } +}; + +struct derived_hash: public hash_base +{ +}; + +BOOST_HOF_TEST_CASE() +{ + + derived_hash x; + + derived_hash const & rcx = x; + derived_hash const * pcx = &x; + + std::shared_ptr<derived_hash> sp(new derived_hash); + + boost::hof::apply(&derived_hash::f0, x); + boost::hof::apply(&derived_hash::f0, &x); + boost::hof::apply(&derived_hash::f0, sp); + + boost::hof::apply(&derived_hash::g0, x); + boost::hof::apply(&derived_hash::g0, rcx); + boost::hof::apply(&derived_hash::g0, &x); + boost::hof::apply(&derived_hash::g0, pcx); + boost::hof::apply(&derived_hash::g0, sp); + + boost::hof::apply(&derived_hash::f1, x, 1); + boost::hof::apply(&derived_hash::f1, &x, 1); + boost::hof::apply(&derived_hash::f1, sp, 1); + + boost::hof::apply(&derived_hash::g1, x, 1); + boost::hof::apply(&derived_hash::g1, rcx, 1); + boost::hof::apply(&derived_hash::g1, &x, 1); + boost::hof::apply(&derived_hash::g1, pcx, 1); + boost::hof::apply(&derived_hash::g1, sp, 1); + + boost::hof::apply(&derived_hash::f2, x, 1, 2); + boost::hof::apply(&derived_hash::f2, &x, 1, 2); + boost::hof::apply(&derived_hash::f2, sp, 1, 2); + + boost::hof::apply(&derived_hash::g2, x, 1, 2); + boost::hof::apply(&derived_hash::g2, rcx, 1, 2); + boost::hof::apply(&derived_hash::g2, &x, 1, 2); + boost::hof::apply(&derived_hash::g2, pcx, 1, 2); + boost::hof::apply(&derived_hash::g2, sp, 1, 2); + + boost::hof::apply(&derived_hash::f3, x, 1, 2, 3); + boost::hof::apply(&derived_hash::f3, &x, 1, 2, 3); + boost::hof::apply(&derived_hash::f3, sp, 1, 2, 3); + + boost::hof::apply(&derived_hash::g3, x, 1, 2, 3); + boost::hof::apply(&derived_hash::g3, rcx, 1, 2, 3); + boost::hof::apply(&derived_hash::g3, &x, 1, 2, 3); + boost::hof::apply(&derived_hash::g3, pcx, 1, 2, 3); + boost::hof::apply(&derived_hash::g3, sp, 1, 2, 3); + + boost::hof::apply(&derived_hash::f4, x, 1, 2, 3, 4); + boost::hof::apply(&derived_hash::f4, &x, 1, 2, 3, 4); + boost::hof::apply(&derived_hash::f4, sp, 1, 2, 3, 4); + + boost::hof::apply(&derived_hash::g4, x, 1, 2, 3, 4); + boost::hof::apply(&derived_hash::g4, rcx, 1, 2, 3, 4); + boost::hof::apply(&derived_hash::g4, &x, 1, 2, 3, 4); + boost::hof::apply(&derived_hash::g4, pcx, 1, 2, 3, 4); + boost::hof::apply(&derived_hash::g4, sp, 1, 2, 3, 4); + + boost::hof::apply(&derived_hash::f5, x, 1, 2, 3, 4, 5); + boost::hof::apply(&derived_hash::f5, &x, 1, 2, 3, 4, 5); + boost::hof::apply(&derived_hash::f5, sp, 1, 2, 3, 4, 5); + + boost::hof::apply(&derived_hash::g5, x, 1, 2, 3, 4, 5); + boost::hof::apply(&derived_hash::g5, rcx, 1, 2, 3, 4, 5); + boost::hof::apply(&derived_hash::g5, &x, 1, 2, 3, 4, 5); + boost::hof::apply(&derived_hash::g5, pcx, 1, 2, 3, 4, 5); + boost::hof::apply(&derived_hash::g5, sp, 1, 2, 3, 4, 5); + + boost::hof::apply(&derived_hash::f6, x, 1, 2, 3, 4, 5, 6); + boost::hof::apply(&derived_hash::f6, &x, 1, 2, 3, 4, 5, 6); + boost::hof::apply(&derived_hash::f6, sp, 1, 2, 3, 4, 5, 6); + + boost::hof::apply(&derived_hash::g6, x, 1, 2, 3, 4, 5, 6); + boost::hof::apply(&derived_hash::g6, rcx, 1, 2, 3, 4, 5, 6); + boost::hof::apply(&derived_hash::g6, &x, 1, 2, 3, 4, 5, 6); + boost::hof::apply(&derived_hash::g6, pcx, 1, 2, 3, 4, 5, 6); + boost::hof::apply(&derived_hash::g6, sp, 1, 2, 3, 4, 5, 6); + + boost::hof::apply(&derived_hash::f7, x, 1, 2, 3, 4, 5, 6, 7); + boost::hof::apply(&derived_hash::f7, &x, 1, 2, 3, 4, 5, 6, 7); + boost::hof::apply(&derived_hash::f7, sp, 1, 2, 3, 4, 5, 6, 7); + + boost::hof::apply(&derived_hash::g7, x, 1, 2, 3, 4, 5, 6, 7); + boost::hof::apply(&derived_hash::g7, rcx, 1, 2, 3, 4, 5, 6, 7); + boost::hof::apply(&derived_hash::g7, &x, 1, 2, 3, 4, 5, 6, 7); + boost::hof::apply(&derived_hash::g7, pcx, 1, 2, 3, 4, 5, 6, 7); + boost::hof::apply(&derived_hash::g7, sp, 1, 2, 3, 4, 5, 6, 7); + + boost::hof::apply(&derived_hash::f8, x, 1, 2, 3, 4, 5, 6, 7, 8); + boost::hof::apply(&derived_hash::f8, &x, 1, 2, 3, 4, 5, 6, 7, 8); + boost::hof::apply(&derived_hash::f8, sp, 1, 2, 3, 4, 5, 6, 7, 8); + + boost::hof::apply(&derived_hash::g8, x, 1, 2, 3, 4, 5, 6, 7, 8); + boost::hof::apply(&derived_hash::g8, rcx, 1, 2, 3, 4, 5, 6, 7, 8); + boost::hof::apply(&derived_hash::g8, &x, 1, 2, 3, 4, 5, 6, 7, 8); + boost::hof::apply(&derived_hash::g8, pcx, 1, 2, 3, 4, 5, 6, 7, 8); + boost::hof::apply(&derived_hash::g8, sp, 1, 2, 3, 4, 5, 6, 7, 8); + + BOOST_HOF_TEST_CHECK(boost::hof::apply(&derived_hash::hash, x) == 17610 && boost::hof::apply(&derived_hash::hash, sp) == 2155); +} + +struct dm_t +{ + int m; +}; + +BOOST_HOF_TEST_CASE() +{ + dm_t x = { 0 }; + + boost::hof::apply( &dm_t::m, x ) = 401; + + BOOST_HOF_TEST_CHECK( x.m == 401 ); + BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, x ) == 401 ); + + boost::hof::apply( &dm_t::m, &x ) = 502; + + BOOST_HOF_TEST_CHECK( x.m == 502 ); + BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, &x ) == 502 ); + + dm_t * px = &x; + + boost::hof::apply( &dm_t::m, px ) = 603; + + BOOST_HOF_TEST_CHECK( x.m == 603 ); + BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, px ) == 603 ); + + dm_t const & cx = x; + dm_t const * pcx = &x; + + BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, cx ) == 603 ); + BOOST_HOF_TEST_CHECK( boost::hof::apply( &dm_t::m, pcx ) == 603 ); + +} + + +struct X_ref +{ + int f() + { + return 1; + } + + int g() const + { + return 2; + } +}; + +BOOST_HOF_TEST_CASE() +{ + X_ref x; + + BOOST_HOF_TEST_CHECK( boost::hof::apply( &X_ref::f, std::ref( x ) ) == 1 ); + BOOST_HOF_TEST_CHECK( boost::hof::apply( &X_ref::g, std::cref( x ) ) == 2 ); +} +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +struct copy_throws +{ + copy_throws() {} + copy_throws(copy_throws const&) {} + copy_throws(copy_throws&&) noexcept {} +}; + +struct no_throw_fo +{ + void operator()() noexcept {} + void operator()(copy_throws) noexcept {} +}; + +struct throws_fo +{ + void operator()() {} +}; + +struct member_obj +{ + int x; +}; +// Only newer versions of gcc support deducing noexcept for member function pointers +#if defined(__GNUC__) && !defined (__clang__) && ((__GNUC__ == 4 && __GNUC_MINOR__ > 8) || (__GNUC__ > 4)) +struct no_throw_member_fun +{ + void foo_nullary() noexcept {} + void foo_unary(copy_throws) noexcept {} +}; +BOOST_HOF_TEST_CASE() +{ + no_throw_member_fun obj; + copy_throws arg; + static_assert(noexcept(boost::hof::apply(&no_throw_member_fun::foo_nullary, obj)), ""); + static_assert(!noexcept(boost::hof::apply(&no_throw_member_fun::foo_unary, obj, arg)), ""); + static_assert(noexcept(boost::hof::apply(&no_throw_member_fun::foo_unary, obj, std::move(arg))), ""); +} +#endif +BOOST_HOF_TEST_CASE() +{ + no_throw_fo obj; + copy_throws arg; + static_assert(noexcept(boost::hof::apply(obj)), ""); + static_assert(!noexcept(boost::hof::apply(obj, arg)), ""); + static_assert(noexcept(boost::hof::apply(obj, std::move(arg))), ""); +} +BOOST_HOF_TEST_CASE() +{ + throws_fo obj; + static_assert(!noexcept(boost::hof::apply(obj)), ""); +} +BOOST_HOF_TEST_CASE() +{ + member_obj obj{42}; + static_assert(noexcept(boost::hof::apply(&member_obj::x, obj)), ""); +} +#endif diff --git a/src/boost/libs/hof/test/apply_eval.cpp b/src/boost/libs/hof/test/apply_eval.cpp new file mode 100644 index 000000000..c97d87c30 --- /dev/null +++ b/src/boost/libs/hof/test/apply_eval.cpp @@ -0,0 +1,63 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + apply_eval.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 <boost/hof/apply_eval.hpp> +#include <boost/hof/always.hpp> +#include <boost/hof/placeholders.hpp> +#include "test.hpp" + +#include <memory> + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::apply_eval(binary_class(), boost::hof::always(1), boost::hof::always(2)) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::apply_eval(binary_class(), []{ return 1; }, []{ return 2;}) == 3); +} + +BOOST_HOF_TEST_CASE() +{ + boost::hof::apply_eval(boost::hof::always(), boost::hof::always(1), boost::hof::always(2)); +} +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::apply_eval(boost::hof::always(), boost::hof::always(1), boost::hof::always(2))), "noexcept apply_eval"); +} +#endif +BOOST_HOF_TEST_CASE() +{ + int i = 3; + BOOST_HOF_TEST_CHECK(boost::hof::apply_eval(boost::hof::_ - boost::hof::_, [&]{ return i++; }, [&]{ return i++;}) == -1); + BOOST_HOF_TEST_CHECK(boost::hof::apply_eval(boost::hof::_ - boost::hof::_, [&]{ return ++i; }, [&]{ return ++i;}) == -1); +} + +struct indirect_sum_f +{ + template<class T, class U> + auto operator()(T x, U y) const + BOOST_HOF_RETURNS(*x + *y); +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK( + boost::hof::apply_eval( + indirect_sum_f(), + []{ return std::unique_ptr<int>(new int(1)); }, + []{ return std::unique_ptr<int>(new int(2)); }) + == 3); +} + +std::unique_ptr<int> moveable(int i) +{ + return std::unique_ptr<int>{new int(i)}; +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(*boost::hof::apply_eval(&moveable, boost::hof::always(1)) == 1); + BOOST_HOF_TEST_CHECK(*boost::hof::apply_eval(&moveable, boost::hof::always(3)) == 3); +} diff --git a/src/boost/libs/hof/test/arg.cpp b/src/boost/libs/hof/test/arg.cpp new file mode 100644 index 000000000..b6343a330 --- /dev/null +++ b/src/boost/libs/hof/test/arg.cpp @@ -0,0 +1,53 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + arg.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 <boost/hof/arg.hpp> +#include <boost/hof/is_invocable.hpp> +#include <type_traits> +#include "test.hpp" + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::arg_c<3>(1,2,3,4,5) == 3); + BOOST_HOF_TEST_CHECK( boost::hof::arg_c<3>(1,2,3,4,5) == 3 ); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::arg(std::integral_constant<int, 3>())(1,2,3,4,5) == 3); + BOOST_HOF_TEST_CHECK( boost::hof::arg(std::integral_constant<int, 3>())(1,2,3,4,5) == 3 ); +} + +BOOST_HOF_TEST_CASE() +{ + auto at_3 = boost::hof::arg(std::integral_constant<int, 3>()); + static_assert(boost::hof::is_invocable<decltype(at_3), int, int, int>::value, "Not SFINAE-friendly"); + static_assert(!boost::hof::is_invocable<decltype(at_3), int, int>::value, "Not SFINAE-friendly"); + static_assert(!boost::hof::is_invocable<decltype(at_3), int>::value, "Not SFINAE-friendly"); +} + +struct foo {}; + +BOOST_HOF_TEST_CASE() +{ + static_assert(!boost::hof::is_invocable<decltype(boost::hof::arg), int>::value, "Not sfinae friendly"); + static_assert(!boost::hof::is_invocable<decltype(boost::hof::arg), foo>::value, "Not sfinae friendly"); +} + +struct copy_throws +{ + copy_throws() {} + copy_throws(copy_throws const&) {} + copy_throws(copy_throws&&) noexcept {} +}; +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::arg_c<3>(1,2,3,4,5)), "noexcept arg"); + static_assert(noexcept(boost::hof::arg(std::integral_constant<int, 3>())(1,2,3,4,5)), "noexcept arg"); + static_assert(!noexcept(boost::hof::arg(std::integral_constant<int, 3>())(1,2,copy_throws{},4,5)), "noexcept arg"); +} +#endif diff --git a/src/boost/libs/hof/test/capture.cpp b/src/boost/libs/hof/test/capture.cpp new file mode 100644 index 000000000..ac80447e3 --- /dev/null +++ b/src/boost/libs/hof/test/capture.cpp @@ -0,0 +1,96 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + capture.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 <boost/hof/capture.hpp> +#include <boost/hof/identity.hpp> +#include "test.hpp" + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture_basic(1, 2)(binary_class())() == 3); + BOOST_HOF_TEST_CHECK(boost::hof::capture_basic(1, 2)(binary_class())() == 3); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture_basic(1)(binary_class())(2) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::capture_basic(1)(binary_class())(2) == 3); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture_basic()(binary_class())(1, 2) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::capture_basic()(binary_class())(1, 2) == 3); + + static const int one = 1; + static const int two = 2; + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture_forward(one, two)(binary_class())() == 3); + BOOST_HOF_TEST_CHECK(boost::hof::capture_forward(one, two)(binary_class())() == 3); + BOOST_HOF_TEST_CHECK(boost::hof::capture_forward(1, 2)(binary_class())() == 3); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture_forward(one)(binary_class())(two) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::capture_forward(1)(binary_class())(2) == 3); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture_forward()(binary_class())(one, two) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::capture_forward()(binary_class())(one, two) == 3); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture(1, 2)(binary_class())() == 3); + BOOST_HOF_TEST_CHECK(boost::hof::capture(1, 2)(binary_class())() == 3); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture(1)(binary_class())(2) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::capture(1)(binary_class())(2) == 3); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::capture()(binary_class())(1, 2) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::capture()(binary_class())(1, 2) == 3); +} + +struct add_member +{ + int i; + + add_member(int ip) : i(ip) + {} + + int add(int j) const + { + return i + j; + } +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::capture_basic(add_member(1), 2)(&add_member::add)() == 3); + BOOST_HOF_TEST_CHECK(boost::hof::capture_basic(add_member(1))(&add_member::add)(2) == 3); +} + +BOOST_HOF_TEST_CASE() +{ + auto id = boost::hof::identity; + auto f = boost::hof::capture(boost::hof::identity)(boost::hof::identity); + static_assert(BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(decltype(id)), "Id not default constructible"); + static_assert(BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(decltype(f)), "Not default constructible"); + f(); +} +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::capture(boost::hof::identity)(boost::hof::identity)()), "noexcept capture"); + static_assert(noexcept(boost::hof::capture_basic(boost::hof::identity)(boost::hof::identity)()), "noexcept capture"); + static_assert(noexcept(boost::hof::capture_forward(boost::hof::identity)(boost::hof::identity)()), "noexcept capture"); +} +#endif +BOOST_HOF_TEST_CASE() +{ + auto f = boost::hof::capture_basic(boost::hof::identity)(boost::hof::identity); + f(); +} + +BOOST_HOF_TEST_CASE() +{ + auto f = boost::hof::capture_forward(boost::hof::identity)(boost::hof::identity); + f(); +} + +BOOST_HOF_TEST_CASE() +{ + auto f = boost::hof::capture(boost::hof::identity)(add_member{1}); + static_assert(!boost::hof::is_invocable<decltype(f), int>::value, "Not sfinae friendly"); +} + diff --git a/src/boost/libs/hof/test/combine.cpp b/src/boost/libs/hof/test/combine.cpp new file mode 100644 index 000000000..6340150e9 --- /dev/null +++ b/src/boost/libs/hof/test/combine.cpp @@ -0,0 +1,71 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + combine.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 <boost/hof/combine.hpp> +#include "test.hpp" + +#include <boost/hof/construct.hpp> +#include <boost/hof/capture.hpp> +#include <utility> +#include <tuple> + +template<class T, class U> +struct mini_pair +{ + T first; + U second; + + template<class X, class Y> + constexpr mini_pair(X&& x, Y&& y) + : first(boost::hof::forward<X>(x)), second(boost::hof::forward<Y>(y)) + {} +}; + +template<class T1, class U1, class T2, class U2> +constexpr bool operator==(const mini_pair<T1, U1>& x, const mini_pair<T2, U2>& y) +{ + return x.first == y.first && x.second == y.second; +} + +template<class T, class U> +constexpr mini_pair<T, U> make_mini_pair(T x, U y) +{ + return mini_pair<T, U>(x, y); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK( + boost::hof::combine( + boost::hof::construct<std::tuple>(), + boost::hof::capture_basic(1)(boost::hof::construct<std::pair>()), + boost::hof::capture_basic(2)(boost::hof::construct<std::pair>()) + )(2, 4) + == std::make_tuple(std::make_pair(1, 2), std::make_pair(2, 4))); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK( + boost::hof::combine( + boost::hof::construct<mini_pair>(), + boost::hof::capture_basic(1)(boost::hof::construct<mini_pair>()), + boost::hof::capture_basic(2)(boost::hof::construct<mini_pair>()) + )(2, 4) + == make_mini_pair(make_mini_pair(1, 2), make_mini_pair(2, 4))); + + BOOST_HOF_STATIC_TEST_CHECK( + boost::hof::combine( + boost::hof::construct<mini_pair>(), + boost::hof::capture_basic(1)(boost::hof::construct<mini_pair>()), + boost::hof::capture_basic(2)(boost::hof::construct<mini_pair>()) + )(2, 4) + == make_mini_pair(make_mini_pair(1, 2), make_mini_pair(2, 4))); +} + + + + diff --git a/src/boost/libs/hof/test/compose.cpp b/src/boost/libs/hof/test/compose.cpp new file mode 100644 index 000000000..f36291fda --- /dev/null +++ b/src/boost/libs/hof/test/compose.cpp @@ -0,0 +1,186 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + compose.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 <boost/hof/compose.hpp> +#include <boost/hof/function.hpp> +#include <boost/hof/lambda.hpp> +#include <boost/hof/placeholders.hpp> +#include <memory> +#include "test.hpp" + +namespace compose_test { +struct increment +{ + template<class T> + constexpr T operator()(T x) const noexcept + { + return x + 1; + } +}; + +struct decrement +{ + template<class T> + constexpr T operator()(T x) const noexcept + { + return x - 1; + } +}; + +struct negate +{ + template<class T> + constexpr T operator()(T x) const noexcept + { + return -x; + } +}; + +struct increment_movable +{ + std::unique_ptr<int> n; + increment_movable() + : n(new int(1)) + {} + template<class T> + T operator()(T x) const + { + return x + *n; + } +}; + +struct decrement_movable +{ + std::unique_ptr<int> n; + decrement_movable() + : n(new int(1)) + {} + template<class T> + T operator()(T x) const + { + return x - *n; + } +}; + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::compose(increment(), decrement(), increment())(3)), "noexcept compose"); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::compose(boost::hof::identity)(3) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::compose(boost::hof::identity, boost::hof::identity)(3) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::compose(boost::hof::identity, boost::hof::identity, boost::hof::identity)(3) == 3); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(boost::hof::identity)(3) == 3); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(boost::hof::identity, boost::hof::identity)(3) == 3); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(boost::hof::identity, boost::hof::identity, boost::hof::identity)(3) == 3); +} + +BOOST_HOF_TEST_CASE() +{ + int r = boost::hof::compose(increment(), decrement(), increment())(3); + BOOST_HOF_TEST_CHECK(r == 4); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(increment(), decrement(), increment())(3) == 4); +} + +BOOST_HOF_TEST_CASE() +{ + int r = boost::hof::compose(increment(), negate(), decrement(), decrement())(3); + BOOST_HOF_TEST_CHECK(r == 0); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(increment(), negate(), decrement(), decrement())(3) == 0); +} +BOOST_HOF_TEST_CASE() +{ + constexpr auto f = boost::hof::compose(increment(), decrement()); +#ifndef _MSC_VER + static_assert(std::is_empty<decltype(f)>::value, "Compose function not empty"); +#endif + static_assert(BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(decltype(f)), "Compose function not default constructible"); + int r = f(3); + BOOST_HOF_TEST_CHECK(r == 3); + BOOST_HOF_STATIC_TEST_CHECK(f(3) == 3); +} + +#ifndef _MSC_VER +BOOST_HOF_TEST_CASE() +{ + constexpr auto f = boost::hof::compose(increment(), negate(), decrement(), decrement()); + static_assert(std::is_empty<decltype(f)>::value, "Compose function not empty"); + static_assert(BOOST_HOF_IS_DEFAULT_CONSTRUCTIBLE(decltype(f)), "Compose function not default constructible"); + int r = f(3); + BOOST_HOF_TEST_CHECK(r == 0); + BOOST_HOF_STATIC_TEST_CHECK(f(3) == 0); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + STATIC_ASSERT_MOVE_ONLY(increment_movable); + STATIC_ASSERT_MOVE_ONLY(decrement_movable); + int r = boost::hof::compose(increment_movable(), decrement_movable(), increment_movable())(3); + BOOST_HOF_TEST_CHECK(r == 4); +} + +template<class T> +struct print; + +BOOST_HOF_TEST_CASE() +{ + const auto f = boost::hof::compose([](int i) { return i+1; }, [](int i) { return i-1; }, [](int i) { return i+1; }); +#ifndef _MSC_VER + static_assert(std::is_empty<decltype(f)>::value, "Compose function not empty"); +#endif + int r = f(3); + BOOST_HOF_TEST_CHECK(r == 4); +} + + +BOOST_HOF_STATIC_FUNCTION(f_compose_single_function) = boost::hof::compose(increment()); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(f_compose_single_function(3) == 4); + BOOST_HOF_STATIC_TEST_CHECK(f_compose_single_function(3) == 4); +} + +BOOST_HOF_STATIC_FUNCTION(f_compose_function) = boost::hof::compose(increment(), decrement(), increment()); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(f_compose_function(3) == 4); + BOOST_HOF_STATIC_TEST_CHECK(f_compose_function(3) == 4); +} + +BOOST_HOF_STATIC_FUNCTION(f_compose_function_4) = boost::hof::compose(increment(), negate(), decrement(), decrement()); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(f_compose_function_4(3) == 0); + BOOST_HOF_STATIC_TEST_CHECK(f_compose_function_4(3) == 0); +} + +BOOST_HOF_STATIC_LAMBDA_FUNCTION(f_compose_lambda) = boost::hof::compose( + [](int i) { return i+1; }, + [](int i) { return i-1; }, + [](int i) { return i+1; } +); + +BOOST_HOF_TEST_CASE() +{ + int r = f_compose_lambda(3); + BOOST_HOF_TEST_CHECK(r == 4); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::compose(boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1)(3) == 36); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::compose(boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1)(3) == 36); +} +} diff --git a/src/boost/libs/hof/test/construct.cpp b/src/boost/libs/hof/test/construct.cpp new file mode 100644 index 000000000..953f0f6c3 --- /dev/null +++ b/src/boost/libs/hof/test/construct.cpp @@ -0,0 +1,222 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + construct.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 <boost/hof/construct.hpp> +#include "test.hpp" + +#include <boost/hof/first_of.hpp> +#include <boost/hof/proj.hpp> +#include <boost/hof/placeholders.hpp> + +#include <tuple> +#include <type_traits> +#include <vector> + +template<class T> +struct ac +{ + T value; + constexpr ac(T i) : value(i) + {} +}; + +template<class... Ts> +struct tuple_meta +{ + typedef std::tuple<Ts...> type; +}; + +struct tuple_meta_class +{ + template<class... Ts> + struct apply + { + typedef std::tuple<Ts...> type; + }; +}; + +struct implicit_default +{ + int mem1; + std::string mem2; +}; + +struct user_default +{ + int mem1; + std::string mem2; + user_default() { } +}; + +struct user_construct +{ + int mem1; + std::string mem2; + user_construct(int) { } +}; + +template<class T> +struct template_user_construct +{ + int mem1; + std::string mem2; + template_user_construct(T) { } +}; + + +BOOST_HOF_TEST_CASE() +{ + auto v = boost::hof::construct<std::vector<int>>()(5, 5); + BOOST_HOF_TEST_CHECK(v.size() == 5); + BOOST_HOF_TEST_CHECK(v == std::vector<int>{5, 5, 5, 5, 5}); +} + +BOOST_HOF_TEST_CASE() +{ + auto v = boost::hof::construct_basic<std::vector<int>>()(5, 5); + BOOST_HOF_TEST_CHECK(v.size() == 5); + BOOST_HOF_TEST_CHECK(v == std::vector<int>{5, 5, 5, 5, 5}); +} + +BOOST_HOF_TEST_CASE() +{ + auto v = boost::hof::construct_forward<std::vector<int>>()(5, 5); + BOOST_HOF_TEST_CHECK(v.size() == 5); + BOOST_HOF_TEST_CHECK(v == std::vector<int>{5, 5, 5, 5, 5}); +} + +BOOST_HOF_TEST_CASE() +{ + auto x = boost::hof::construct<implicit_default>()(); + BOOST_HOF_TEST_CHECK(x.mem1 == 0); + BOOST_HOF_TEST_CHECK(x.mem2 == ""); +} + +BOOST_HOF_TEST_CASE() +{ + auto x = boost::hof::construct<user_default>()(); + BOOST_HOF_TEST_CHECK(x.mem1 == 0); + BOOST_HOF_TEST_CHECK(x.mem2 == ""); +} + +BOOST_HOF_TEST_CASE() +{ + auto x = boost::hof::construct<user_construct>()(3); + BOOST_HOF_TEST_CHECK(x.mem1 == 0); + BOOST_HOF_TEST_CHECK(x.mem2 == ""); +} + +BOOST_HOF_TEST_CASE() +{ + auto x = boost::hof::construct<template_user_construct>()(3); + BOOST_HOF_TEST_CHECK(x.mem1 == 0); + BOOST_HOF_TEST_CHECK(x.mem2 == ""); +} + +BOOST_HOF_TEST_CASE() +{ + auto x = boost::hof::construct_forward<template_user_construct>()(3); + BOOST_HOF_TEST_CHECK(x.mem1 == 0); + BOOST_HOF_TEST_CHECK(x.mem2 == ""); +} + +BOOST_HOF_TEST_CASE() +{ + auto x = boost::hof::construct_basic<template_user_construct>()(3); + BOOST_HOF_TEST_CHECK(x.mem1 == 0); + BOOST_HOF_TEST_CHECK(x.mem2 == ""); +} + +BOOST_HOF_TEST_CASE() +{ + auto v = boost::hof::construct<std::vector<int>>()({5, 5, 5, 5, 5}); + BOOST_HOF_TEST_CHECK(v.size() == 5); + BOOST_HOF_TEST_CHECK(v == std::vector<int>{5, 5, 5, 5, 5}); +} + +BOOST_HOF_TEST_CASE() +{ + auto t = boost::hof::construct<std::tuple>()(1, 2, 3); + static_assert(std::is_same<std::tuple<int, int, int>, decltype(t)>::value, ""); + BOOST_HOF_TEST_CHECK(t == std::make_tuple(1, 2, 3)); +// GCC 4.7 doesn't have fully constexpr tuple +#if BOOST_HOF_HAS_CONSTEXPR_TUPLE + BOOST_HOF_STATIC_TEST_CHECK(std::make_tuple(1, 2, 3) == boost::hof::construct<std::tuple>()(1, 2, 3)); +#endif +} + +BOOST_HOF_TEST_CASE() +{ + auto t = boost::hof::construct<std::pair>()(1, 2); + static_assert(std::is_same<std::pair<int, int>, decltype(t)>::value, ""); + BOOST_HOF_TEST_CHECK(t == std::make_pair(1, 2)); +// GCC 4.7 doesn't have fully constexpr pair +#if BOOST_HOF_HAS_CONSTEXPR_TUPLE + BOOST_HOF_STATIC_TEST_CHECK(std::make_pair(1, 2) == boost::hof::construct<std::pair>()(1, 2)); +#endif +} + +BOOST_HOF_TEST_CASE() +{ + auto f = boost::hof::first_of(boost::hof::construct<std::pair>(), boost::hof::identity); + BOOST_HOF_TEST_CHECK(f(1, 2) == std::make_pair(1, 2)); + BOOST_HOF_TEST_CHECK(f(1) == 1); +} + +BOOST_HOF_TEST_CASE() +{ + auto x = boost::hof::construct<ac>()(1); + static_assert(std::is_same<ac<int>, decltype(x)>::value, ""); + BOOST_HOF_TEST_CHECK(x.value == ac<int>(1).value); + BOOST_HOF_STATIC_TEST_CHECK(ac<int>(1).value == boost::hof::construct<ac>()(1).value); +} + +BOOST_HOF_TEST_CASE() +{ + auto x = boost::hof::construct_basic<ac>()(1); + static_assert(std::is_same<ac<int>, decltype(x)>::value, ""); + BOOST_HOF_TEST_CHECK(x.value == ac<int>(1).value); + BOOST_HOF_STATIC_TEST_CHECK(ac<int>(1).value == boost::hof::construct<ac>()(1).value); +} + +BOOST_HOF_TEST_CASE() +{ + int i = 1; + auto x = boost::hof::construct_forward<ac>()(i); + static_assert(std::is_same<ac<int&>, decltype(x)>::value, ""); + BOOST_HOF_TEST_CHECK(&x.value == &i); +} + +BOOST_HOF_TEST_CASE() +{ + int i = 1; + auto x = boost::hof::construct_basic<ac>()(i); + static_assert(std::is_same<ac<int&>, decltype(x)>::value, ""); + BOOST_HOF_TEST_CHECK(&x.value == &i); +} + +BOOST_HOF_TEST_CASE() +{ + auto t = boost::hof::construct_meta<tuple_meta>()(1, 2, 3); + static_assert(std::is_same<std::tuple<int, int, int>, decltype(t)>::value, ""); + BOOST_HOF_TEST_CHECK(t == std::make_tuple(1, 2, 3)); +// GCC 4.7 doesn't have fully constexpr tuple +#if BOOST_HOF_HAS_CONSTEXPR_TUPLE + BOOST_HOF_STATIC_TEST_CHECK(std::make_tuple(1, 2, 3) == boost::hof::construct_meta<tuple_meta>()(1, 2, 3)); +#endif +} + +BOOST_HOF_TEST_CASE() +{ + auto t = boost::hof::construct_meta<tuple_meta_class>()(1, 2, 3); + static_assert(std::is_same<std::tuple<int, int, int>, decltype(t)>::value, ""); + BOOST_HOF_TEST_CHECK(t == std::make_tuple(1, 2, 3)); +// GCC 4.7 doesn't have fully constexpr tuple +#if BOOST_HOF_HAS_CONSTEXPR_TUPLE + BOOST_HOF_STATIC_TEST_CHECK(std::make_tuple(1, 2, 3) == boost::hof::construct_meta<tuple_meta_class>()(1, 2, 3)); +#endif +} + diff --git a/src/boost/libs/hof/test/decay.cpp b/src/boost/libs/hof/test/decay.cpp new file mode 100644 index 000000000..bcf235bfd --- /dev/null +++ b/src/boost/libs/hof/test/decay.cpp @@ -0,0 +1,28 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + decay.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 <boost/hof/decay.hpp> +#include "test.hpp" + +#define CHECK_DECAY(T) \ + STATIC_ASSERT_SAME(decltype(boost::hof::decay(std::declval<T>())), std::decay<T>::type) + +BOOST_HOF_TEST_CASE() +{ + CHECK_DECAY(int); + CHECK_DECAY(int*); + CHECK_DECAY(int&); + CHECK_DECAY(int&&); + CHECK_DECAY(const int&); + CHECK_DECAY(int[2]); + CHECK_DECAY(int(int)); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::decay(3) == 3); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::decay(3) == 3); +} diff --git a/src/boost/libs/hof/test/decorate.cpp b/src/boost/libs/hof/test/decorate.cpp new file mode 100644 index 000000000..11b1f5b66 --- /dev/null +++ b/src/boost/libs/hof/test/decorate.cpp @@ -0,0 +1,35 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + decorate.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 <boost/hof/decorate.hpp> +#include "test.hpp" + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::decorate(boost::hof::always(1))(boost::hof::always(1))(boost::hof::always(1))(5) == 1); +} + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +struct copy_throws +{ + copy_throws() {} + copy_throws(copy_throws const&) {} + copy_throws(copy_throws&&) noexcept {} +}; + +struct no_throw_fo +{ + void operator()() const noexcept {} + void operator()(copy_throws) const noexcept {} +}; + +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::decorate(boost::hof::always(1))(boost::hof::always(1))(boost::hof::always(1))(5)), "noexcept decorator"); + static_assert(!noexcept(boost::hof::decorate(boost::hof::always(1))(boost::hof::always(1))(boost::hof::always(1))(copy_throws{})), "noexcept decorator"); +} + +#endif diff --git a/src/boost/libs/hof/test/fail/always.cpp b/src/boost/libs/hof/test/fail/always.cpp new file mode 100644 index 000000000..76b6e5d70 --- /dev/null +++ b/src/boost/libs/hof/test/fail/always.cpp @@ -0,0 +1,14 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + always.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 <boost/hof/always.hpp> +#include <memory> + +int main() { + auto f = boost::hof::always(std::unique_ptr<int>{new int(1)}); + auto i = f(1, 2, 3); + (void)i; +} diff --git a/src/boost/libs/hof/test/fail/apply_eval.cpp b/src/boost/libs/hof/test/fail/apply_eval.cpp new file mode 100644 index 000000000..c87d7ed9d --- /dev/null +++ b/src/boost/libs/hof/test/fail/apply_eval.cpp @@ -0,0 +1,11 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + apply_eval.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 <boost/hof/apply_eval.hpp> + +int main() { + (void)boost::hof::apply_eval(boost::hof::always(), 1, 2); +} diff --git a/src/boost/libs/hof/test/fail/flip_lazy.cpp b/src/boost/libs/hof/test/fail/flip_lazy.cpp new file mode 100644 index 000000000..7d5e0dc36 --- /dev/null +++ b/src/boost/libs/hof/test/fail/flip_lazy.cpp @@ -0,0 +1,14 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + flip_lazy.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 <boost/hof/lazy.hpp> +#include <boost/hof/placeholders.hpp> +#include <boost/hof/flip.hpp> + +int main() { + auto i = (boost::hof::flip(boost::hof::_1 - boost::hof::_2) * boost::hof::_1)(3, 6); + (void)i; +} diff --git a/src/boost/libs/hof/test/fail/implicit.cpp b/src/boost/libs/hof/test/fail/implicit.cpp new file mode 100644 index 000000000..df81297ac --- /dev/null +++ b/src/boost/libs/hof/test/fail/implicit.cpp @@ -0,0 +1,29 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + implicit.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 <boost/hof/implicit.hpp> + +template<class T> +struct auto_caster +{ + template<class U> + T operator()(U x) + { + return T(x); + } +}; + + +int main() +{ + boost::hof::implicit<auto_caster> auto_cast = {}; + auto x = auto_cast(1.5); + (void)x; +// This is not possible in c++17 due to guaranteed copy elison +#if BOOST_HOF_HAS_STD_17 || (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7) + static_assert(false, "Always fail"); +#endif +} diff --git a/src/boost/libs/hof/test/fail/rotate_lazy.cpp b/src/boost/libs/hof/test/fail/rotate_lazy.cpp new file mode 100644 index 000000000..59c4f4e95 --- /dev/null +++ b/src/boost/libs/hof/test/fail/rotate_lazy.cpp @@ -0,0 +1,14 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + rotate_lazy.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 <boost/hof/lazy.hpp> +#include <boost/hof/placeholders.hpp> +#include <boost/hof/rotate.hpp> + +int main() { + auto i = (boost::hof::rotate(boost::hof::_1 - boost::hof::_2) * boost::hof::_1)(3, 6); + (void)i; +} diff --git a/src/boost/libs/hof/test/fail/unpack.cpp b/src/boost/libs/hof/test/fail/unpack.cpp new file mode 100644 index 000000000..f4758be0c --- /dev/null +++ b/src/boost/libs/hof/test/fail/unpack.cpp @@ -0,0 +1,27 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + unpack.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 <boost/hof/unpack.hpp> + +struct foo +{}; + +namespace boost { namespace hof { + +template<> +struct unpack_sequence<foo> +{ + template<class F, class S> + constexpr static int apply(F&&, S&&) + { + return 0; + } +}; +} + +int main() { + boost::hof::unpack(boost::hof::always(1))(foo{}); +} diff --git a/src/boost/libs/hof/test/fail/unpack_uncallable.cpp b/src/boost/libs/hof/test/fail/unpack_uncallable.cpp new file mode 100644 index 000000000..d3c946f4e --- /dev/null +++ b/src/boost/libs/hof/test/fail/unpack_uncallable.cpp @@ -0,0 +1,24 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + unpack_uncallable.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 <boost/hof/unpack.hpp> + +struct foo +{}; + +namespace boost { namespace hof { + +template<> +struct unpack_sequence<foo> +{ + template<class F, class S> + constexpr static auto apply(F&&, S&& s) BOOST_HOF_RETURNS(s.bar); +}; +} + +int main() { + boost::hof::unpack(boost::hof::always(1))(foo{}); +} diff --git a/src/boost/libs/hof/test/filter.cpp b/src/boost/libs/hof/test/filter.cpp new file mode 100644 index 000000000..0b0268e01 --- /dev/null +++ b/src/boost/libs/hof/test/filter.cpp @@ -0,0 +1,54 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + filter.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 <boost/hof/if.hpp> +#include "test.hpp" + +#include <boost/hof/proj.hpp> +#include <boost/hof/lift.hpp> +#include <boost/hof/construct.hpp> +#include <boost/hof/first_of.hpp> +#include <boost/hof/unpack.hpp> + +#include <tuple> + +BOOST_HOF_LIFT_CLASS(make_tuple_f, std::make_tuple); + +struct integer_predicate +{ + constexpr integer_predicate() + {} + template<class T> + constexpr auto operator()(T x) const BOOST_HOF_RETURNS + ( + boost::hof::first_of( + boost::hof::if_(std::is_integral<T>())(boost::hof::pack_basic), + boost::hof::always(boost::hof::pack_basic()) + )(boost::hof::move(x)) + ) +}; + +struct filter_integers +{ + template<class Seq> + constexpr auto operator()(Seq s) const BOOST_HOF_RETURNS + ( + boost::hof::unpack( + boost::hof::proj(integer_predicate(), boost::hof::unpack(make_tuple_f())) + )(std::move(s)) + ) +}; + + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(filter_integers()(boost::hof::pack_basic(1, 2, 2.0, 3)) == std::make_tuple(1, 2, 3)); +#if BOOST_HOF_HAS_CONSTEXPR_TUPLE + BOOST_HOF_STATIC_TEST_CHECK(filter_integers()(boost::hof::pack_basic(1, 2, 2.0, 3)) == std::make_tuple(1, 2, 3)); +#endif +} + + diff --git a/src/boost/libs/hof/test/final_base.cpp b/src/boost/libs/hof/test/final_base.cpp new file mode 100644 index 000000000..d348e922a --- /dev/null +++ b/src/boost/libs/hof/test/final_base.cpp @@ -0,0 +1,26 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + final_base.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 <boost/hof/flip.hpp> +#include "test.hpp" + +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7 +#define FINAL +#else +#define FINAL final +#endif + + +struct f FINAL { + int operator()(int i, void *) const { + return i; + } +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::flip(f())(nullptr, 2) == 2); +} diff --git a/src/boost/libs/hof/test/first_of.cpp b/src/boost/libs/hof/test/first_of.cpp new file mode 100644 index 000000000..c995e5142 --- /dev/null +++ b/src/boost/libs/hof/test/first_of.cpp @@ -0,0 +1,216 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + first_of.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 <boost/hof/first_of.hpp> +#include <boost/hof/static.hpp> +#include <boost/hof/lambda.hpp> +#include <boost/hof/function.hpp> +#include <memory> +#include "test.hpp" + +namespace conditional_test { + +#define CONDITIONAL_FUNCTION(n) \ +struct t ## n {}; \ +struct f ## n \ +{ \ + constexpr int operator()(t ## n) const \ + { \ + return n; \ + } \ +}; + +CONDITIONAL_FUNCTION(1) +CONDITIONAL_FUNCTION(2) +CONDITIONAL_FUNCTION(3) + +#define CONDITIONAL_MOVE_FUNCTION(n) \ +struct t_move ## n {}; \ +struct f_move ## n \ +{ \ + std::unique_ptr<int> i;\ + f_move ## n(int ip) : i(new int(ip)) {}; \ + int operator()(t_move ## n) const \ + { \ + return *i; \ + } \ +}; + +CONDITIONAL_MOVE_FUNCTION(1) +CONDITIONAL_MOVE_FUNCTION(2) +CONDITIONAL_MOVE_FUNCTION(3) + +struct ff +{ + constexpr int operator()(t2) const + { + return 500; + } +}; + +static constexpr boost::hof::static_<boost::hof::first_of_adaptor<f1, f2, f3, ff> > f = {}; + +BOOST_HOF_STATIC_FUNCTION(f_constexpr) = boost::hof::first_of_adaptor<f1, f2, f3, ff>(); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(f(t1()) == 1); + BOOST_HOF_TEST_CHECK(f(t2()) == 2); + BOOST_HOF_TEST_CHECK(f(t3()) == 3); + + BOOST_HOF_STATIC_TEST_CHECK(f_constexpr(t1()) == 1); + BOOST_HOF_STATIC_TEST_CHECK(f_constexpr(t2()) == 2); + BOOST_HOF_STATIC_TEST_CHECK(f_constexpr(t3()) == 3); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::first_of(f1{}, f2{})(t1()) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::first_of(f1{}, f2{})(t2()) == 2); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(f1{}, f2{})(t1()) == 1); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(f1{}, f2{})(t2()) == 2); +} + +#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7) +#else + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f1{}, f2{}))(t1()) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f1{}, f2{}))(t2()) == 2); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f1{}, f2{}))(t1()) == 1); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f1{}, f2{}))(t2()) == 2); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t1()) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t2()) == 2); + BOOST_HOF_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t3()) == 3); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t1()) == 1); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t2()) == 2); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(f1{}, boost::hof::first_of(f2{}, f3{}))(t3()) == 3); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t1()) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t2()) == 2); + BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t3()) == 3); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t1()) == 1); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t2()) == 2); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::first_of(boost::hof::first_of(f1{}, f2{}), boost::hof::first_of(f2{}, f3{}))(t3()) == 3); +} + +#endif + +BOOST_HOF_TEST_CASE() +{ + auto f_move_local = boost::hof::first_of(f_move1(1), f_move2(2), f_move3(3)); + STATIC_ASSERT_MOVE_ONLY(decltype(f_move_local)); + BOOST_HOF_TEST_CHECK(f_move_local(t_move1()) == 1); + BOOST_HOF_TEST_CHECK(f_move_local(t_move2()) == 2); + BOOST_HOF_TEST_CHECK(f_move_local(t_move3()) == 3); +} +#ifndef _MSC_VER +static constexpr auto lam = boost::hof::first_of( + BOOST_HOF_STATIC_LAMBDA(t1) + { + return 1; + }, + BOOST_HOF_STATIC_LAMBDA(t2) + { + return 2; + }, + BOOST_HOF_STATIC_LAMBDA(t3) + { + return 3; + } +); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(lam(t1()) == 1); + BOOST_HOF_TEST_CHECK(lam(t2()) == 2); + BOOST_HOF_TEST_CHECK(lam(t3()) == 3); +} +#endif + +BOOST_HOF_STATIC_LAMBDA_FUNCTION(static_fun) = boost::hof::first_of( + [](t1) + { + return 1; + }, + [](t2) + { + return 2; + }, + [](t3) + { + return 3; + } +); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(static_fun(t1()) == 1); + BOOST_HOF_TEST_CHECK(static_fun(t2()) == 2); + BOOST_HOF_TEST_CHECK(static_fun(t3()) == 3); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::first_of(boost::hof::identity, boost::hof::identity)(3) == 3); +} + +template<class T> +struct throw_fo +{ + void operator()(T) const {} +}; + +template<class T> +struct no_throw_fo +{ + void operator()(T) const noexcept {} +}; +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + typedef boost::hof::first_of_adaptor<throw_fo<t1>, no_throw_fo<t2>> fun; + auto g = fun{}; + static_assert(noexcept(g(t2{})), "noexcept conditional"); + static_assert(!noexcept(g(t1{})), "noexcept conditional"); + + static_assert(noexcept(fun{}(t2{})), "noexcept conditional"); + static_assert(!noexcept(fun{}(t1{})), "noexcept conditional"); +} + +BOOST_HOF_TEST_CASE() +{ + typedef boost::hof::first_of_adaptor<no_throw_fo<t2>, throw_fo<t1>> fun; + auto g = fun{}; + static_assert(noexcept(g(t2{})), "noexcept conditional"); + static_assert(!noexcept(g(t1{})), "noexcept conditional"); + + static_assert(noexcept(fun{}(t2{})), "noexcept conditional"); + static_assert(!noexcept(fun{}(t1{})), "noexcept conditional"); +} + +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::first_of_adaptor<no_throw_fo<t2>, throw_fo<t1>>{}(t2{})), "noexcept conditional"); + static_assert(!noexcept(boost::hof::first_of_adaptor<no_throw_fo<t2>, throw_fo<t1>>{}(t1{})), "noexcept conditional"); + + static_assert(noexcept(boost::hof::first_of(no_throw_fo<t2>{}, throw_fo<t1>{})(t2{})), "noexcept conditional"); + static_assert(!noexcept(boost::hof::first_of(no_throw_fo<t2>{}, throw_fo<t1>{})(t1{})), "noexcept conditional"); +} +#endif +} diff --git a/src/boost/libs/hof/test/fix.cpp b/src/boost/libs/hof/test/fix.cpp new file mode 100644 index 000000000..8262d9eb0 --- /dev/null +++ b/src/boost/libs/hof/test/fix.cpp @@ -0,0 +1,100 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + fix.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 <boost/hof/fix.hpp> +#include <boost/hof/static.hpp> +#include <boost/hof/reveal.hpp> +#include <boost/hof/result.hpp> +#include "test.hpp" + +#include <memory> + +struct factorial_t +{ + template<class Self, class T> + T operator()(Self s, T x) const noexcept + { + return x == 0 ? 1 : x * s(x-1); + } +}; + +struct factorial_constexpr_t +{ + template<class Self, class T> + constexpr T operator()(Self s, T x) const noexcept + { + return x == 0 ? 1 : x * s(x-1); + } +}; + +struct factorial_move_t +{ + std::unique_ptr<int> i; + factorial_move_t() : i(new int(1)) + {} + template<class Self, class T> + T operator()(const Self& s, T x) const + { + return x == 0 ? *i : x * s(x-1); + } +}; + +static constexpr boost::hof::fix_adaptor<factorial_t> factorial = {}; +static constexpr boost::hof::fix_adaptor<factorial_constexpr_t> factorial_constexpr = {}; +static constexpr boost::hof::static_<boost::hof::fix_adaptor<factorial_move_t> > factorial_move = {}; + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(factorial(5)), "noexcept fix"); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + const int r = factorial(5); + BOOST_HOF_TEST_CHECK(r == 5*4*3*2*1); +} + +BOOST_HOF_TEST_CASE() +{ + const int r = boost::hof::reveal(factorial)(5); + BOOST_HOF_TEST_CHECK(r == 5*4*3*2*1); +} + +#if !BOOST_HOF_NO_EXPRESSION_SFINAE +BOOST_HOF_TEST_CASE() +{ + const int r = boost::hof::fix(boost::hof::result<int>(factorial_constexpr_t()))(5); + BOOST_HOF_TEST_CHECK(r == 5*4*3*2*1); +} + +BOOST_HOF_TEST_CASE() +{ + const int r = boost::hof::result<int>(factorial_constexpr)(5); + BOOST_HOF_TEST_CHECK(r == 5*4*3*2*1); +} +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fix(boost::hof::result<int>(factorial_constexpr_t()))(5) == 5*4*3*2*1); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::result<int>(factorial_constexpr)(5) == 5*4*3*2*1); +} +#endif +BOOST_HOF_TEST_CASE() +{ +#if BOOST_HOF_HAS_GENERIC_LAMBDA + auto factorial_ = boost::hof::fix([](auto s, auto x) -> decltype(x) { return x == 0 ? 1 : x * s(x-1); }); + int r = boost::hof::result<int>(factorial_)(5); + BOOST_HOF_TEST_CHECK(r == 5*4*3*2*1); +#endif +} + +BOOST_HOF_TEST_CASE() +{ + const int r = factorial_move(5); + BOOST_HOF_TEST_CHECK(r == 5*4*3*2*1); + BOOST_HOF_TEST_CHECK(boost::hof::fix(factorial_move_t())(5) == 5*4*3*2*1); +} diff --git a/src/boost/libs/hof/test/flip.cpp b/src/boost/libs/hof/test/flip.cpp new file mode 100644 index 000000000..599997421 --- /dev/null +++ b/src/boost/libs/hof/test/flip.cpp @@ -0,0 +1,61 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + flip.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 <boost/hof/flip.hpp> +#include <boost/hof/placeholders.hpp> +#include "test.hpp" + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == boost::hof::flip(boost::hof::_ - boost::hof::_)(2, 5)); + BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::flip(boost::hof::_ - boost::hof::_)(2, 5)); +} + +BOOST_HOF_TEST_CASE() +{ + typedef std::integral_constant<int, 1> one; + typedef std::integral_constant<int, 2> two; + typedef std::integral_constant<int, 3> three; + BOOST_HOF_TEST_CHECK(1 == boost::hof::arg(one{})(1, 2, 3, 4)); + BOOST_HOF_STATIC_TEST_CHECK(1 == boost::hof::arg(one{})(1, 2, 3, 4)); + BOOST_HOF_TEST_CHECK(2 == boost::hof::flip(boost::hof::arg(one{}))(1, 2, 3, 4)); + BOOST_HOF_STATIC_TEST_CHECK(2 == boost::hof::flip(boost::hof::arg(one{}))(1, 2, 3, 4)); + + BOOST_HOF_TEST_CHECK(2 == boost::hof::arg(two{})(1, 2, 3, 4)); + BOOST_HOF_STATIC_TEST_CHECK(2 == boost::hof::arg(two{})(1, 2, 3, 4)); + BOOST_HOF_TEST_CHECK(1 == boost::hof::flip(boost::hof::arg(two{}))(1, 2, 3, 4)); + BOOST_HOF_STATIC_TEST_CHECK(1 == boost::hof::flip(boost::hof::arg(two{}))(1, 2, 3, 4)); + + BOOST_HOF_TEST_CHECK(3 == boost::hof::arg(three{})(1, 2, 3, 4)); + BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::arg(three{})(1, 2, 3, 4)); + BOOST_HOF_TEST_CHECK(3 == boost::hof::flip(boost::hof::arg(three{}))(1, 2, 3, 4)); + BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::flip(boost::hof::arg(three{}))(1, 2, 3, 4)); +} + +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7 +#define FINAL +#else +#define FINAL final +#endif + + +struct f FINAL { + int operator()(int i, void *) const { + return i; + } +}; + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(boost::hof::flip(boost::hof::_ - boost::hof::_)(2, 5), "noexcept flip"); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::flip(f())(nullptr, 2) == 2); +} diff --git a/src/boost/libs/hof/test/flow.cpp b/src/boost/libs/hof/test/flow.cpp new file mode 100644 index 000000000..755374e47 --- /dev/null +++ b/src/boost/libs/hof/test/flow.cpp @@ -0,0 +1,169 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + flow.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 <boost/hof/flow.hpp> +#include <boost/hof/function.hpp> +#include <boost/hof/lambda.hpp> +#include <boost/hof/placeholders.hpp> +#include <memory> +#include "test.hpp" + +namespace flow_test { +struct increment +{ + template<class T> + constexpr T operator()(T x) const noexcept + { + return x + 1; + } +}; + +struct decrement +{ + template<class T> + constexpr T operator()(T x) const noexcept + { + return x - 1; + } +}; + +struct negate +{ + template<class T> + constexpr T operator()(T x) const noexcept + { + return -x; + } +}; + +struct increment_movable +{ + std::unique_ptr<int> n; + increment_movable() + : n(new int(1)) + {} + template<class T> + T operator()(T x) const + { + return x + *n; + } +}; + +struct decrement_movable +{ + std::unique_ptr<int> n; + decrement_movable() + : n(new int(1)) + {} + template<class T> + T operator()(T x) const + { + return x - *n; + } +}; +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::flow(increment(), decrement(), increment())(3)), "noexcept flow"); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::flow(boost::hof::identity)(3) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::flow(boost::hof::identity, boost::hof::identity)(3) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::flow(boost::hof::identity, boost::hof::identity, boost::hof::identity)(3) == 3); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(boost::hof::identity)(3) == 3); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(boost::hof::identity, boost::hof::identity)(3) == 3); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(boost::hof::identity, boost::hof::identity, boost::hof::identity)(3) == 3); +} + +BOOST_HOF_TEST_CASE() +{ + int r = boost::hof::flow(increment(), decrement(), increment())(3); + BOOST_HOF_TEST_CHECK(r == 4); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(increment(), decrement(), increment())(3) == 4); +} + +BOOST_HOF_TEST_CASE() +{ + int r = boost::hof::flow(increment(), negate(), decrement(), decrement())(3); + BOOST_HOF_TEST_CHECK(r == -6); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(increment(), negate(), decrement(), decrement())(3) == -6); +} +#ifndef _MSC_VER +BOOST_HOF_TEST_CASE() +{ + constexpr auto f = boost::hof::flow(increment(), decrement()); + static_assert(std::is_empty<decltype(f)>::value, "Compose function not empty"); + int r = f(3); + BOOST_HOF_TEST_CHECK(r == 3); + BOOST_HOF_STATIC_TEST_CHECK(f(3) == 3); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + STATIC_ASSERT_MOVE_ONLY(increment_movable); + STATIC_ASSERT_MOVE_ONLY(decrement_movable); + int r = boost::hof::flow(increment_movable(), decrement_movable(), increment_movable())(3); + BOOST_HOF_TEST_CHECK(r == 4); +} + +BOOST_HOF_TEST_CASE() +{ + const auto f = boost::hof::flow([](int i) { return i+1; }, [](int i) { return i-1; }, [](int i) { return i+1; }); +#ifndef _MSC_VER + static_assert(std::is_empty<decltype(f)>::value, "Compose function not empty"); +#endif + int r = f(3); + BOOST_HOF_TEST_CHECK(r == 4); +} + + +BOOST_HOF_STATIC_FUNCTION(f_flow_single_function) = boost::hof::flow(increment()); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(f_flow_single_function(3) == 4); + BOOST_HOF_STATIC_TEST_CHECK(f_flow_single_function(3) == 4); +} + +BOOST_HOF_STATIC_FUNCTION(f_flow_function) = boost::hof::flow(increment(), decrement(), increment()); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(f_flow_function(3) == 4); + BOOST_HOF_STATIC_TEST_CHECK(f_flow_function(3) == 4); +} + +BOOST_HOF_STATIC_FUNCTION(f_flow_function_4) = boost::hof::flow(increment(), negate(), decrement(), decrement()); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(f_flow_function_4(3) == -6); + BOOST_HOF_STATIC_TEST_CHECK(f_flow_function_4(3) == -6); +} + +BOOST_HOF_STATIC_LAMBDA_FUNCTION(f_flow_lambda) = boost::hof::flow( + [](int i) { return i+1; }, + [](int i) { return i-1; }, + [](int i) { return i+1; } +); + +BOOST_HOF_TEST_CASE() +{ + int r = f_flow_lambda(3); + BOOST_HOF_TEST_CHECK(r == 4); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::flow(boost::hof::_1 + boost::hof::_1, boost::hof::_1 * boost::hof::_1)(3) == 36); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::flow(boost::hof::_1 + boost::hof::_1, boost::hof::_1 * boost::hof::_1)(3) == 36); +} +} diff --git a/src/boost/libs/hof/test/fold.cpp b/src/boost/libs/hof/test/fold.cpp new file mode 100644 index 000000000..cf1cf9cba --- /dev/null +++ b/src/boost/libs/hof/test/fold.cpp @@ -0,0 +1,93 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + fold.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 <boost/hof/fold.hpp> +#include "test.hpp" + +struct max_f +{ + template<class T, class U> + constexpr T operator()(T x, U y) const noexcept + { + return x > y ? x : y; + } +}; + +struct sum_f +{ + template<class T, class U> + constexpr T operator()(T x, U y) const BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(x+y) + { + return x + y; + } +}; + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::fold(max_f(), 0)(2, 3, 4, 5)), "noexcept fold"); + static_assert(noexcept(boost::hof::fold(sum_f(), 0)(2, 3, 4, 5)), "noexcept fold"); + static_assert(!noexcept(boost::hof::fold(sum_f(), std::string())("hello", "-", "world")), "noexcept fold"); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f(), 0)(2, 3, 4, 5) == 5); + BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f(), 0)(5, 4, 3, 2) == 5); + BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f(), 0)(2, 3, 5, 4) == 5); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f(), 0)(2, 3, 4, 5) == 5); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f(), 0)(5, 4, 3, 2) == 5); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f(), 0)(2, 3, 5, 4) == 5); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f(), 0)() == 0); + BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f(), 0)(5) == 5); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f(), 0)() == 0); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f(), 0)(5) == 5); +} + +template<class... Ts> +constexpr auto find_positive_max(Ts... xs) BOOST_HOF_RETURNS +( + boost::hof::fold(max_f(), 0)(xs...) +); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(find_positive_max() == 0); + BOOST_HOF_TEST_CHECK(find_positive_max(5) == 5); + + BOOST_HOF_STATIC_TEST_CHECK(find_positive_max() == 0); + BOOST_HOF_STATIC_TEST_CHECK(find_positive_max(5) == 5); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f())(5) == 5); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f())(5) == 5); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f())(2, 3, 4, 5) == 5); + BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f())(5, 4, 3, 2) == 5); + BOOST_HOF_TEST_CHECK(boost::hof::fold(max_f())(2, 3, 5, 4) == 5); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f())(2, 3, 4, 5) == 5); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f())(5, 4, 3, 2) == 5); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::fold(max_f())(2, 3, 5, 4) == 5); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::fold(sum_f(), std::string())("hello", "-", "world") == "hello-world"); +} diff --git a/src/boost/libs/hof/test/function.cpp b/src/boost/libs/hof/test/function.cpp new file mode 100644 index 000000000..fc4a4774f --- /dev/null +++ b/src/boost/libs/hof/test/function.cpp @@ -0,0 +1,106 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + function.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 <boost/hof/function.hpp> +#include <boost/hof/partial.hpp> +#include <boost/hof/infix.hpp> +#include <memory> +#include "test.hpp" + +namespace test_constexpr { + +struct sum_f +{ + template<class T, class U> + constexpr T operator()(T x, U y) const + { + return x+y; + } +}; + +BOOST_HOF_STATIC_FUNCTION(sum_init) = sum_f(); + +BOOST_HOF_TEST_CASE() +{ +// TODO: Should be empty on MSVC as well +#ifndef _MSC_VER + STATIC_ASSERT_EMPTY(sum_init); +#endif + BOOST_HOF_TEST_CHECK(3 == sum_init(1, 2)); + + BOOST_HOF_STATIC_TEST_CHECK(3 == sum_init(1, 2)); +} + +BOOST_HOF_STATIC_FUNCTION(sum_partial) = boost::hof::partial(sum_f()); +BOOST_HOF_TEST_CASE() +{ +#ifndef _MSC_VER + STATIC_ASSERT_EMPTY(sum_partial); +#endif + BOOST_HOF_TEST_CHECK(3 == sum_partial(1, 2)); + BOOST_HOF_TEST_CHECK(3 == sum_partial(1)(2)); + + BOOST_HOF_STATIC_TEST_CHECK(3 == sum_partial(1, 2)); + BOOST_HOF_STATIC_TEST_CHECK(3 == sum_partial(1)(2)); +} + +} + +namespace test_static { + +struct sum_f +{ + template<class T, class U> + constexpr T operator()(T x, U y) const + { + return x+y; + } +}; + +struct add_one_f +{ + template<class T> + constexpr T operator()(T x) const + { + return x+1; + } +}; + +BOOST_HOF_STATIC_FUNCTION(sum_partial) = boost::hof::partial(sum_f()); + +BOOST_HOF_TEST_CASE() +{ +#ifndef _MSC_VER + STATIC_ASSERT_EMPTY(sum_partial); +#endif + BOOST_HOF_TEST_CHECK(3 == sum_partial(1, 2)); + BOOST_HOF_TEST_CHECK(3 == sum_partial(1)(2)); +} + +BOOST_HOF_STATIC_FUNCTION(add_one_pipable) = boost::hof::pipable(add_one_f()); + +BOOST_HOF_TEST_CASE() +{ +// TODO: Make this work on msvc +#ifndef _MSC_VER + STATIC_ASSERT_EMPTY(add_one_pipable); +#endif + BOOST_HOF_TEST_CHECK(3 == add_one_pipable(2)); + BOOST_HOF_TEST_CHECK(3 == (2 | add_one_pipable)); +} + +BOOST_HOF_STATIC_FUNCTION(sum_infix) = boost::hof::infix(sum_f()); + +BOOST_HOF_TEST_CASE() +{ +// TODO: Make this work on msvc +#ifndef _MSC_VER + STATIC_ASSERT_EMPTY(sum_infix); +#endif + BOOST_HOF_TEST_CHECK(3 == (1 <sum_infix> 2)); +} + +} diff --git a/src/boost/libs/hof/test/identity.cpp b/src/boost/libs/hof/test/identity.cpp new file mode 100644 index 000000000..d19023f9d --- /dev/null +++ b/src/boost/libs/hof/test/identity.cpp @@ -0,0 +1,68 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + identity.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 <boost/hof/identity.hpp> +#include <boost/hof/is_invocable.hpp> +#include <boost/hof/detail/move.hpp> +#include "test.hpp" + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::identity(10) == 10); + BOOST_HOF_TEST_CHECK(boost::hof::identity(10) == 10); +} + +BOOST_HOF_TEST_CASE() +{ + int i = 3; + BOOST_HOF_TEST_CHECK(boost::hof::identity(i) == 3); + BOOST_HOF_TEST_CHECK(&boost::hof::identity(i) == &i); + static_assert(std::is_lvalue_reference<decltype(boost::hof::identity(i))>::value, "Not lvalue"); + static_assert(!std::is_lvalue_reference<decltype(boost::hof::identity(3))>::value, "Not rvalue"); +} + +BOOST_HOF_TEST_CASE() +{ + auto ls = boost::hof::identity({1, 2, 3, 4}); + std::vector<int> v{1, 2, 3, 4}; + BOOST_HOF_TEST_CHECK(std::equal(ls.begin(), ls.end(), v.begin())); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(std::vector<int>(boost::hof::identity({1, 2, 3})) == std::vector<int>{1, 2, 3}); +} + +BOOST_HOF_TEST_CASE() +{ + static_assert(boost::hof::is_invocable<decltype(boost::hof::identity), int>::value, "Identiy callable"); + static_assert(!boost::hof::is_invocable<decltype(boost::hof::identity), int, int>::value, "Identiy not callable"); + static_assert(!boost::hof::is_invocable<decltype(boost::hof::identity)>::value, "Identiy not callable"); +} + +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::identity({1, 2, 3})), "Noexcept identity"); + static_assert(noexcept(boost::hof::identity(1)), "Noexcept identity"); + int i = 5; + static_assert(noexcept(boost::hof::identity(i)), "Noexcept identity"); +} + +struct copy_throws +{ + copy_throws() {} + copy_throws(copy_throws const&) {} + copy_throws(copy_throws&&) noexcept {} +}; + +BOOST_HOF_TEST_CASE() +{ + copy_throws ct{}; + static_assert(noexcept(boost::hof::identity(ct)), "Noexcept identity"); + static_assert(noexcept(boost::hof::identity(boost::hof::move(ct))), "Noexcept identity"); + static_assert(!noexcept(boost::hof::identity(copy_throws{})), "Noexcept identity"); +} + diff --git a/src/boost/libs/hof/test/if.cpp b/src/boost/libs/hof/test/if.cpp new file mode 100644 index 000000000..ee5a98fd1 --- /dev/null +++ b/src/boost/libs/hof/test/if.cpp @@ -0,0 +1,154 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + 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 <boost/hof/if.hpp> +#include "test.hpp" + +#include <boost/hof/first_of.hpp> +#include <boost/hof/placeholders.hpp> + + +struct is_5 +{ + template<class T> + constexpr bool operator()(T i) const + { + return i == 5; + } +}; + +struct is_not_5 +{ + template<class T> + constexpr bool operator()(T i) const + { + return i != 5; + } +}; + +template<class F> +struct test_int +{ + template<class T> + constexpr bool operator()(T x) const + { + return boost::hof::first_of( + boost::hof::if_(std::is_integral<T>())(F()), + boost::hof::always(true) + )(x); + } +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(test_int<is_5>()(5)); + BOOST_HOF_TEST_CHECK(test_int<is_5>()(5L)); + BOOST_HOF_TEST_CHECK(test_int<is_5>()(5.0)); + BOOST_HOF_TEST_CHECK(test_int<is_5>()(6.0)); + + BOOST_HOF_TEST_CHECK(test_int<is_not_5>()(6)); + BOOST_HOF_TEST_CHECK(test_int<is_not_5>()(6L)); + BOOST_HOF_TEST_CHECK(test_int<is_not_5>()(5.0)); + BOOST_HOF_TEST_CHECK(test_int<is_not_5>()(6.0)); + + BOOST_HOF_STATIC_TEST_CHECK(test_int<is_5>()(5)); + BOOST_HOF_STATIC_TEST_CHECK(test_int<is_5>()(5L)); + BOOST_HOF_STATIC_TEST_CHECK(test_int<is_5>()(5.0)); + BOOST_HOF_STATIC_TEST_CHECK(test_int<is_5>()(6.0)); + + BOOST_HOF_STATIC_TEST_CHECK(test_int<is_not_5>()(6)); + BOOST_HOF_STATIC_TEST_CHECK(test_int<is_not_5>()(6L)); + BOOST_HOF_STATIC_TEST_CHECK(test_int<is_not_5>()(5.0)); + BOOST_HOF_STATIC_TEST_CHECK(test_int<is_not_5>()(6.0)); +} + +template<class F> +struct test_int_c +{ + template<class T> + constexpr bool operator()(T x) const + { + return boost::hof::first_of( + boost::hof::if_c<std::is_integral<T>::value>(F()), + boost::hof::always(true) + )(x); + } +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(test_int_c<is_5>()(5)); + BOOST_HOF_TEST_CHECK(test_int_c<is_5>()(5L)); + BOOST_HOF_TEST_CHECK(test_int_c<is_5>()(5.0)); + BOOST_HOF_TEST_CHECK(test_int_c<is_5>()(6.0)); + + BOOST_HOF_TEST_CHECK(test_int_c<is_not_5>()(6)); + BOOST_HOF_TEST_CHECK(test_int_c<is_not_5>()(6L)); + BOOST_HOF_TEST_CHECK(test_int_c<is_not_5>()(5.0)); + BOOST_HOF_TEST_CHECK(test_int_c<is_not_5>()(6.0)); + + BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_5>()(5)); + BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_5>()(5L)); + BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_5>()(5.0)); + BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_5>()(6.0)); + + BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_not_5>()(6)); + BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_not_5>()(6L)); + BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_not_5>()(5.0)); + BOOST_HOF_STATIC_TEST_CHECK(test_int_c<is_not_5>()(6.0)); +} + +struct sum_f +{ + template<class T> + constexpr int operator()(T x, T y) const + { + return boost::hof::first_of( + boost::hof::if_(std::is_integral<T>())(boost::hof::_ + boost::hof::_), + boost::hof::always(0) + )(x, y); + } +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(sum_f()(1, 2) == 3); + BOOST_HOF_TEST_CHECK(sum_f()(1.0, 2.0) == 0); + BOOST_HOF_TEST_CHECK(sum_f()("", "") == 0); + + BOOST_HOF_STATIC_TEST_CHECK(sum_f()(1, 2) == 3); + BOOST_HOF_STATIC_TEST_CHECK(sum_f()("", "") == 0); +} + + +struct sum_f_c +{ + template<class T> + constexpr int operator()(T x, T y) const + { + return boost::hof::first_of( + boost::hof::if_c<std::is_integral<T>::value>(boost::hof::_ + boost::hof::_), + boost::hof::always(0) + )(x, y); + } +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(sum_f_c()(1, 2) == 3); + BOOST_HOF_TEST_CHECK(sum_f_c()(1.0, 2.0) == 0); + BOOST_HOF_TEST_CHECK(sum_f_c()("", "") == 0); + + BOOST_HOF_STATIC_TEST_CHECK(sum_f_c()(1, 2) == 3); + BOOST_HOF_STATIC_TEST_CHECK(sum_f_c()("", "") == 0); +} + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::if_(std::is_integral<int>())(boost::hof::identity)(1)), "noexcept if"); +} +#endif diff --git a/src/boost/libs/hof/test/implicit.cpp b/src/boost/libs/hof/test/implicit.cpp new file mode 100644 index 000000000..2f6624f4d --- /dev/null +++ b/src/boost/libs/hof/test/implicit.cpp @@ -0,0 +1,56 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + implicit.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 <boost/hof/implicit.hpp> +#include "test.hpp" + +template<class T> +struct auto_caster +{ + template<class U> + T operator()(U x) + { + return T(x); + } +}; + +template<class T> +struct auto_caster_noexcept +{ + template<class U> + T operator()(U x) noexcept + { + return T(x); + } +}; + +struct auto_caster_foo +{ + int i; + explicit auto_caster_foo(int ip) : i(ip) {} + +}; +// TODO: Test template constraint on conversion operator +static constexpr boost::hof::implicit<auto_caster> auto_cast = {}; + +BOOST_HOF_TEST_CASE() +{ + float f = 1.5; + int i = auto_cast(f); + // auto_caster_foo x = 1; + auto_caster_foo x = auto_cast(1); + BOOST_HOF_TEST_CHECK(1 == i); + BOOST_HOF_TEST_CHECK(1 == x.i); + +} +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + boost::hof::implicit<auto_caster_noexcept> lauto_cast{}; + float f = 1.5; + static_assert(noexcept(int(lauto_cast(f))), "noexcept implicit"); +} +#endif diff --git a/src/boost/libs/hof/test/indirect.cpp b/src/boost/libs/hof/test/indirect.cpp new file mode 100644 index 000000000..b1e3e548f --- /dev/null +++ b/src/boost/libs/hof/test/indirect.cpp @@ -0,0 +1,52 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + indirect.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 <boost/hof/indirect.hpp> +#include "test.hpp" + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == boost::hof::indirect(std::unique_ptr<binary_class>(new binary_class()))(1, 2)); + BOOST_HOF_TEST_CHECK(3 == boost::hof::reveal(boost::hof::indirect(std::unique_ptr<binary_class>(new binary_class())))(1, 2)); + + binary_class f; + + BOOST_HOF_TEST_CHECK(3 == boost::hof::indirect(&f)(1, 2)); + BOOST_HOF_TEST_CHECK(3 == boost::hof::reveal(boost::hof::indirect(&f))(1, 2)); +} +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + binary_class f; + static_assert(noexcept(boost::hof::indirect(&f)(1, 2)), "noexcept indirect"); +} +#endif + +struct mutable_function +{ + mutable_function() : value(0) {} + void operator()(int a) { value += a; } + int value; +}; + +BOOST_HOF_TEST_CASE() +{ + auto mf = mutable_function{}; + boost::hof::indirect(&mf)(15); + boost::hof::indirect(&mf)(2); + BOOST_HOF_TEST_CHECK(mf.value == 17); +} + + +BOOST_HOF_TEST_CASE() +{ + auto mf = std::make_shared<mutable_function>(); + boost::hof::indirect(mf)(15); + boost::hof::indirect(mf)(2); + BOOST_HOF_TEST_CHECK(mf->value == 17); +} + + diff --git a/src/boost/libs/hof/test/infix.cpp b/src/boost/libs/hof/test/infix.cpp new file mode 100644 index 000000000..6b79489f4 --- /dev/null +++ b/src/boost/libs/hof/test/infix.cpp @@ -0,0 +1,115 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + infix.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 <boost/hof/infix.hpp> +#include <boost/hof/function.hpp> +#include <boost/hof/lambda.hpp> +#include <boost/hof/pipable.hpp> +#include <boost/hof/placeholders.hpp> +#include "test.hpp" + +struct sum_f +{ + template<class T, class U> + constexpr T operator()(T x, U y) const BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(x+y) + { + return x+y; + } +}; + +static constexpr boost::hof::infix_adaptor<sum_f> sum = {}; + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(1 <sum> 2), "noexcept infix"); + static_assert(!noexcept(std::string() <sum> std::string()), "noexcept infix"); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == (1 <sum> 2)); + BOOST_HOF_STATIC_TEST_CHECK(3 == (1 <sum> 2)); + + BOOST_HOF_TEST_CHECK(3 == (sum(1, 2))); + BOOST_HOF_STATIC_TEST_CHECK(3 == (sum(1, 2))); +} + +BOOST_HOF_STATIC_FUNCTION(sum1) = boost::hof::infix(sum_f()); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == (1 <sum1> 2)); + BOOST_HOF_STATIC_TEST_CHECK(3 == (1 <sum1> 2)); + + BOOST_HOF_TEST_CHECK(3 == (sum1(1, 2))); + BOOST_HOF_STATIC_TEST_CHECK(3 == (sum1(1, 2))); +} + +BOOST_HOF_STATIC_LAMBDA_FUNCTION(sum2) = boost::hof::infix([](int x, int y) { return x + y; }); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == (1 <sum2> 2)); + + BOOST_HOF_TEST_CHECK(3 == (sum2(1, 2))); +} + +BOOST_HOF_STATIC_FUNCTION(sum3) = boost::hof::infix(boost::hof::_ + boost::hof::_); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == (1 <sum3> 2)); + BOOST_HOF_STATIC_TEST_CHECK(3 == (1 <sum3> 2)); + + BOOST_HOF_TEST_CHECK(3 == (sum3(1, 2))); + BOOST_HOF_STATIC_TEST_CHECK(3 == (sum3(1, 2))); +} + + +BOOST_HOF_STATIC_LAMBDA_FUNCTION(sum4) = boost::hof::infix(boost::hof::infix([](int x, int y) { return x + y; })); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == (1 <sum4> 2)); + + BOOST_HOF_TEST_CHECK(3 == (sum4(1, 2))); +} + +BOOST_HOF_STATIC_FUNCTION(sum5) = boost::hof::infix(boost::hof::infix(boost::hof::_ + boost::hof::_)); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == (1 <sum5> 2)); + BOOST_HOF_STATIC_TEST_CHECK(3 == (1 <sum5> 2)); + + BOOST_HOF_TEST_CHECK(3 == (sum5(1, 2))); + BOOST_HOF_STATIC_TEST_CHECK(3 == (sum5(1, 2))); +} + +BOOST_HOF_TEST_CASE() +{ +#if (defined(__GNUC__) && !defined (__clang__)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wparentheses" +#endif + BOOST_HOF_TEST_CHECK(6 == (1 + 2 <sum> 3)); + BOOST_HOF_TEST_CHECK(3 == 1 <sum> 2); +#if (defined(__GNUC__) && !defined (__clang__)) +#pragma GCC diagnostic pop +#endif +} + +struct foo {}; + +BOOST_HOF_TEST_CASE() +{ + auto f = boost::hof::infix([](int, int) { return foo{}; }); + auto g = boost::hof::infix([](foo, foo) { return std::string("hello"); }); + BOOST_HOF_TEST_CHECK((1 <f> 2 <g> foo{}) == "hello"); + +} diff --git a/src/boost/libs/hof/test/is_invocable.cpp b/src/boost/libs/hof/test/is_invocable.cpp new file mode 100644 index 000000000..e65d49c15 --- /dev/null +++ b/src/boost/libs/hof/test/is_invocable.cpp @@ -0,0 +1,192 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + is_invocable.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 <boost/hof/is_invocable.hpp> +#include <ciso646> +#include "test.hpp" + +template<int N> +struct callable_rank : callable_rank<N-1> +{}; + +template<> +struct callable_rank<0> +{}; + +BOOST_HOF_STATIC_TEST_CASE() +{ + struct is_callable_class + { + void operator()(int) const + { + } + }; + struct callable_test_param {}; + + void is_callable_function(int) + { + } + + struct is_callable_rank_class + { + void operator()(int, callable_rank<3>) const + { + } + + void operator()(int, callable_rank<4>) const + { + } + }; + + static_assert(boost::hof::is_invocable<is_callable_class, int>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_class, long>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_class, double>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_class, const int&>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_class, const long&>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_class, const double&>::value, "Not callable"); + static_assert(not boost::hof::is_invocable<is_callable_class, callable_test_param>::value, "callable failed"); + static_assert(not boost::hof::is_invocable<is_callable_class>::value, "callable failed"); + static_assert(not boost::hof::is_invocable<is_callable_class, int, int>::value, "callable failed"); + + typedef void (*is_callable_function_pointer)(int); + static_assert(boost::hof::is_invocable<is_callable_function_pointer, int>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_function_pointer, long>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_function_pointer, double>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_function_pointer, const int&>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_function_pointer, const long&>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_function_pointer, const double&>::value, "Not callable"); + static_assert(not boost::hof::is_invocable<is_callable_function_pointer, callable_test_param>::value, "callable failed"); + static_assert(not boost::hof::is_invocable<is_callable_function_pointer>::value, "callable failed"); + static_assert(not boost::hof::is_invocable<is_callable_function_pointer, int, int>::value, "callable failed"); + + static_assert(boost::hof::is_invocable<is_callable_rank_class, int, callable_rank<3>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, long, callable_rank<3>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, double, callable_rank<3>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, const int&, callable_rank<3>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, const long&, callable_rank<3>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, const double&, callable_rank<3>>::value, "Not callable"); + + static_assert(boost::hof::is_invocable<is_callable_rank_class, int, callable_rank<4>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, long, callable_rank<4>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, double, callable_rank<4>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, const int&, callable_rank<4>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, const long&, callable_rank<4>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, const double&, callable_rank<4>>::value, "Not callable"); + + static_assert(boost::hof::is_invocable<is_callable_rank_class, int, callable_rank<5>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, long, callable_rank<5>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, double, callable_rank<5>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, const int&, callable_rank<5>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, const long&, callable_rank<5>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, const double&, callable_rank<5>>::value, "Not callable"); + + static_assert(boost::hof::is_invocable<is_callable_rank_class, int, callable_rank<6>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, long, callable_rank<6>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, double, callable_rank<6>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, const int&, callable_rank<6>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, const long&, callable_rank<6>>::value, "Not callable"); + static_assert(boost::hof::is_invocable<is_callable_rank_class, const double&, callable_rank<6>>::value, "Not callable"); + + static_assert(not boost::hof::is_invocable<is_callable_rank_class, int, callable_rank<1>>::value, "callable failed"); + static_assert(not boost::hof::is_invocable<is_callable_rank_class, long, callable_rank<1>>::value, "callable failed"); + static_assert(not boost::hof::is_invocable<is_callable_rank_class, double, callable_rank<1>>::value, "callable failed"); + static_assert(not boost::hof::is_invocable<is_callable_rank_class, const int&, callable_rank<1>>::value, "callable failed"); + static_assert(not boost::hof::is_invocable<is_callable_rank_class, const long&, callable_rank<1>>::value, "callable failed"); + static_assert(not boost::hof::is_invocable<is_callable_rank_class, const double&, callable_rank<1>>::value, "callable failed"); + + static_assert(not boost::hof::is_invocable<is_callable_rank_class, callable_test_param, callable_test_param>::value, "callable failed"); + static_assert(not boost::hof::is_invocable<is_callable_rank_class, callable_rank<3>, callable_test_param>::value, "callable failed"); + static_assert(not boost::hof::is_invocable<is_callable_rank_class, callable_rank<4>, callable_test_param>::value, "callable failed"); + static_assert(not boost::hof::is_invocable<is_callable_rank_class, callable_test_param, callable_rank<3>>::value, "callable failed"); + static_assert(not boost::hof::is_invocable<is_callable_rank_class, callable_test_param, callable_rank<4>>::value, "callable failed"); + static_assert(not boost::hof::is_invocable<is_callable_rank_class>::value, "callable failed"); + static_assert(not boost::hof::is_invocable<is_callable_rank_class, int, int>::value, "callable failed"); +}; + +BOOST_HOF_STATIC_TEST_CASE() +{ + typedef int(callable_rank<0>::*fn)(int); + + static_assert(boost::hof::is_invocable<fn, callable_rank<0>&, int>::value, "Failed"); + static_assert(boost::hof::is_invocable<fn, callable_rank<1>&, int>::value, "Failed"); + static_assert(!boost::hof::is_invocable<fn, callable_rank<0>&>::value, "Failed"); + static_assert(!boost::hof::is_invocable<fn, callable_rank<0> const&, int>::value, "Failed"); +}; + +BOOST_HOF_STATIC_TEST_CASE() +{ + typedef int(callable_rank<0>::*fn)(int); + + typedef callable_rank<0>* T; + typedef callable_rank<1>* DT; + typedef const callable_rank<0>* CT; + typedef std::unique_ptr<callable_rank<0>> ST; + + static_assert(boost::hof::is_invocable<fn, T&, int>::value, "Failed"); + static_assert(boost::hof::is_invocable<fn, DT&, int>::value, "Failed"); + static_assert(boost::hof::is_invocable<fn, const T&, int>::value, "Failed"); + static_assert(boost::hof::is_invocable<fn, T&&, int>::value, "Failed"); + static_assert(boost::hof::is_invocable<fn, ST, int>::value, "Failed"); + static_assert(!boost::hof::is_invocable<fn, CT&, int>::value, "Failed"); + +}; + +BOOST_HOF_STATIC_TEST_CASE() +{ + typedef int(callable_rank<0>::*fn); + + static_assert(!boost::hof::is_invocable<fn>::value, "Failed"); +}; + +BOOST_HOF_STATIC_TEST_CASE() +{ + typedef int(callable_rank<0>::*fn); + + static_assert(boost::hof::is_invocable<fn, callable_rank<0>&>::value, "Failed"); + static_assert(boost::hof::is_invocable<fn, callable_rank<0>&&>::value, "Failed"); + static_assert(boost::hof::is_invocable<fn, const callable_rank<0>&>::value, "Failed"); + static_assert(boost::hof::is_invocable<fn, callable_rank<1>&>::value, "Failed"); +}; + +BOOST_HOF_STATIC_TEST_CASE() +{ + typedef int(callable_rank<0>::*fn); + + typedef callable_rank<0>* T; + typedef callable_rank<1>* DT; + typedef const callable_rank<0>* CT; + typedef std::unique_ptr<callable_rank<0>> ST; + + static_assert(boost::hof::is_invocable<fn, T&>::value, "Failed"); + static_assert(boost::hof::is_invocable<fn, DT&>::value, "Failed"); + static_assert(boost::hof::is_invocable<fn, const T&>::value, "Failed"); + static_assert(boost::hof::is_invocable<fn, T&&>::value, "Failed"); + static_assert(boost::hof::is_invocable<fn, ST>::value, "Failed"); + static_assert(boost::hof::is_invocable<fn, CT&>::value, "Failed"); + +}; + +BOOST_HOF_STATIC_TEST_CASE() +{ + typedef void(*fp)(callable_rank<0>&, int); + + static_assert(boost::hof::is_invocable<fp, callable_rank<0>&, int>::value, "Failed"); + static_assert(boost::hof::is_invocable<fp, callable_rank<1>&, int>::value, "Failed"); + static_assert(!boost::hof::is_invocable<fp, const callable_rank<0>&, int>::value, "Failed"); + static_assert(!boost::hof::is_invocable<fp>::value, "Failed"); + static_assert(!boost::hof::is_invocable<fp, callable_rank<0>&>::value, "Failed"); +}; + +BOOST_HOF_STATIC_TEST_CASE() +{ + typedef void(&fp)(callable_rank<0>&, int); + + static_assert(boost::hof::is_invocable<fp, callable_rank<0>&, int>::value, "Failed"); + static_assert(boost::hof::is_invocable<fp, callable_rank<1>&, int>::value, "Failed"); + static_assert(!boost::hof::is_invocable<fp, const callable_rank<0>&, int>::value, "Failed"); + static_assert(!boost::hof::is_invocable<fp>::value, "Failed"); + static_assert(!boost::hof::is_invocable<fp, callable_rank<0>&>::value, "Failed"); +}; diff --git a/src/boost/libs/hof/test/issue8.cpp b/src/boost/libs/hof/test/issue8.cpp new file mode 100644 index 000000000..08acb9a70 --- /dev/null +++ b/src/boost/libs/hof/test/issue8.cpp @@ -0,0 +1,48 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + issue8.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 "test.hpp" +#include <vector> +#include <boost/hof/pipable.hpp> +#include <boost/hof/placeholders.hpp> +#include <algorithm> + + +struct filter_fn +{ + template<class Input, class P> + Input operator()(Input input, P pred) const + { + Input output(input.size()); + output.erase( + ::std::copy_if( + ::std::begin(input), + ::std::end(input), + ::std::begin(output), + pred + ), + ::std::end(output) + ); + return output; + } +}; + +static constexpr boost::hof::pipable_adaptor<filter_fn> filter = {}; + +BOOST_HOF_TEST_CASE() +{ + std::vector<int> data; + for(int i=0;i<6;i++) + { + data.push_back(i); + } + std::vector<int> r1 = data | filter(boost::hof::_1 > 1); + BOOST_HOF_TEST_CHECK(r1.size() == 4); + + std::vector<int> r2 = filter(data, boost::hof::_1 > 1); + BOOST_HOF_TEST_CHECK(r2.size() == 4); +} diff --git a/src/boost/libs/hof/test/lambda.cpp b/src/boost/libs/hof/test/lambda.cpp new file mode 100644 index 000000000..42e79959f --- /dev/null +++ b/src/boost/libs/hof/test/lambda.cpp @@ -0,0 +1,103 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + lambda.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 <boost/hof/lambda.hpp> +#include <boost/hof/first_of.hpp> +#include <boost/hof/partial.hpp> +#include <boost/hof/infix.hpp> +#include <boost/hof/pipable.hpp> +#include <memory> +#include "test.hpp" + + +static constexpr auto add_one = BOOST_HOF_STATIC_LAMBDA(int x) +{ + return x + 1; +}; + +template<class F> +struct wrapper : F +{ + BOOST_HOF_INHERIT_CONSTRUCTOR(wrapper, F) +}; + +template<class T> +constexpr wrapper<T> wrap(T x) +{ + return x; +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == add_one(2)); +} + +BOOST_HOF_TEST_CASE() +{ + constexpr auto add_one_again = add_one; + BOOST_HOF_TEST_CHECK(3 == add_one_again(2)); +} + +BOOST_HOF_TEST_CASE() +{ + constexpr auto add_one_again = wrap(add_one); + BOOST_HOF_TEST_CHECK(3 == add_one_again(2)); +} + +namespace test_static { + +BOOST_HOF_STATIC_LAMBDA_FUNCTION(add_one) = [](int x) +{ + return x + 1; +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(add_one(2) == 3); +} + +BOOST_HOF_STATIC_LAMBDA_FUNCTION(sum_partial) = boost::hof::partial([](int x, int y) +{ + return x + y; +}); + +BOOST_HOF_TEST_CASE() +{ +#ifndef _MSC_VER + STATIC_ASSERT_EMPTY(sum_partial); +#endif + BOOST_HOF_TEST_CHECK(3 == sum_partial(1, 2)); + BOOST_HOF_TEST_CHECK(3 == sum_partial(1)(2)); +} + +BOOST_HOF_STATIC_LAMBDA_FUNCTION(add_one_pipable) = boost::hof::pipable([](int x) +{ + return x + 1; +}); + +BOOST_HOF_TEST_CASE() +{ +#ifndef _MSC_VER + STATIC_ASSERT_EMPTY(add_one_pipable); +#endif + BOOST_HOF_TEST_CHECK(3 == add_one_pipable(2)); + BOOST_HOF_TEST_CHECK(3 == (2 | add_one_pipable)); +} + +BOOST_HOF_STATIC_LAMBDA_FUNCTION(sum_infix) = boost::hof::infix([](int x, int y) +{ + return x + y; +}); + +BOOST_HOF_TEST_CASE() +{ +#ifndef _MSC_VER + STATIC_ASSERT_EMPTY(sum_infix); +#endif + BOOST_HOF_TEST_CHECK(3 == (1 <sum_infix> 2)); +} + +} diff --git a/src/boost/libs/hof/test/lazy.cpp b/src/boost/libs/hof/test/lazy.cpp new file mode 100644 index 000000000..bea58fe69 --- /dev/null +++ b/src/boost/libs/hof/test/lazy.cpp @@ -0,0 +1,713 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + lazy.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 <boost/hof/lazy.hpp> +#include <memory> +#include "test.hpp" + +template<int N> +struct test_placeholder +{}; + +namespace std { + template<int N> + struct is_placeholder<test_placeholder<N>> + : std::integral_constant<int, N> + {}; +} + +BOOST_HOF_TEST_CASE() +{ + int i = 5; + + static_assert(std::is_reference<decltype(boost::hof::detail::ref_transformer()(std::ref(i))(0,0,0))>::value, "Reference wrapper failed"); + static_assert(std::is_reference<decltype(boost::hof::detail::pick_transformer(std::ref(i))(0,0,0))>::value, "Reference wrapper failed"); + static_assert(std::is_reference<decltype(boost::hof::detail::lazy_transform(std::ref(i), boost::hof::pack_basic(0,0,0)))>::value, "Reference wrapper failed"); + + BOOST_HOF_TEST_CHECK(&boost::hof::detail::ref_transformer()(std::ref(i))(0,0,0) == &i); + BOOST_HOF_TEST_CHECK(&boost::hof::detail::pick_transformer(std::ref(i))(0,0,0) == &i); + BOOST_HOF_TEST_CHECK(&boost::hof::detail::lazy_transform(std::ref(i), boost::hof::pack_basic(0,0,0)) == &i); +} + +BOOST_HOF_TEST_CASE() +{ + int i = 5; + + BOOST_HOF_TEST_CHECK(boost::hof::detail::id_transformer()(i)(0,0,0) == i); + BOOST_HOF_TEST_CHECK(boost::hof::detail::pick_transformer(i)(0,0,0) == i); + BOOST_HOF_TEST_CHECK(boost::hof::detail::lazy_transform(i, boost::hof::pack_basic(0,0,0)) == i); +} + +BOOST_HOF_TEST_CASE() +{ + auto id =[](int i){ return i;}; + auto fi = std::bind(id, 5); + + BOOST_HOF_TEST_CHECK(boost::hof::detail::bind_transformer()(fi)(0,0,0) == id(5)); + BOOST_HOF_TEST_CHECK(boost::hof::detail::pick_transformer(fi)(0,0,0) == id(5)); + BOOST_HOF_TEST_CHECK(boost::hof::detail::lazy_transform(fi, boost::hof::pack_basic(0,0,0)) == id(5)); +} + +struct f_0 { +constexpr long operator()() const +{ + return 17041L; +} +}; + +struct f_1 { +constexpr long operator()(long a) const +{ + return a; +} +}; + +struct f_2 { +constexpr long operator()(long a, long b) const +{ + return a + 10 * b; +} +}; + +static long global_result; + +struct fv_0 { +void operator()() const +{ + global_result = 17041L; +} +}; + +struct fv_1 { +void operator()(long a) const +{ + global_result = a; +} +}; + +struct fv_2 { +void operator()(long a, long b) const +{ + global_result = a + 10 * b; +} +}; + +struct Y +{ + short operator()(short & r) const { return ++r; } + int operator()(int a, int b) const { return a + 10 * b; } + long operator() (long a, long b, long c) const { return a + 10 * b + 100 * c; } + void operator() (long a, long b, long c, long d) const { global_result = a + 10 * b + 100 * c + 1000 * d; } +}; + +BOOST_HOF_TEST_CASE() +{ + short i(6); + + int const k = 3; + + BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( std::ref(i))() == 7 ); + BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( std::ref(i))() == 8 ); + BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( i,std::placeholders::_1)(k) == 38 ); + BOOST_HOF_TEST_CHECK( boost::hof::lazy(Y())( i,std::placeholders::_1, 9)(k) == 938 ); + + global_result = 0; + boost::hof::lazy(Y())( i,std::placeholders::_1, 9, 4)(k); + BOOST_HOF_TEST_CHECK( global_result == 4938 ); + +} + +BOOST_HOF_TEST_CASE() +{ + int const x = 1; + int const y = 2; + + BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_1())(std::placeholders::_1))(x) == 1L ); + BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_2())(std::placeholders::_1, std::placeholders::_2))(x, y) == 21L ); + BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_2())( boost::hof::lazy(f_1())(std::placeholders::_1), boost::hof::lazy(f_1())(std::placeholders::_1))(x) == 11L ); + BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_2())( boost::hof::lazy(f_1())(std::placeholders::_1), boost::hof::lazy(f_1())( std::placeholders::_2))(x, y) == 21L ); + BOOST_HOF_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_0())())() == 17041L ); + + BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_1())(test_placeholder<1>()))(x) == 1L ); + BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_2())(test_placeholder<1>(), test_placeholder<2>()))(x, y) == 21L ); + BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_2())( boost::hof::lazy(f_1())(test_placeholder<1>()), boost::hof::lazy(f_1())(test_placeholder<1>()))(x) == 11L ); + BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_2())( boost::hof::lazy(f_1())(test_placeholder<1>()), boost::hof::lazy(f_1())( test_placeholder<2>()))(x, y) == 21L ); + BOOST_HOF_STATIC_TEST_CHECK( boost::hof::lazy(f_1())( boost::hof::lazy(f_0())())() == 17041L ); + + BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_1())( boost::hof::lazy(f_1())(std::placeholders::_1))(x), (global_result == 1L)) ); + BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_1())( boost::hof::lazy(f_2())(std::placeholders::_1, std::placeholders::_2))(x, y), (global_result == 21L)) ); + BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_2())( boost::hof::lazy(f_1())(std::placeholders::_1), boost::hof::lazy(f_1())(std::placeholders::_1))(x), (global_result == 11L)) ); + BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_2())( boost::hof::lazy(f_1())(std::placeholders::_1), boost::hof::lazy(f_1())( std::placeholders::_2))(x, y), (global_result == 21L)) ); + BOOST_HOF_TEST_CHECK( (boost::hof::lazy(fv_1())( boost::hof::lazy(f_0())())(), (global_result == 17041L)) ); +} + + +struct X +{ + mutable unsigned int hash; + + X(): hash(0) {} + + int f0() { f1(17); return 0; } + int g0() const { g1(17); return 0; } + + int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; } + int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; } + + int f2(int a1, int a2) { f1(a1); f1(a2); return 0; } + int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; } + + int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; } + int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; } + + int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; } + int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; } + + int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; } + int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; } + + int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; } + int g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); return 0; } + + int f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); return 0; } + int g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); return 0; } + + int f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); return 0; } + int g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); return 0; } +}; + +struct V +{ + mutable unsigned int hash; + + V(): hash(0) {} + + void f0() { f1(17); } + void g0() const { g1(17); } + + void f1(int a1) { hash = (hash * 17041 + a1) % 32768; } + void g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; } + + void f2(int a1, int a2) { f1(a1); f1(a2); } + void g2(int a1, int a2) const { g1(a1); g1(a2); } + + void f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); } + void g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); } + + void f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); } + void g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); } + + void f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); } + void g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); } + + void f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); } + void g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); } + + void f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); } + void g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); } + + void f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); } + void g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); } +}; + +BOOST_HOF_TEST_CASE() +{ + + X x; + + // 0 + + boost::hof::lazy(&X::f0)(&x)(); + boost::hof::lazy(&X::f0)(std::ref(x))(); + + boost::hof::lazy(&X::g0)(&x)(); + boost::hof::lazy(&X::g0)(x)(); + boost::hof::lazy(&X::g0)(std::ref(x))(); + + // 1 + + boost::hof::lazy(&X::f1)(&x, 1)(); + boost::hof::lazy(&X::f1)(std::ref(x), 1)(); + + boost::hof::lazy(&X::g1)(&x, 1)(); + boost::hof::lazy(&X::g1)(x, 1)(); + boost::hof::lazy(&X::g1)(std::ref(x), 1)(); + + // 2 + + boost::hof::lazy(&X::f2)(&x, 1, 2)(); + boost::hof::lazy(&X::f2)(std::ref(x), 1, 2)(); + + boost::hof::lazy(&X::g2)(&x, 1, 2)(); + boost::hof::lazy(&X::g2)(x, 1, 2)(); + boost::hof::lazy(&X::g2)(std::ref(x), 1, 2)(); + + // 3 + + boost::hof::lazy(&X::f3)(&x, 1, 2, 3)(); + boost::hof::lazy(&X::f3)(std::ref(x), 1, 2, 3)(); + + boost::hof::lazy(&X::g3)(&x, 1, 2, 3)(); + boost::hof::lazy(&X::g3)(x, 1, 2, 3)(); + boost::hof::lazy(&X::g3)(std::ref(x), 1, 2, 3)(); + + // 4 + + boost::hof::lazy(&X::f4)(&x, 1, 2, 3, 4)(); + boost::hof::lazy(&X::f4)(std::ref(x), 1, 2, 3, 4)(); + + boost::hof::lazy(&X::g4)(&x, 1, 2, 3, 4)(); + boost::hof::lazy(&X::g4)(x, 1, 2, 3, 4)(); + boost::hof::lazy(&X::g4)(std::ref(x), 1, 2, 3, 4)(); + + // 5 + + boost::hof::lazy(&X::f5)(&x, 1, 2, 3, 4, 5)(); + boost::hof::lazy(&X::f5)(std::ref(x), 1, 2, 3, 4, 5)(); + + boost::hof::lazy(&X::g5)(&x, 1, 2, 3, 4, 5)(); + boost::hof::lazy(&X::g5)(x, 1, 2, 3, 4, 5)(); + boost::hof::lazy(&X::g5)(std::ref(x), 1, 2, 3, 4, 5)(); + + // 6 + + boost::hof::lazy(&X::f6)(&x, 1, 2, 3, 4, 5, 6)(); + boost::hof::lazy(&X::f6)(std::ref(x), 1, 2, 3, 4, 5, 6)(); + + boost::hof::lazy(&X::g6)(&x, 1, 2, 3, 4, 5, 6)(); + boost::hof::lazy(&X::g6)(x, 1, 2, 3, 4, 5, 6)(); + boost::hof::lazy(&X::g6)(std::ref(x), 1, 2, 3, 4, 5, 6)(); + + // 7 + + boost::hof::lazy(&X::f7)(&x, 1, 2, 3, 4, 5, 6, 7)(); + boost::hof::lazy(&X::f7)(std::ref(x), 1, 2, 3, 4, 5, 6, 7)(); + + boost::hof::lazy(&X::g7)(&x, 1, 2, 3, 4, 5, 6, 7)(); + boost::hof::lazy(&X::g7)(x, 1, 2, 3, 4, 5, 6, 7)(); + boost::hof::lazy(&X::g7)(std::ref(x), 1, 2, 3, 4, 5, 6, 7)(); + + // 8 + + boost::hof::lazy(&X::f8)(&x, 1, 2, 3, 4, 5, 6, 7, 8)(); + boost::hof::lazy(&X::f8)(std::ref(x), 1, 2, 3, 4, 5, 6, 7, 8)(); + + boost::hof::lazy(&X::g8)(&x, 1, 2, 3, 4, 5, 6, 7, 8)(); + boost::hof::lazy(&X::g8)(x, 1, 2, 3, 4, 5, 6, 7, 8)(); + boost::hof::lazy(&X::g8)(std::ref(x), 1, 2, 3, 4, 5, 6, 7, 8)(); + + BOOST_HOF_TEST_CHECK( x.hash == 23558 ); +} + +BOOST_HOF_TEST_CASE() +{ + V v; + + // 0 + + boost::hof::lazy(&V::f0)(&v)(); + boost::hof::lazy(&V::f0)(std::ref(v))(); + + boost::hof::lazy(&V::g0)(&v)(); + boost::hof::lazy(&V::g0)(v)(); + boost::hof::lazy(&V::g0)(std::ref(v))(); + + // 1 + + boost::hof::lazy(&V::f1)(&v, 1)(); + boost::hof::lazy(&V::f1)(std::ref(v), 1)(); + + boost::hof::lazy(&V::g1)(&v, 1)(); + boost::hof::lazy(&V::g1)(v, 1)(); + boost::hof::lazy(&V::g1)(std::ref(v), 1)(); + + // 2 + + boost::hof::lazy(&V::f2)(&v, 1, 2)(); + boost::hof::lazy(&V::f2)(std::ref(v), 1, 2)(); + + boost::hof::lazy(&V::g2)(&v, 1, 2)(); + boost::hof::lazy(&V::g2)(v, 1, 2)(); + boost::hof::lazy(&V::g2)(std::ref(v), 1, 2)(); + + // 3 + + boost::hof::lazy(&V::f3)(&v, 1, 2, 3)(); + boost::hof::lazy(&V::f3)(std::ref(v), 1, 2, 3)(); + + boost::hof::lazy(&V::g3)(&v, 1, 2, 3)(); + boost::hof::lazy(&V::g3)(v, 1, 2, 3)(); + boost::hof::lazy(&V::g3)(std::ref(v), 1, 2, 3)(); + + // 4 + + boost::hof::lazy(&V::f4)(&v, 1, 2, 3, 4)(); + boost::hof::lazy(&V::f4)(std::ref(v), 1, 2, 3, 4)(); + + boost::hof::lazy(&V::g4)(&v, 1, 2, 3, 4)(); + boost::hof::lazy(&V::g4)(v, 1, 2, 3, 4)(); + boost::hof::lazy(&V::g4)(std::ref(v), 1, 2, 3, 4)(); + + // 5 + + boost::hof::lazy(&V::f5)(&v, 1, 2, 3, 4, 5)(); + boost::hof::lazy(&V::f5)(std::ref(v), 1, 2, 3, 4, 5)(); + + boost::hof::lazy(&V::g5)(&v, 1, 2, 3, 4, 5)(); + boost::hof::lazy(&V::g5)(v, 1, 2, 3, 4, 5)(); + boost::hof::lazy(&V::g5)(std::ref(v), 1, 2, 3, 4, 5)(); + + // 6 + + boost::hof::lazy(&V::f6)(&v, 1, 2, 3, 4, 5, 6)(); + boost::hof::lazy(&V::f6)(std::ref(v), 1, 2, 3, 4, 5, 6)(); + + boost::hof::lazy(&V::g6)(&v, 1, 2, 3, 4, 5, 6)(); + boost::hof::lazy(&V::g6)(v, 1, 2, 3, 4, 5, 6)(); + boost::hof::lazy(&V::g6)(std::ref(v), 1, 2, 3, 4, 5, 6)(); + + // 7 + + boost::hof::lazy(&V::f7)(&v, 1, 2, 3, 4, 5, 6, 7)(); + boost::hof::lazy(&V::f7)(std::ref(v), 1, 2, 3, 4, 5, 6, 7)(); + + boost::hof::lazy(&V::g7)(&v, 1, 2, 3, 4, 5, 6, 7)(); + boost::hof::lazy(&V::g7)(v, 1, 2, 3, 4, 5, 6, 7)(); + boost::hof::lazy(&V::g7)(std::ref(v), 1, 2, 3, 4, 5, 6, 7)(); + + // 8 + + boost::hof::lazy(&V::f8)(&v, 1, 2, 3, 4, 5, 6, 7, 8)(); + boost::hof::lazy(&V::f8)(std::ref(v), 1, 2, 3, 4, 5, 6, 7, 8)(); + + boost::hof::lazy(&V::g8)(&v, 1, 2, 3, 4, 5, 6, 7, 8)(); + boost::hof::lazy(&V::g8)(v, 1, 2, 3, 4, 5, 6, 7, 8)(); + boost::hof::lazy(&V::g8)(std::ref(v), 1, 2, 3, 4, 5, 6, 7, 8)(); + + BOOST_HOF_TEST_CHECK( v.hash == 23558 ); +} + +struct id +{ + int operator()(int i) const + { + return i; + } +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::lazy(id())(3)() == 3); +} + +struct deref +{ + int operator()(const std::unique_ptr<int>& i) const + { + return *i; + } +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::lazy(deref())(std::unique_ptr<int>(new int(3)))() == 3); +} + +void fv1( std::unique_ptr<int> p1 ) +{ + BOOST_HOF_TEST_CHECK( *p1 == 1 ); +} + +void fv2( std::unique_ptr<int> p1, std::unique_ptr<int> p2 ) +{ + BOOST_HOF_TEST_CHECK( *p1 == 1 ); + BOOST_HOF_TEST_CHECK( *p2 == 2 ); +} + +void fv3( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3 ) +{ + BOOST_HOF_TEST_CHECK( *p1 == 1 ); + BOOST_HOF_TEST_CHECK( *p2 == 2 ); + BOOST_HOF_TEST_CHECK( *p3 == 3 ); +} + +void fv4( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4 ) +{ + BOOST_HOF_TEST_CHECK( *p1 == 1 ); + BOOST_HOF_TEST_CHECK( *p2 == 2 ); + BOOST_HOF_TEST_CHECK( *p3 == 3 ); + BOOST_HOF_TEST_CHECK( *p4 == 4 ); +} + +void fv5( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4, std::unique_ptr<int> p5 ) +{ + BOOST_HOF_TEST_CHECK( *p1 == 1 ); + BOOST_HOF_TEST_CHECK( *p2 == 2 ); + BOOST_HOF_TEST_CHECK( *p3 == 3 ); + BOOST_HOF_TEST_CHECK( *p4 == 4 ); + BOOST_HOF_TEST_CHECK( *p5 == 5 ); +} + +void fv6( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4, std::unique_ptr<int> p5, std::unique_ptr<int> p6 ) +{ + BOOST_HOF_TEST_CHECK( *p1 == 1 ); + BOOST_HOF_TEST_CHECK( *p2 == 2 ); + BOOST_HOF_TEST_CHECK( *p3 == 3 ); + BOOST_HOF_TEST_CHECK( *p4 == 4 ); + BOOST_HOF_TEST_CHECK( *p5 == 5 ); + BOOST_HOF_TEST_CHECK( *p6 == 6 ); +} + +void fv7( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4, std::unique_ptr<int> p5, std::unique_ptr<int> p6, std::unique_ptr<int> p7 ) +{ + BOOST_HOF_TEST_CHECK( *p1 == 1 ); + BOOST_HOF_TEST_CHECK( *p2 == 2 ); + BOOST_HOF_TEST_CHECK( *p3 == 3 ); + BOOST_HOF_TEST_CHECK( *p4 == 4 ); + BOOST_HOF_TEST_CHECK( *p5 == 5 ); + BOOST_HOF_TEST_CHECK( *p6 == 6 ); + BOOST_HOF_TEST_CHECK( *p7 == 7 ); +} + +void fv8( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4, std::unique_ptr<int> p5, std::unique_ptr<int> p6, std::unique_ptr<int> p7, std::unique_ptr<int> p8 ) +{ + BOOST_HOF_TEST_CHECK( *p1 == 1 ); + BOOST_HOF_TEST_CHECK( *p2 == 2 ); + BOOST_HOF_TEST_CHECK( *p3 == 3 ); + BOOST_HOF_TEST_CHECK( *p4 == 4 ); + BOOST_HOF_TEST_CHECK( *p5 == 5 ); + BOOST_HOF_TEST_CHECK( *p6 == 6 ); + BOOST_HOF_TEST_CHECK( *p7 == 7 ); + BOOST_HOF_TEST_CHECK( *p8 == 8 ); +} + +void fv9( std::unique_ptr<int> p1, std::unique_ptr<int> p2, std::unique_ptr<int> p3, std::unique_ptr<int> p4, std::unique_ptr<int> p5, std::unique_ptr<int> p6, std::unique_ptr<int> p7, std::unique_ptr<int> p8, std::unique_ptr<int> p9 ) +{ + BOOST_HOF_TEST_CHECK( *p1 == 1 ); + BOOST_HOF_TEST_CHECK( *p2 == 2 ); + BOOST_HOF_TEST_CHECK( *p3 == 3 ); + BOOST_HOF_TEST_CHECK( *p4 == 4 ); + BOOST_HOF_TEST_CHECK( *p5 == 5 ); + BOOST_HOF_TEST_CHECK( *p6 == 6 ); + BOOST_HOF_TEST_CHECK( *p7 == 7 ); + BOOST_HOF_TEST_CHECK( *p8 == 8 ); + BOOST_HOF_TEST_CHECK( *p9 == 9 ); +} + +BOOST_HOF_TEST_CASE() +{ + std::unique_ptr<int> p1( new int(1) ); + + boost::hof::lazy( fv1 )( std::placeholders::_1 )( std::move( p1 ) ); +} +BOOST_HOF_TEST_CASE() +{ + std::unique_ptr<int> p1( new int(1) ); + std::unique_ptr<int> p2( new int(2) ); + + boost::hof::lazy( fv2 )( std::placeholders::_1, std::placeholders::_2 )( std::move( p1 ), std::move( p2 ) ); +} +BOOST_HOF_TEST_CASE() +{ + std::unique_ptr<int> p1( new int(1) ); + std::unique_ptr<int> p2( new int(2) ); + std::unique_ptr<int> p3( new int(3) ); + + boost::hof::lazy( fv3 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3 )( std::move( p1 ), std::move( p2 ), std::move( p3 ) ); +} +BOOST_HOF_TEST_CASE() +{ + std::unique_ptr<int> p1( new int(1) ); + std::unique_ptr<int> p2( new int(2) ); + std::unique_ptr<int> p3( new int(3) ); + std::unique_ptr<int> p4( new int(4) ); + + boost::hof::lazy( fv4 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ) ); +} +BOOST_HOF_TEST_CASE() +{ + std::unique_ptr<int> p1( new int(1) ); + std::unique_ptr<int> p2( new int(2) ); + std::unique_ptr<int> p3( new int(3) ); + std::unique_ptr<int> p4( new int(4) ); + std::unique_ptr<int> p5( new int(5) ); + + boost::hof::lazy( fv5 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ) ); +} +BOOST_HOF_TEST_CASE() +{ + std::unique_ptr<int> p1( new int(1) ); + std::unique_ptr<int> p2( new int(2) ); + std::unique_ptr<int> p3( new int(3) ); + std::unique_ptr<int> p4( new int(4) ); + std::unique_ptr<int> p5( new int(5) ); + std::unique_ptr<int> p6( new int(6) ); + + boost::hof::lazy( fv6 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ) ); +} +BOOST_HOF_TEST_CASE() +{ + std::unique_ptr<int> p1( new int(1) ); + std::unique_ptr<int> p2( new int(2) ); + std::unique_ptr<int> p3( new int(3) ); + std::unique_ptr<int> p4( new int(4) ); + std::unique_ptr<int> p5( new int(5) ); + std::unique_ptr<int> p6( new int(6) ); + std::unique_ptr<int> p7( new int(7) ); + + boost::hof::lazy( fv7 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ), std::move( p7 ) ); +} +BOOST_HOF_TEST_CASE() +{ + std::unique_ptr<int> p1( new int(1) ); + std::unique_ptr<int> p2( new int(2) ); + std::unique_ptr<int> p3( new int(3) ); + std::unique_ptr<int> p4( new int(4) ); + std::unique_ptr<int> p5( new int(5) ); + std::unique_ptr<int> p6( new int(6) ); + std::unique_ptr<int> p7( new int(7) ); + std::unique_ptr<int> p8( new int(8) ); + + boost::hof::lazy( fv8 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ), std::move( p7 ), std::move( p8 ) ); +} +BOOST_HOF_TEST_CASE() +{ + std::unique_ptr<int> p1( new int(1) ); + std::unique_ptr<int> p2( new int(2) ); + std::unique_ptr<int> p3( new int(3) ); + std::unique_ptr<int> p4( new int(4) ); + std::unique_ptr<int> p5( new int(5) ); + std::unique_ptr<int> p6( new int(6) ); + std::unique_ptr<int> p7( new int(7) ); + std::unique_ptr<int> p8( new int(8) ); + std::unique_ptr<int> p9( new int(9) ); + + boost::hof::lazy( fv9 )( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8, std::placeholders::_9 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ), std::move( p7 ), std::move( p8 ), std::move( p9 ) ); +} + + +struct X_ref +{ + int f( int x ) + { + return x; + } + + int g( int x ) const + { + return -x; + } +}; + +BOOST_HOF_TEST_CASE() +{ + X_ref x; + + BOOST_HOF_TEST_CHECK( boost::hof::lazy( &X_ref::f )( std::ref( x ), std::placeholders::_1 )( 1 ) == 1 ); + BOOST_HOF_TEST_CHECK( boost::hof::lazy( &X_ref::g )( std::cref( x ), std::placeholders::_1 )( 2 ) == -2 ); +} + +BOOST_HOF_TEST_CASE() +{ + auto lazy_f_1 = boost::hof::lazy(f_1())(std::placeholders::_1); + static_assert(boost::hof::is_invocable<decltype(lazy_f_1), long>::value, "Invocable"); + static_assert(boost::hof::is_invocable<decltype(lazy_f_1), long, long>::value, "Invocable"); + + auto lazy_f_2 = boost::hof::lazy(f_2())(std::placeholders::_1, std::placeholders::_2); + static_assert(boost::hof::is_invocable<decltype(lazy_f_2), long, long>::value, "Invocable"); + static_assert(!boost::hof::is_invocable<decltype(lazy_f_2), long>::value, "Not SFINAE-friendly"); +} + +struct dummy_unary_fn +{ + template <typename S> + int operator()(S const &) const { return 0; } +}; + +struct bad_unary_fn +{ + template <typename S> + constexpr int operator()(S const &) const + { + static_assert(!std::is_same<S, S>::value, "Failure"); + return 0; + } +}; + +BOOST_HOF_TEST_CASE() +{ + auto b = boost::hof::lazy(dummy_unary_fn())(bad_unary_fn()); + b(0); +} + + +struct by_value_fn +{ + template<typename T, typename U> + void operator()(T &&, U &&) const + { + static_assert(std::is_same<U, int>::value, ""); + } +}; + +BOOST_HOF_TEST_CASE() +{ + boost::hof::lazy(by_value_fn{})(std::placeholders::_1, 42)("hello"); +} + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +struct copy_throws +{ + copy_throws() {} + copy_throws(copy_throws const&) {} + copy_throws(copy_throws&&) noexcept {} +}; + +struct no_throw_fo +{ + void operator()() const noexcept {} + void operator()(int) const noexcept {} + void operator()(copy_throws) const noexcept {} +}; + +struct throws_fo +{ + void operator()() const {} +}; + +struct member_obj +{ + int x; +}; + +BOOST_HOF_TEST_CASE() +{ + no_throw_fo obj; + copy_throws arg; + static_assert(noexcept(boost::hof::lazy(no_throw_fo{})()()), "noexcept lazy"); + static_assert(noexcept(boost::hof::lazy(obj)()()), "noexcept lazy"); + static_assert(!noexcept(boost::hof::lazy(obj)(arg)()), "noexcept lazy"); + static_assert(noexcept(boost::hof::lazy(obj)(1)()), "noexcept lazy"); + static_assert(noexcept(boost::hof::lazy(obj)(std::placeholders::_1)), "noexcept lazy"); + // static_assert(noexcept(boost::hof::lazy(obj)(std::placeholders::_1)()), "noexcept lazy"); + static_assert(noexcept(boost::hof::lazy(obj)(std::placeholders::_1)(1)), "noexcept lazy"); + static_assert(!noexcept(boost::hof::lazy(obj)(std::placeholders::_1)(arg)), "noexcept lazy"); + + static_assert(noexcept(boost::hof::lazy(obj)(std::move(arg))), "noexcept lazy"); + static_assert(!noexcept(boost::hof::lazy(obj)(std::move(arg))()), "noexcept lazy"); +} +BOOST_HOF_TEST_CASE() +{ + throws_fo obj; + static_assert(!noexcept(boost::hof::lazy(obj)()()), "noexcept lazy"); +} +BOOST_HOF_TEST_CASE() +{ + member_obj obj{42}; + static_assert(noexcept(boost::hof::lazy(&member_obj::x)(obj)()), "noexcept lazy"); + static_assert(noexcept(boost::hof::lazy(&member_obj::x)(std::placeholders::_1)(obj)), "noexcept lazy"); +} +#endif diff --git a/src/boost/libs/hof/test/lift.cpp b/src/boost/libs/hof/test/lift.cpp new file mode 100644 index 000000000..cae105783 --- /dev/null +++ b/src/boost/libs/hof/test/lift.cpp @@ -0,0 +1,58 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + lift.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 "test.hpp" +#include <boost/hof/lift.hpp> +#include <boost/hof/function.hpp> +#include <boost/hof/detail/move.hpp> +#include <tuple> +#include <algorithm> + +template<class T, class U> +constexpr T sum(T x, U y) BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(x+y) +{ + return x + y; +} + +BOOST_HOF_LIFT_CLASS(max_f, std::max); +BOOST_HOF_LIFT_CLASS(sum_f, sum); + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(sum_f()(1, 2)), "noexcept lift"); + static_assert(!noexcept(sum_f()(std::string(), std::string())), "noexcept lift"); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(max_f()(3, 4) == std::max(3, 4)); + + BOOST_HOF_TEST_CHECK(sum_f()(1, 2) == 3); + BOOST_HOF_STATIC_TEST_CHECK(sum_f()(1, 2) == 3); +} + +#if BOOST_HOF_HAS_GENERIC_LAMBDA +BOOST_HOF_TEST_CASE() +{ + auto my_max = BOOST_HOF_LIFT(std::max); + BOOST_HOF_TEST_CHECK(my_max(3, 4) == std::max(3, 4)); + + BOOST_HOF_TEST_CHECK(BOOST_HOF_LIFT(std::max)(3, 4) == std::max(3, 4)); + BOOST_HOF_TEST_CHECK(BOOST_HOF_LIFT(sum)(1, 2) == 3); +} + +BOOST_HOF_STATIC_FUNCTION(psum) = BOOST_HOF_LIFT(sum); +BOOST_HOF_STATIC_FUNCTION(pmax) = BOOST_HOF_LIFT(std::max); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(pmax(3, 4) == std::max(3, 4)); + + BOOST_HOF_TEST_CHECK(psum(1, 2) == 3); +} +#endif diff --git a/src/boost/libs/hof/test/limit.cpp b/src/boost/libs/hof/test/limit.cpp new file mode 100644 index 000000000..74697413e --- /dev/null +++ b/src/boost/libs/hof/test/limit.cpp @@ -0,0 +1,49 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + limit.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 <boost/hof/limit.hpp> +#include <boost/hof/is_invocable.hpp> +#include <boost/hof/pack.hpp> +#include "test.hpp" + +BOOST_HOF_TEST_CASE() +{ + auto f = boost::hof::limit(std::integral_constant<int, 2>())(binary_class()); + BOOST_HOF_TEST_CHECK(f(1, 2) == 3); + static_assert(boost::hof::function_param_limit<decltype(f)>::value == 2, "Function limit is 2"); +} + +BOOST_HOF_TEST_CASE() +{ + auto f = boost::hof::limit_c<2>(binary_class()); + BOOST_HOF_TEST_CHECK(f(1, 2) == 3); + static_assert(boost::hof::function_param_limit<decltype(f)>::value == 2, "Function limit is 2"); +} + +BOOST_HOF_TEST_CASE() +{ + auto f = boost::hof::limit_c<2>(boost::hof::always(3)); + BOOST_HOF_TEST_CHECK(f(1, 2) == 3); + BOOST_HOF_TEST_CHECK(f(1) == 3); + BOOST_HOF_TEST_CHECK(f() == 3); + static_assert(boost::hof::function_param_limit<decltype(f)>::value == 2, "Function limit is 2"); + static_assert(boost::hof::is_invocable<decltype(f), int>::value, "Invocable"); + static_assert(boost::hof::is_invocable<decltype(f), int, int>::value, "Invocable"); + static_assert(!boost::hof::is_invocable<decltype(f), int, int, int>::value, "Not Invocable"); +} + +BOOST_HOF_TEST_CASE() +{ + static_assert(!boost::hof::is_invocable<decltype(boost::hof::limit), int>::value, "Not integral constant"); +} + +BOOST_HOF_TEST_CASE() +{ + static_assert(boost::hof::function_param_limit<decltype(boost::hof::pack())>::value == 0, "Failed limit on pack"); + static_assert(boost::hof::function_param_limit<decltype(boost::hof::pack(1))>::value == 1, "Failed limit on pack"); + static_assert(boost::hof::function_param_limit<decltype(boost::hof::pack(1, 2))>::value == 2, "Failed limit on pack"); +} + diff --git a/src/boost/libs/hof/test/match.cpp b/src/boost/libs/hof/test/match.cpp new file mode 100644 index 000000000..0d09dfdf6 --- /dev/null +++ b/src/boost/libs/hof/test/match.cpp @@ -0,0 +1,193 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + match.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 <boost/hof/match.hpp> +#include <boost/hof/static.hpp> +#include <boost/hof/lambda.hpp> +#include <boost/hof/placeholders.hpp> +#include <boost/hof/limit.hpp> +#include "test.hpp" + +#include <memory> + +namespace test1 +{ + struct int_class + { + int operator()(int) const + { + return 1; + } + }; + + struct foo + {}; + + struct foo_class + { + foo operator()(foo) const + { + return foo(); + } + }; + + static constexpr boost::hof::static_<boost::hof::match_adaptor<int_class, foo_class> > fun = {}; + + static_assert(std::is_same<int, decltype(fun(1))>::value, "Failed match"); + static_assert(std::is_same<foo, decltype(fun(foo()))>::value, "Failed match"); +} + +struct int_class +{ + constexpr int operator()(int) const + { + return 1; + } +}; + +struct foo +{}; + +struct foo_class +{ + constexpr int operator()(foo) const + { + return 2; + } +}; + +static constexpr boost::hof::match_adaptor<int_class, foo_class> fun = {}; + +BOOST_HOF_TEST_CASE() +{ + + BOOST_HOF_TEST_CHECK(fun(1) == 1); + BOOST_HOF_TEST_CHECK(fun(foo()) == 2); + + BOOST_HOF_STATIC_TEST_CHECK(fun(1) == 1); + BOOST_HOF_STATIC_TEST_CHECK(fun(foo()) == 2); +}; + +BOOST_HOF_TEST_CASE() +{ + + BOOST_HOF_TEST_CHECK(boost::hof::reveal(fun)(1) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::reveal(fun)(foo()) == 2); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reveal(fun)(1) == 1); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reveal(fun)(foo()) == 2); +}; + +BOOST_HOF_TEST_CASE() +{ + + constexpr auto lam = boost::hof::match( + BOOST_HOF_STATIC_LAMBDA(int) { return 1; }, + BOOST_HOF_STATIC_LAMBDA(foo) { return 2; } + ); + + BOOST_HOF_TEST_CHECK(lam(1) == 1); + BOOST_HOF_TEST_CHECK(lam(foo()) == 2); +}; + +BOOST_HOF_TEST_CASE() +{ + int i = 0; + auto lam = boost::hof::match( + [&](int) { return i+1; }, + [&](foo) { return i+2; } + ); +// Disable this check on msvc, since lambdas might be default constructible +#ifndef _MSC_VER + STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(decltype(lam)); +#endif + BOOST_HOF_TEST_CHECK(lam(1) == 1); + BOOST_HOF_TEST_CHECK(lam(foo()) == 2); +}; + + +BOOST_HOF_TEST_CASE() +{ + struct not_default_constructible + { + int i; + not_default_constructible(int x) : i(x) + {} + }; + STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(not_default_constructible); + not_default_constructible ndc = not_default_constructible(0); + auto lam = boost::hof::match( + [&](int) { return ndc.i+1; }, + [&](foo) { return ndc.i+2; } + ); +// Disable this check on msvc, since lambdas might be default constructible +#ifndef _MSC_VER + STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(decltype(lam)); +#endif + + BOOST_HOF_TEST_CHECK(lam(1) == 1); + BOOST_HOF_TEST_CHECK(lam(foo()) == 2); +}; + + +struct int_move_class +{ + std::unique_ptr<int> i; + int_move_class() : i(new int(1)) + {} + int operator()(int) const + { + return *i; + } +}; + +struct foo_move_class +{ + std::unique_ptr<int> i; + foo_move_class() : i(new int(2)) + {} + int operator()(foo) const + { + return *i; + } +}; + +BOOST_HOF_TEST_CASE() +{ + auto fun_move = boost::hof::match(int_move_class(), foo_move_class()); + BOOST_HOF_TEST_CHECK(fun_move(1) == 1); + BOOST_HOF_TEST_CHECK(fun_move(foo()) == 2); + +}; + +BOOST_HOF_TEST_CASE() +{ + const auto negate = (!boost::hof::_); + const auto sub = (boost::hof::_ - boost::hof::_); + BOOST_HOF_TEST_CHECK(boost::hof::match(negate, sub)(0) == negate(0)); + BOOST_HOF_TEST_CHECK(boost::hof::match(negate, sub)(0, 1) == sub(0, 1)); +} + +BOOST_HOF_TEST_CASE() +{ + const auto negate = (!boost::hof::_1); + const auto sub = (boost::hof::_1 - boost::hof::_2); + BOOST_HOF_TEST_CHECK(boost::hof::match(negate, sub)(0) == negate(0)); + // This is test is disabled because its invalid. It is valid to give more + // parameters than what are used by the placeholders. So negate(0, 1) is a + // valid call, which makes the following test fail with ambigous overload. + // BOOST_HOF_TEST_CHECK(boost::hof::match(negate, sub)(0, 1) == sub(0, 1)); +} + +BOOST_HOF_TEST_CASE() +{ + const auto negate = boost::hof::limit_c<1>(!boost::hof::_1); + const auto sub = boost::hof::limit_c<2>(boost::hof::_1 - boost::hof::_2); + BOOST_HOF_TEST_CHECK(boost::hof::match(negate, sub)(0) == negate(0)); + // This test will pass because we have limited the number of parameters. + BOOST_HOF_TEST_CHECK(boost::hof::match(negate, sub)(0, 1) == sub(0, 1)); +} + diff --git a/src/boost/libs/hof/test/mutable.cpp b/src/boost/libs/hof/test/mutable.cpp new file mode 100644 index 000000000..d071bc639 --- /dev/null +++ b/src/boost/libs/hof/test/mutable.cpp @@ -0,0 +1,72 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + mutable.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 <boost/hof/mutable.hpp> +#include <boost/hof/lazy.hpp> +#include <boost/hof/detail/move.hpp> +#include <memory> +#include "test.hpp" + +struct mutable_fun +{ + int x; + mutable_fun() noexcept + : x(1) + {} + + int operator()(int i) noexcept + { + x+=i; + return x; + } +}; + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::mutable_(mutable_fun())(3)), "noexcept mutable_"); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::mutable_(mutable_fun())(3) == 4); +} + +BOOST_HOF_TEST_CASE() +{ + auto mut_fun = mutable_fun(); + auto by_5 = boost::hof::lazy(boost::hof::mutable_(std::ref(mut_fun)))(5); + BOOST_HOF_TEST_CHECK(by_5() == 6); + BOOST_HOF_TEST_CHECK(by_5() == 11); +} + +struct mutable_move_fun +{ + std::unique_ptr<int> x; + mutable_move_fun() : x(new int(1)) + {} + + int operator()(int i) + { + *x+=i; + return *x; + } +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::mutable_(mutable_move_fun())(3) == 4); +} + +BOOST_HOF_TEST_CASE() +{ + auto mut_fun = mutable_move_fun(); + auto by_5 = boost::hof::lazy(boost::hof::mutable_(boost::hof::move(mut_fun)))(5); + BOOST_HOF_TEST_CHECK(by_5() == 6); + BOOST_HOF_TEST_CHECK(by_5() == 11); +} + diff --git a/src/boost/libs/hof/test/pack.cpp b/src/boost/libs/hof/test/pack.cpp new file mode 100644 index 000000000..ac64c39ca --- /dev/null +++ b/src/boost/libs/hof/test/pack.cpp @@ -0,0 +1,395 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + pack.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 <boost/hof/pack.hpp> +#include <boost/hof/always.hpp> +#include <boost/hof/identity.hpp> +#include <memory> +#include "test.hpp" + +BOOST_HOF_TEST_CASE() +{ + auto p1 = boost::hof::pack_basic(1, 2); + auto p2 = p1; + BOOST_HOF_TEST_CHECK(p2(binary_class()) == p1(binary_class())); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_basic(1, 2)(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_basic(1, 2)(binary_class()) == 3 ); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack(1, 2)(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack(1, 2)(binary_class()) == 3 ); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_forward(1, 2)(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_forward(1, 2)(binary_class()) == 3 ); +} +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +struct copy_throws +{ + copy_throws() {} + copy_throws(copy_throws const&) {} + copy_throws(copy_throws&&) noexcept {} +}; + +BOOST_HOF_TEST_CASE() +{ + int i = 1; + copy_throws ct{}; + static_assert(!noexcept(boost::hof::pack(ct, ct)(boost::hof::always())), "noexcept pack"); + static_assert(noexcept(boost::hof::pack(1, 2)(boost::hof::always())), "noexcept pack"); + static_assert(noexcept(boost::hof::pack_forward(ct, ct)(boost::hof::always())), "noexcept pack"); + static_assert(noexcept(boost::hof::pack_forward(i, i)(boost::hof::always())), "noexcept pack"); + static_assert(noexcept(boost::hof::pack_forward(1, 2)(boost::hof::always())), "noexcept pack"); + static_assert(noexcept(boost::hof::pack_basic(ct, ct)(boost::hof::always())), "noexcept pack"); + static_assert(noexcept(boost::hof::pack_basic(i, i)(boost::hof::always())), "noexcept pack"); + static_assert(noexcept(boost::hof::pack_basic(1, 2)(boost::hof::always())), "noexcept pack"); + + static_assert(noexcept(boost::hof::pack()(boost::hof::always())), "noexcept pack"); + static_assert(noexcept(boost::hof::pack_forward()(boost::hof::always())), "noexcept pack"); + static_assert(noexcept(boost::hof::pack_basic()(boost::hof::always())), "noexcept pack"); +} + +BOOST_HOF_TEST_CASE() +{ + copy_throws ct{}; + static_assert(!noexcept(boost::hof::pack_join(boost::hof::pack(ct), boost::hof::pack(ct))(boost::hof::always())), "noexcept pack"); + static_assert(noexcept(boost::hof::pack_join(boost::hof::pack(1), boost::hof::pack(1))(boost::hof::always())), "noexcept pack"); + static_assert(noexcept(boost::hof::pack_join(boost::hof::pack(), boost::hof::pack())(boost::hof::always())), "noexcept pack"); + auto p = boost::hof::pack(1); + static_assert(noexcept(boost::hof::pack_join(p, boost::hof::pack())(boost::hof::always())), "noexcept pack"); + static_assert(noexcept(boost::hof::pack_join(boost::hof::pack(), p)(boost::hof::always())), "noexcept pack"); + static_assert(noexcept(boost::hof::pack_join(p, p)(boost::hof::always())), "noexcept pack"); + auto pt = boost::hof::pack(ct); + static_assert(!noexcept(boost::hof::pack_join(pt, boost::hof::pack())(boost::hof::always())), "noexcept pack"); + static_assert(!noexcept(boost::hof::pack_join(boost::hof::pack(), pt)(boost::hof::always())), "noexcept pack"); + static_assert(!noexcept(boost::hof::pack_join(pt, pt)(boost::hof::always())), "noexcept pack"); + +} +#endif +BOOST_HOF_TEST_CASE() +{ + static constexpr int x = 1; + static constexpr int y = 2; + + auto p1 = boost::hof::pack_basic(x, y); + static_assert(!boost::hof::detail::is_default_constructible<decltype(p1)>::value, "Pack default constructible"); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_basic(x, y)(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_basic(x, y)(binary_class()) == 3 ); + + auto p2 = boost::hof::pack(std::ref(x), std::ref(y)); + static_assert(!boost::hof::detail::is_default_constructible<decltype(p2)>::value, "Pack default constructible"); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack(x, y)(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack(std::ref(x), std::ref(y))(binary_class()) == 3 ); + + auto p3 = boost::hof::pack_forward(x, y); + static_assert(!boost::hof::detail::is_default_constructible<decltype(p3)>::value, "Pack default constructible"); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_forward(x, y)(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_forward(x, y)(binary_class()) == 3 ); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_basic()(boost::hof::always(3)) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_basic()(boost::hof::always(3)) == 3 ); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_basic(3)(boost::hof::identity) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_basic(3)(boost::hof::identity) == 3 ); +} + +BOOST_HOF_TEST_CASE() +{ + auto p = boost::hof::pack(1); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(p, boost::hof::pack(2))(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(p, p)(binary_class()) == 2); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(p, p, boost::hof::pack())(binary_class()) == 2); + +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1), boost::hof::pack_basic(2))(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1), boost::hof::pack_basic(2))(binary_class()) == 3 ); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1), boost::hof::pack(2))(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1), boost::hof::pack(2))(binary_class()) == 3 ); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1), boost::hof::pack_forward(2))(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1), boost::hof::pack_forward(2))(binary_class()) == 3 ); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(), boost::hof::pack_basic(1, 2))(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(), boost::hof::pack_basic(1, 2))(binary_class()) == 3 ); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(), boost::hof::pack(1, 2))(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(), boost::hof::pack(1, 2))(binary_class()) == 3 ); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(), boost::hof::pack_forward(1, 2))(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(), boost::hof::pack_forward(1, 2))(binary_class()) == 3 ); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1, 2), boost::hof::pack_basic())(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1, 2), boost::hof::pack_basic())(binary_class()) == 3 ); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1, 2), boost::hof::pack())(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1, 2), boost::hof::pack())(binary_class()) == 3 ); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1, 2), boost::hof::pack_forward())(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1, 2), boost::hof::pack_forward())(binary_class()) == 3 ); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1), boost::hof::pack_basic(), boost::hof::pack_basic(2))(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1), boost::hof::pack_basic(), boost::hof::pack_basic(2))(binary_class()) == 3 ); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1), boost::hof::pack(), boost::hof::pack(2))(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1), boost::hof::pack(), boost::hof::pack(2))(binary_class()) == 3 ); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1), boost::hof::pack_forward(), boost::hof::pack_forward(2))(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1), boost::hof::pack_forward(), boost::hof::pack_forward(2))(binary_class()) == 3 ); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(), boost::hof::pack_basic(1), boost::hof::pack_basic(), boost::hof::pack_basic(2))(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(), boost::hof::pack_basic(1), boost::hof::pack_basic(), boost::hof::pack_basic(2))(binary_class()) == 3 ); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(), boost::hof::pack(1), boost::hof::pack(), boost::hof::pack(2))(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(), boost::hof::pack(1), boost::hof::pack(), boost::hof::pack(2))(binary_class()) == 3 ); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(), boost::hof::pack_forward(1), boost::hof::pack_forward(), boost::hof::pack_forward(2))(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(), boost::hof::pack_forward(1), boost::hof::pack_forward(), boost::hof::pack_forward(2))(binary_class()) == 3 ); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1), boost::hof::pack_basic(), boost::hof::pack_basic(2), boost::hof::pack_basic())(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(1), boost::hof::pack_basic(), boost::hof::pack_basic(2), boost::hof::pack_basic())(binary_class()) == 3 ); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1), boost::hof::pack(), boost::hof::pack(2), boost::hof::pack())(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(1), boost::hof::pack(), boost::hof::pack(2), boost::hof::pack())(binary_class()) == 3 ); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1), boost::hof::pack_forward(), boost::hof::pack_forward(2), boost::hof::pack_forward())(binary_class()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(1), boost::hof::pack_forward(), boost::hof::pack_forward(2), boost::hof::pack_forward())(binary_class()) == 3 ); +} + +struct deref +{ + int operator()(const std::unique_ptr<int>& i) const + { + return *i; + } +}; + +BOOST_HOF_TEST_CASE() +{ + std::unique_ptr<int> i(new int(3)); + BOOST_HOF_TEST_CHECK(boost::hof::pack_basic(i)(deref()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_basic(std::unique_ptr<int>(new int(3)))(deref()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_forward(std::unique_ptr<int>(new int(3)))(deref()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack(std::unique_ptr<int>(new int(3)))(deref()) == 3); + auto p = boost::hof::pack_basic(std::unique_ptr<int>(new int(3))); + BOOST_HOF_TEST_CHECK(p(deref()) == 3); + + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_basic(), boost::hof::pack_basic(std::unique_ptr<int>(new int(3))))(deref()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack_forward(), boost::hof::pack_forward(std::unique_ptr<int>(new int(3))))(deref()) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::pack_join(boost::hof::pack(), boost::hof::pack(std::unique_ptr<int>(new int(3))))(deref()) == 3); + // BOOST_HOF_TEST_CHECK(p(deref()) == 3); +} + +struct move_rvalue +{ + void operator()(std::string&& s) const + { + std::string ss = std::move(s); + BOOST_HOF_TEST_CHECK(ss == "abcdef"); + s = "00000"; + } +}; + +struct check_rvalue +{ + void operator()(std::string&& s) const + { + BOOST_HOF_TEST_CHECK(s == "abcdef"); + } +}; + +BOOST_HOF_TEST_CASE() +{ + auto p = boost::hof::pack_basic(std::string{"abcdef"}); + p(move_rvalue{}); + p(check_rvalue{}); +} + +BOOST_HOF_TEST_CASE() +{ + auto p = boost::hof::pack(std::string{"abcdef"}); + p(move_rvalue{}); + p(check_rvalue{}); +} + +struct empty1 +{}; + +struct empty2 +{}; + +BOOST_HOF_TEST_CASE() +{ + static_assert(boost::hof::detail::is_default_constructible<empty1, empty2>::value, "Not default constructible"); +} + +BOOST_HOF_TEST_CASE() +{ + static constexpr auto p = boost::hof::pack_basic(empty1()); + BOOST_HOF_TEST_CHECK(p(boost::hof::always(0)) == 0); + BOOST_HOF_STATIC_TEST_CHECK(p(boost::hof::always(0)) == 0); +#ifndef _MSC_VER + static_assert(std::is_empty<decltype(p)>::value, "Pack not empty"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(p)>::value, "Not default constructible"); + +} + +BOOST_HOF_TEST_CASE() +{ + static constexpr auto p = boost::hof::pack_basic(empty1(), empty2()); + BOOST_HOF_TEST_CHECK(p(boost::hof::always(0)) == 0); + BOOST_HOF_STATIC_TEST_CHECK(p(boost::hof::always(0)) == 0); +#ifndef _MSC_VER + static_assert(std::is_empty<decltype(p)>::value, "Pack not empty"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(p)>::value, "Not default constructible"); +} + +BOOST_HOF_TEST_CASE() +{ + static constexpr auto p = boost::hof::pack_basic(boost::hof::pack_basic(), boost::hof::pack_basic()); + BOOST_HOF_TEST_CHECK(p(boost::hof::always(0)) == 0); + BOOST_HOF_STATIC_TEST_CHECK(p(boost::hof::always(0)) == 0); +#ifndef _MSC_VER + static_assert(std::is_empty<decltype(p)>::value, "Pack not empty"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(p)>::value, "Not default constructible"); +} + +BOOST_HOF_TEST_CASE() +{ + static constexpr auto p = boost::hof::pack_basic(empty1(), empty2(), empty1()); + BOOST_HOF_TEST_CHECK(p(boost::hof::always(0)) == 0); + BOOST_HOF_STATIC_TEST_CHECK(p(boost::hof::always(0)) == 0); +#ifndef _MSC_VER + static_assert(std::is_empty<decltype(p)>::value, "Pack not empty"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(p)>::value, "Not default constructible"); +} + +BOOST_HOF_TEST_CASE() +{ + static constexpr auto p = boost::hof::pack_basic(empty1(), boost::hof::pack_basic(empty1(), empty2())); + BOOST_HOF_TEST_CHECK(p(boost::hof::always(0)) == 0); + BOOST_HOF_STATIC_TEST_CHECK(p(boost::hof::always(0)) == 0); +#ifndef _MSC_VER + static_assert(std::is_empty<decltype(p)>::value, "Pack not empty"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(p)>::value, "Not default constructible"); +} + +BOOST_HOF_TEST_CASE() +{ + static constexpr auto p = boost::hof::pack_basic(boost::hof::pack_basic(), boost::hof::pack_basic(boost::hof::pack_basic()), empty1(), boost::hof::pack_basic(empty1(), empty2())); + BOOST_HOF_TEST_CHECK(p(boost::hof::always(0)) == 0); + BOOST_HOF_STATIC_TEST_CHECK(p(boost::hof::always(0)) == 0); +#ifndef _MSC_VER + static_assert(std::is_empty<decltype(p)>::value, "Pack not empty"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(p)>::value, "Not default constructible"); +} + +struct not_default_constructible +{ + int i; + constexpr not_default_constructible(int x) : i(x) + {} +}; + +struct select_i +{ + template<class T> + constexpr int operator()(T&& x) const + { + return x.i; + } + + template<class T, class U> + constexpr int operator()(T&& x, U&& y) const + { + return x.i + y.i; + } + + template<class T, class U, class V> + constexpr int operator()(T&& x, U&& y, V&& z) const + { + return x.i + y.i + z.i; + } +}; + +BOOST_HOF_TEST_CASE() +{ + static_assert(!boost::hof::detail::is_default_constructible<not_default_constructible>::value, "Default constructible"); + auto p = boost::hof::pack_basic(not_default_constructible(3)); + static_assert(!boost::hof::detail::is_default_constructible<decltype(p)>::value, "Pack default constructible"); + auto p1 = boost::hof::pack_forward(p); + static_assert(!boost::hof::detail::is_default_constructible<decltype(p1)>::value, "Packs default constructible"); + auto p2 = boost::hof::pack_forward(p, p); + static_assert(!boost::hof::detail::is_default_constructible<decltype(p2)>::value, "Packs default constructible"); + auto p3 = boost::hof::pack_forward(p, p, p); + static_assert(!boost::hof::detail::is_default_constructible<decltype(p3)>::value, "Packs default constructible"); + BOOST_HOF_TEST_CHECK(p(select_i()) == 3); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_basic(not_default_constructible(3))(select_i()) == 3); +} + +BOOST_HOF_TEST_CASE() +{ + static_assert(!boost::hof::detail::is_default_constructible<not_default_constructible>::value, "Default constructible"); + auto p = boost::hof::pack_basic(not_default_constructible(1), not_default_constructible(2)); + static_assert(!boost::hof::detail::is_default_constructible<decltype(p)>::value, "Pack default constructible"); + auto p1 = boost::hof::pack_forward(p); + static_assert(!boost::hof::detail::is_default_constructible<decltype(p1)>::value, "Packs default constructible"); + auto p2 = boost::hof::pack_forward(p, p); + static_assert(!boost::hof::detail::is_default_constructible<decltype(p2)>::value, "Packs default constructible"); + auto p3 = boost::hof::pack_forward(p, p, p); + static_assert(!boost::hof::detail::is_default_constructible<decltype(p3)>::value, "Packs default constructible"); + BOOST_HOF_TEST_CHECK(p(select_i()) == 3); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_basic(not_default_constructible(1), not_default_constructible(2))(select_i()) == 3); +} + +BOOST_HOF_TEST_CASE() +{ + static_assert(!boost::hof::detail::is_default_constructible<not_default_constructible>::value, "Default constructible"); + auto p = boost::hof::pack_basic(not_default_constructible(1), not_default_constructible(1), not_default_constructible(1)); + static_assert(!boost::hof::detail::is_default_constructible<decltype(p)>::value, "Pack default constructible"); + auto p1 = boost::hof::pack_forward(p); + static_assert(!boost::hof::detail::is_default_constructible<decltype(p1)>::value, "Packs default constructible"); + auto p2 = boost::hof::pack_forward(p, p); + static_assert(!boost::hof::detail::is_default_constructible<decltype(p2)>::value, "Packs default constructible"); + auto p3 = boost::hof::pack_forward(p, p, p); + static_assert(!boost::hof::detail::is_default_constructible<decltype(p3)>::value, "Packs default constructible"); + BOOST_HOF_TEST_CHECK(p(select_i()) == 3); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::pack_basic(not_default_constructible(1), not_default_constructible(1), not_default_constructible(1))(select_i()) == 3); +} + + diff --git a/src/boost/libs/hof/test/partial.cpp b/src/boost/libs/hof/test/partial.cpp new file mode 100644 index 000000000..bb4d5b75a --- /dev/null +++ b/src/boost/libs/hof/test/partial.cpp @@ -0,0 +1,108 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + partial.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 <boost/hof/partial.hpp> +#include <boost/hof/limit.hpp> +#include "test.hpp" + +static constexpr boost::hof::static_<boost::hof::partial_adaptor<binary_class> > binary_partial = {}; + +static constexpr boost::hof::static_<boost::hof::partial_adaptor<unary_class> > unary_partial = {}; + +static constexpr boost::hof::static_<boost::hof::partial_adaptor<mutable_class> > mutable_partial = {}; + +static constexpr boost::hof::static_<boost::hof::partial_adaptor<void_class> > void_partial = {}; + +static constexpr boost::hof::static_<boost::hof::partial_adaptor<mono_class> > mono_partial = {}; + +static constexpr boost::hof::static_<boost::hof::partial_adaptor<move_class> > move_partial = {}; + +constexpr boost::hof::partial_adaptor<binary_class> binary_partial_constexpr = {}; + +constexpr boost::hof::partial_adaptor<unary_class> unary_partial_constexpr = {}; + +constexpr boost::hof::partial_adaptor<void_class> void_partial_constexpr = {}; + +constexpr boost::hof::partial_adaptor<mono_class> mono_partial_constexpr = {}; + +BOOST_HOF_TEST_CASE() +{ + boost::hof::partial_adaptor<void_class>()(1); + + void_partial(1); + void_partial()(1); + BOOST_HOF_TEST_CHECK(3 == binary_partial(1)(2)); + BOOST_HOF_TEST_CHECK(3 == binary_partial(1, 2)); + BOOST_HOF_TEST_CHECK(3 == unary_partial()(3)); + BOOST_HOF_TEST_CHECK(3 == unary_partial(3)); + BOOST_HOF_TEST_CHECK(3 == mono_partial(2)); + BOOST_HOF_TEST_CHECK(3 == mono_partial()(2)); + + int i1 = 1; + BOOST_HOF_TEST_CHECK(3 == binary_partial(2)(i1)); + BOOST_HOF_TEST_CHECK(3 == mutable_partial(std::ref(i1))(2)); + BOOST_HOF_TEST_CHECK(3 == i1); + int i2 = 1; + BOOST_HOF_TEST_CHECK(3 == mutable_partial(i2, 2)); + BOOST_HOF_TEST_CHECK(3 == i2); + +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == (move_class()(1, 2))); + BOOST_HOF_TEST_CHECK(3 == (move_partial(1, 2))); + BOOST_HOF_TEST_CHECK(3 == (move_partial(1)(2))); + BOOST_HOF_TEST_CHECK(3 == (boost::hof::partial(move_class())(1)(2))); + BOOST_HOF_TEST_CHECK(3 == (boost::hof::partial(move_class())(1, 2))); +} + +BOOST_HOF_TEST_CASE() +{ + void_partial_constexpr(1); + void_partial_constexpr()(1); + BOOST_HOF_STATIC_TEST_CHECK(3 == binary_partial_constexpr(1)(2)); + BOOST_HOF_STATIC_TEST_CHECK(3 == binary_partial_constexpr(1, 2)); + BOOST_HOF_STATIC_TEST_CHECK(3 == unary_partial_constexpr()(3)); + BOOST_HOF_STATIC_TEST_CHECK(3 == unary_partial_constexpr(3)); + BOOST_HOF_STATIC_TEST_CHECK(3 == mono_partial_constexpr(2)); + BOOST_HOF_STATIC_TEST_CHECK(3 == mono_partial_constexpr()(2)); +} +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::partial(binary_class{})(1)(2)), "noexcept partial"); +} +#endif +BOOST_HOF_TEST_CASE() +{ + auto f = boost::hof::partial(boost::hof::limit_c<2>(binary_class())); + static_assert(boost::hof::is_invocable<decltype(f), int>::value, "Passing the limit is not callable"); + static_assert(boost::hof::is_invocable<decltype(f), int, int>::value, "Passing the limit is not callable"); + static_assert(!boost::hof::is_invocable<decltype(f), int, int, int>::value, "Passing the limit is not callable"); + static_assert(!boost::hof::is_invocable<decltype(f), int, int, int, int>::value, "Passing the limit is not callable"); + + auto g = f(0); + static_assert(boost::hof::is_invocable<decltype(g), int>::value, "Passing the limit is not callable"); + static_assert(!boost::hof::is_invocable<decltype(g), int, int>::value, "Passing the limit is not callable"); + static_assert(!boost::hof::is_invocable<decltype(g), int, int, int>::value, "Passing the limit is not callable"); + static_assert(!boost::hof::is_invocable<decltype(g), int, int, int, int>::value, "Passing the limit is not callable"); +} + +BOOST_HOF_TEST_CASE() +{ + auto f = boost::hof::partial(binary_class()); + static_assert(boost::hof::is_invocable<decltype(f), int>::value, "Passing the limit is not callable"); + static_assert(boost::hof::is_invocable<decltype(f), int, int>::value, "Passing the limit is not callable"); + static_assert(boost::hof::is_invocable<decltype(f), int, int, int>::value, "Passing the limit is not callable"); + static_assert(boost::hof::is_invocable<decltype(f), int, int, int, int>::value, "Passing the limit is not callable"); + + auto g = f(0); + static_assert(boost::hof::is_invocable<decltype(g), int>::value, "Passing the limit is not callable"); + static_assert(boost::hof::is_invocable<decltype(g), int, int>::value, "Passing the limit is not callable"); + static_assert(boost::hof::is_invocable<decltype(g), int, int, int>::value, "Passing the limit is not callable"); + static_assert(boost::hof::is_invocable<decltype(g), int, int, int, int>::value, "Passing the limit is not callable"); +} diff --git a/src/boost/libs/hof/test/pipable.cpp b/src/boost/libs/hof/test/pipable.cpp new file mode 100644 index 000000000..45bf7fdfa --- /dev/null +++ b/src/boost/libs/hof/test/pipable.cpp @@ -0,0 +1,90 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + pipable.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 <boost/hof/pipable.hpp> +#include <boost/hof/static.hpp> +#include <boost/hof/limit.hpp> +#include "test.hpp" + +static constexpr boost::hof::static_<boost::hof::pipable_adaptor<binary_class> > binary_pipable = {}; + +static constexpr boost::hof::static_<boost::hof::pipable_adaptor<unary_class> > unary_pipable = {}; + +static constexpr boost::hof::static_<boost::hof::pipable_adaptor<mutable_class> > mutable_pipable = {}; + +static constexpr boost::hof::static_<boost::hof::pipable_adaptor<void_class> > void_pipable = {}; + +static constexpr boost::hof::static_<boost::hof::pipable_adaptor<mono_class> > mono_pipable = {}; + +static constexpr boost::hof::static_<boost::hof::pipable_adaptor<move_class> > move_pipable = {}; + +constexpr boost::hof::pipable_adaptor<void_class> void_pipable_constexpr = {}; + +constexpr boost::hof::pipable_adaptor<binary_class> binary_pipable_constexpr = {}; + +constexpr boost::hof::pipable_adaptor<unary_class> unary_pipable_constexpr = {}; + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(1 | binary_pipable(2)), "noexcept pipable"); + static_assert(noexcept(binary_pipable(1, 2)), "noexcept pipable"); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + void_pipable(1); + 1 | void_pipable; + BOOST_HOF_TEST_CHECK(3 == (1 | binary_pipable(2))); + BOOST_HOF_TEST_CHECK(3 == (binary_pipable(1, 2))); + BOOST_HOF_TEST_CHECK(3 == (3 | unary_pipable)); + BOOST_HOF_TEST_CHECK(3 == (3 | unary_pipable())); + BOOST_HOF_TEST_CHECK(3 == (unary_pipable(3))); + int i1 = 1; + BOOST_HOF_TEST_CHECK(3 == (2 | binary_pipable(i1))); + BOOST_HOF_TEST_CHECK(3 == (i1 | mutable_pipable(2))); + BOOST_HOF_TEST_CHECK(3 == (i1)); + int i2 = 1; + BOOST_HOF_TEST_CHECK(3 == (mutable_pipable(i2, 2))); + BOOST_HOF_TEST_CHECK(3 == (i2)); + BOOST_HOF_TEST_CHECK(3 == (mono_pipable(2))); + BOOST_HOF_TEST_CHECK(3 == (2| mono_pipable)); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == (move_class()(1, 2))); + BOOST_HOF_TEST_CHECK(3 == (move_pipable(1, 2))); + BOOST_HOF_TEST_CHECK(3 == (1 | move_pipable(2))); + BOOST_HOF_TEST_CHECK(3 == (1 | boost::hof::pipable(move_class())(2))); + BOOST_HOF_TEST_CHECK(3 == (boost::hof::pipable(move_class())(1, 2))); +} + +BOOST_HOF_TEST_CASE() +{ + void_pipable_constexpr(1); + 1 | void_pipable_constexpr; + BOOST_HOF_STATIC_TEST_CHECK(3 == (1 | binary_pipable_constexpr(2))); + BOOST_HOF_STATIC_TEST_CHECK(3 == (binary_pipable_constexpr(1, 2))); + BOOST_HOF_STATIC_TEST_CHECK(3 == (3 | unary_pipable_constexpr)); + BOOST_HOF_STATIC_TEST_CHECK(3 == (3 | unary_pipable_constexpr())); + BOOST_HOF_STATIC_TEST_CHECK(3 == (unary_pipable_constexpr(3))); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == boost::hof::limit_c<2>(binary_pipable_constexpr)(1, 2)); + BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::limit_c<2>(binary_pipable_constexpr)(1, 2)); +} + +BOOST_HOF_TEST_CASE() +{ + auto f = boost::hof::pipable(boost::hof::limit_c<2>(binary_class())); + static_assert(boost::hof::is_invocable<decltype(f), int, int>::value, "Passing the limit is not callable"); + static_assert(!boost::hof::is_invocable<decltype(f), int, int, int>::value, "Passing the limit is not callable"); + static_assert(!boost::hof::is_invocable<decltype(f), int, int, int, int>::value, "Passing the limit is not callable"); +} diff --git a/src/boost/libs/hof/test/placeholders.cpp b/src/boost/libs/hof/test/placeholders.cpp new file mode 100644 index 000000000..352230a8f --- /dev/null +++ b/src/boost/libs/hof/test/placeholders.cpp @@ -0,0 +1,813 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + placeholders.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 <boost/hof/placeholders.hpp> +#include "test.hpp" +#include <sstream> + +// TODO: Test assign operators + +#if BOOST_HOF_HAS_STATIC_TEST_CHECK +#define BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR constexpr +#else +#define BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR +#endif + +struct square +{ + template<class T> + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto operator()(T x) const BOOST_HOF_RETURNS(x*x); +}; + +#define CHECK_DEFAULT_CONSTRUCTION_OP(op, name) \ + static_assert(boost::hof::detail::is_default_constructible<boost::hof::operators::name>::value, "Operator not default constructible"); + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +#define PLACEHOLDER_CHECK(...) \ + BOOST_HOF_STATIC_TEST_CHECK(__VA_ARGS__); \ + BOOST_HOF_TEST_CHECK(__VA_ARGS__); \ + static_assert(noexcept(__VA_ARGS__), "noexcept placeholders") +#else +#define PLACEHOLDER_CHECK(...) \ + BOOST_HOF_STATIC_TEST_CHECK(__VA_ARGS__); \ + BOOST_HOF_TEST_CHECK(__VA_ARGS__) +#endif + +BOOST_HOF_TEST_CASE() +{ + static_assert(boost::hof::detail::is_default_constructible<boost::hof::placeholder<1>>::value, "Placeholder not default constructible"); + static_assert(boost::hof::detail::is_default_constructible<boost::hof::placeholder<2>>::value, "Placeholder not default constructible"); + static_assert(boost::hof::detail::is_default_constructible<boost::hof::placeholder<3>>::value, "Placeholder not default constructible"); + + BOOST_HOF_FOREACH_BINARY_OP(CHECK_DEFAULT_CONSTRUCTION_OP) + BOOST_HOF_FOREACH_ASSIGN_OP(CHECK_DEFAULT_CONSTRUCTION_OP) + BOOST_HOF_FOREACH_UNARY_OP(CHECK_DEFAULT_CONSTRUCTION_OP) +} + +BOOST_HOF_TEST_CASE() +{ + auto simple_print = boost::hof::reveal(std::ref(std::cout) << boost::hof::_); + simple_print("Hello"); +} + +BOOST_HOF_TEST_CASE() +{ + std::stringstream ss; + auto simple_print = boost::hof::reveal(std::ref(ss) << boost::hof::_); + simple_print("Hello"); + BOOST_HOF_TEST_CHECK(ss.str() == "Hello"); +} + +BOOST_HOF_TEST_CASE() +{ + const auto x_square_add = 2 + (4*4); + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_square_add = boost::hof::_1 + boost::hof::lazy(square())(boost::hof::_2); +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_square_add)>::value, "Not copyable"); +#endif + PLACEHOLDER_CHECK(f_square_add(2, 4) == x_square_add); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_invoke_2 = boost::hof::_1(3); +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_invoke_2)>::value, "Not copyable"); +#endif + PLACEHOLDER_CHECK(f_invoke_2(square()) == 9); +} + +BOOST_HOF_TEST_CASE() +{ + const auto x_add = 2 + 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_add = boost::hof::_1 + boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_add)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_add)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_add(2, 1) == x_add); + + const auto x_subtract = 2 - 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_subtract = boost::hof::_1 - boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_subtract)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_subtract)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_subtract(2, 1) == x_subtract); + + const auto x_multiply = 2 * 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_multiply = boost::hof::_1 * boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_multiply)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_multiply)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_multiply(2, 1) == x_multiply); + + const auto x_divide = 2 / 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_divide = boost::hof::_1 / boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_divide)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_divide)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_divide(2, 1) == x_divide); + + const auto x_remainder = 2 % 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_remainder = boost::hof::_1 % boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_remainder)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_remainder)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_remainder(2, 1) == x_remainder); + + const auto x_shift_right = 2 >> 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_right = boost::hof::_1 >> boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_shift_right)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_shift_right)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_shift_right(2, 1) == x_shift_right); + + const auto x_shift_left = 2 << 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_left = boost::hof::_1 << boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_shift_left)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_shift_left)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_shift_left(2, 1) == x_shift_left); + + const auto x_greater_than = 2 > 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than = boost::hof::_1 > boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_greater_than)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_greater_than)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_greater_than(2, 1) == x_greater_than); + + const auto x_less_than = 2 < 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than = boost::hof::_1 < boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_less_than)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_less_than)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_less_than(2, 1) == x_less_than); + + const auto x_less_than_equal = 2 <= 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than_equal = boost::hof::_1 <= boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_less_than_equal)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_less_than_equal)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_less_than_equal(2, 1) == x_less_than_equal); + + const auto x_greater_than_equal = 2 >= 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than_equal = boost::hof::_1 >= boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_greater_than_equal)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_greater_than_equal)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_greater_than_equal(2, 1) == x_greater_than_equal); + + const auto x_equal = 2 == 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_equal = boost::hof::_1 == boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_equal)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_equal)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_equal(2, 1) == x_equal); + + const auto x_not_equal = 2 != 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_not_equal = boost::hof::_1 != boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_not_equal)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_not_equal)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_not_equal(2, 1) == x_not_equal); + + const auto x_bit_and = 2 & 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_and = boost::hof::_1 & boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_bit_and)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_bit_and)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_bit_and(2, 1) == x_bit_and); + + const auto x_xor_ = 2 ^ 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_xor_ = boost::hof::_1 ^ boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_xor_)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_xor_)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_xor_(2, 1) == x_xor_); + + const auto x_bit_or = 2 | 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_or = boost::hof::_1 | boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_bit_or)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_bit_or)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_bit_or(2, 1) == x_bit_or); + + const auto x_and_ = true && false; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_and_ = boost::hof::_1 && boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_and_)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_and_)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_and_(true, false) == x_and_); + + const auto x_or_ = true; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_or_ = boost::hof::_1 || boost::hof::_2; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_or_)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_or_)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_or_(true, false) == x_or_); +} + +BOOST_HOF_TEST_CASE() +{ + + const auto x_not_ = !false; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_not_ = !boost::hof::_1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_not_)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_not_)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_not_(false) == x_not_); + + const auto x_not_0 = !0; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_not_0 = !boost::hof::_1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_not_0)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_not_0)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_not_0(0) == x_not_0); + + const auto x_compl_ = ~2; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_compl_ = ~boost::hof::_1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_compl_)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_compl_)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_compl_(2) == x_compl_); + + const auto x_unary_plus = +2; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_unary_plus = +boost::hof::_1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_unary_plus)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_unary_plus)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_unary_plus(2) == x_unary_plus); + + const auto x_unary_subtract = -2; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_unary_subtract = -boost::hof::_1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_unary_subtract)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_unary_subtract)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_unary_subtract(2) == x_unary_subtract); + + const auto x_dereference = 2; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_dereference = *boost::hof::_1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_dereference)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_dereference)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_dereference(&x_dereference) == x_dereference); + + // TODO: Test BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR increment and decrement +#ifndef _MSC_VER + auto x_increment = 2; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_increment = ++boost::hof::_1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_increment)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_increment)>::value, "Not default constructible"); + f_increment(x_increment); + BOOST_HOF_TEST_CHECK(x_increment == 3); + + auto x_decrement = 2; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_decrement = --boost::hof::_1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_decrement)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_decrement)>::value, "Not default constructible"); + f_decrement(x_decrement); + BOOST_HOF_TEST_CHECK(x_decrement == 1); +#endif + + // TODO: Test post increment and decrement +} + + +BOOST_HOF_TEST_CASE() +{ + const auto x_add = 2 + 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_add = boost::hof::_ + boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_add)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_add)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_add(2, 1) == x_add); + + const auto x_subtract = 2 - 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_subtract = boost::hof::_ - boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_subtract)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_subtract)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_subtract(2, 1) == x_subtract); + + const auto x_multiply = 2 * 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_multiply = boost::hof::_ * boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_multiply)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_multiply)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_multiply(2, 1) == x_multiply); + + const auto x_divide = 2 / 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_divide = boost::hof::_ / boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_divide)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_divide)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_divide(2, 1) == x_divide); + + const auto x_remainder = 2 % 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_remainder = boost::hof::_ % boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_remainder)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_remainder)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_remainder(2, 1) == x_remainder); + + const auto x_shift_right = 2 >> 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_right = boost::hof::_ >> boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_shift_right)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_shift_right)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_shift_right(2, 1) == x_shift_right); + + const auto x_shift_left = 2 << 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_left = boost::hof::_ << boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_shift_left)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_shift_left)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_shift_left(2, 1) == x_shift_left); + + const auto x_greater_than = 2 > 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than = boost::hof::_ > boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_greater_than)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_greater_than)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_greater_than(2, 1) == x_greater_than); + + const auto x_less_than = 2 < 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than = boost::hof::_ < boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_less_than)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_less_than)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_less_than(2, 1) == x_less_than); + + const auto x_less_than_equal = 2 <= 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than_equal = boost::hof::_ <= boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_less_than_equal)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_less_than_equal)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_less_than_equal(2, 1) == x_less_than_equal); + + const auto x_greater_than_equal = 2 >= 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than_equal = boost::hof::_ >= boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_greater_than_equal)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_greater_than_equal)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_greater_than_equal(2, 1) == x_greater_than_equal); + + const auto x_equal = 2 == 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_equal = boost::hof::_ == boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_equal)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_equal)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_equal(2, 1) == x_equal); + + const auto x_not_equal = 2 != 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_not_equal = boost::hof::_ != boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_not_equal)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_not_equal)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_not_equal(2, 1) == x_not_equal); + + const auto x_bit_and = 2 & 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_and = boost::hof::_ & boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_bit_and)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_bit_and)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_bit_and(2, 1) == x_bit_and); + + const auto x_xor_ = 2 ^ 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_xor_ = boost::hof::_ ^ boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_xor_)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_xor_)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_xor_(2, 1) == x_xor_); + + const auto x_bit_or = 2 | 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_or = boost::hof::_ | boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_bit_or)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_bit_or)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_bit_or(2, 1) == x_bit_or); + + const auto x_and_ = true && false; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_and_ = boost::hof::_ && boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_and_)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_and_)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_and_(true, false) == x_and_); + + const auto x_or_ = true; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_or_ = boost::hof::_ || boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_or_)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_or_)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_or_(true, false) == x_or_); +} + +BOOST_HOF_TEST_CASE() +{ + const auto x_add = 2 + 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_add = 2 + boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_add)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_add)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_add(1) == x_add); + + const auto x_subtract = 2 - 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_subtract = 2 - boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_subtract)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_subtract)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_subtract(1) == x_subtract); + + const auto x_multiply = 2 * 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_multiply = 2 * boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_multiply)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_multiply)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_multiply(1) == x_multiply); + + const auto x_divide = 2 / 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_divide = 2 / boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_divide)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_divide)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_divide(1) == x_divide); + + const auto x_remainder = 2 % 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_remainder = 2 % boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_remainder)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_remainder)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_remainder(1) == x_remainder); + + const auto x_shift_right = 2 >> 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_right = 2 >> boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_shift_right)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_shift_right)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_shift_right(1) == x_shift_right); + + const auto x_shift_left = 2 << 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_left = 2 << boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_shift_left)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_shift_left)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_shift_left(1) == x_shift_left); + + const auto x_greater_than = 2 > 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than = 2 > boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_greater_than)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_greater_than)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_greater_than(1) == x_greater_than); + + const auto x_less_than = 2 < 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than = 2 < boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_less_than)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_less_than)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_less_than(1) == x_less_than); + + const auto x_less_than_equal = 2 <= 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than_equal = 2 <= boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_less_than_equal)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_less_than_equal)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_less_than_equal(1) == x_less_than_equal); + + const auto x_greater_than_equal = 2 >= 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than_equal = 2 >= boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_greater_than_equal)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_greater_than_equal)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_greater_than_equal(1) == x_greater_than_equal); + + const auto x_equal = 2 == 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_equal = 2 == boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_equal)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_equal)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_equal(1) == x_equal); + + const auto x_not_equal = 2 != 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_not_equal = 2 != boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_not_equal)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_not_equal)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_not_equal(1) == x_not_equal); + + const auto x_bit_and = 2 & 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_and = 2 & boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_bit_and)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_bit_and)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_bit_and(1) == x_bit_and); + + const auto x_xor_ = 2 ^ 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_xor_ = 2 ^ boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_xor_)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_xor_)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_xor_(1) == x_xor_); + + const auto x_bit_or = 2 | 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_or = 2 | boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_bit_or)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_bit_or)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_bit_or(1) == x_bit_or); + + const auto x_and_ = true && false; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_and_ = true && boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_and_)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_and_)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_and_(false) == x_and_); + + const auto x_or_ = true; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_or_ = true || boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_or_)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_or_)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_or_(false) == x_or_); +} + +BOOST_HOF_TEST_CASE() +{ + const auto x_add = 2 + 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_add = boost::hof::_ + 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_add)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_add)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_add(2) == x_add); + + const auto x_subtract = 2 - 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_subtract = boost::hof::_ - 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_subtract)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_subtract)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_subtract(2) == x_subtract); + + const auto x_multiply = 2 * 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_multiply = boost::hof::_ * 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_multiply)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_multiply)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_multiply(2) == x_multiply); + + const auto x_divide = 2 / 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_divide = boost::hof::_ / 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_divide)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_divide)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_divide(2) == x_divide); + + const auto x_remainder = 2 % 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_remainder = boost::hof::_ % 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_remainder)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_remainder)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_remainder(2) == x_remainder); + + const auto x_shift_right = 2 >> 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_right = boost::hof::_ >> 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_shift_right)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_shift_right)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_shift_right(2) == x_shift_right); + + const auto x_shift_left = 2 << 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_shift_left = boost::hof::_ << 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_shift_left)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_shift_left)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_shift_left(2) == x_shift_left); + + const auto x_greater_than = 2 > 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than = boost::hof::_ > 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_greater_than)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_greater_than)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_greater_than(2) == x_greater_than); + + const auto x_less_than = 2 < 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than = boost::hof::_ < 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_less_than)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_less_than)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_less_than(2) == x_less_than); + + const auto x_less_than_equal = 2 <= 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_less_than_equal = boost::hof::_ <= 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_less_than_equal)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_less_than_equal)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_less_than_equal(2) == x_less_than_equal); + + const auto x_greater_than_equal = 2 >= 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_greater_than_equal = boost::hof::_ >= 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_greater_than_equal)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_greater_than_equal)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_greater_than_equal(2) == x_greater_than_equal); + + const auto x_equal = 2 == 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_equal = boost::hof::_ == 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_equal)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_equal)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_equal(2) == x_equal); + + const auto x_not_equal = 2 != 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_not_equal = boost::hof::_ != 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_not_equal)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_not_equal)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_not_equal(2) == x_not_equal); + + const auto x_bit_and = 2 & 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_and = boost::hof::_ & 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_bit_and)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_bit_and)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_bit_and(2) == x_bit_and); + + const auto x_xor_ = 2 ^ 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_xor_ = boost::hof::_ ^ 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_xor_)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_xor_)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_xor_(2) == x_xor_); + + const auto x_bit_or = 2 | 1; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_bit_or = boost::hof::_ | 1; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_bit_or)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_bit_or)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_bit_or(2) == x_bit_or); + + const auto x_and_ = true && false; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_and_ = boost::hof::_ && false; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_and_)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_and_)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_and_(true) == x_and_); + + const auto x_or_ = true; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_or_ = boost::hof::_ || false; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_or_)>::value, "Not copyable"); +#endif + static_assert(!boost::hof::detail::is_default_constructible<decltype(f_or_)>::value, "default constructible"); + PLACEHOLDER_CHECK(f_or_(true) == x_or_); +} + +BOOST_HOF_TEST_CASE() +{ + + const auto x_not_ = !false; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_not_ = !boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_not_)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_not_)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_not_(false) == x_not_); + + const auto x_compl_ = ~2; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_compl_ = ~boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_compl_)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_compl_)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_compl_(2) == x_compl_); + + const auto x_unary_plus = +2; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_unary_plus = +boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_unary_plus)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_unary_plus)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_unary_plus(2) == x_unary_plus); + + const auto x_unary_subtract = -2; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_unary_subtract = -boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_unary_subtract)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_unary_subtract)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_unary_subtract(2) == x_unary_subtract); + + const auto x_dereference = 2; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_dereference = *boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_dereference)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_dereference)>::value, "Not default constructible"); + PLACEHOLDER_CHECK(f_dereference(&x_dereference) == x_dereference); + + // TODO: Test constexpr increment and decrement +#ifndef _MSC_VER + auto x_increment = 2; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_increment = ++boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_increment)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_increment)>::value, "Not default constructible"); + f_increment(x_increment); + BOOST_HOF_TEST_CHECK(x_increment == 3); + + auto x_decrement = 2; + BOOST_HOF_PLACEHOLDER_TEST_CONSTEXPR auto f_decrement = --boost::hof::_; +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ > 6 + static_assert(std::is_copy_constructible<decltype(f_decrement)>::value, "Not copyable"); +#endif + static_assert(boost::hof::detail::is_default_constructible<decltype(f_decrement)>::value, "Not default constructible"); + f_decrement(x_decrement); + BOOST_HOF_TEST_CHECK(x_decrement == 1); +#endif + + // TODO: Test post increment and decrement +} + diff --git a/src/boost/libs/hof/test/proj.cpp b/src/boost/libs/hof/test/proj.cpp new file mode 100644 index 000000000..c544fc4bd --- /dev/null +++ b/src/boost/libs/hof/test/proj.cpp @@ -0,0 +1,164 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + proj.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 <boost/hof/proj.hpp> +#include <boost/hof/placeholders.hpp> +#include <boost/hof/mutable.hpp> +#include "test.hpp" + +#include <memory> + +struct foo +{ + constexpr foo(int xp) : x(xp) + {} + int x; +}; + +struct select_x +{ + template<class T> + constexpr auto operator()(T&& x) const BOOST_HOF_RETURNS(x.x); +}; + +BOOST_HOF_TEST_CASE() +{ +#ifndef _MSC_VER + constexpr +#endif + auto add = boost::hof::_ + boost::hof::_; + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::proj(select_x(), add)(foo(1), foo(2)) == 3); + // Using mutable_ as a workaround on libc++, since mem_fn does not meet the + // requirements of a FunctionObject + BOOST_HOF_TEST_CHECK(boost::hof::proj(boost::hof::mutable_(std::mem_fn(&foo::x)), add)(foo(1), foo(2)) == 3); + static_assert(boost::hof::detail::is_default_constructible<decltype(boost::hof::proj(select_x(), add))>::value, "Not default constructible"); +} + +BOOST_HOF_TEST_CASE() +{ +#ifndef _MSC_VER + constexpr +#endif + auto add = boost::hof::_ + boost::hof::_; + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::proj(select_x(), add)(foo(1), foo(2)) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::proj(&foo::x, add)(foo(1), foo(2)) == 3); + static_assert(boost::hof::detail::is_default_constructible<decltype(boost::hof::proj(select_x(), add))>::value, "Not default constructible"); +} + +BOOST_HOF_TEST_CASE() +{ + auto indirect_add = boost::hof::proj(*boost::hof::_, boost::hof::_ + boost::hof::_); + BOOST_HOF_TEST_CHECK(indirect_add(std::unique_ptr<int>(new int(1)), std::unique_ptr<int>(new int(2))) == 3); + static_assert(boost::hof::detail::is_default_constructible<decltype(indirect_add)>::value, "Not default constructible"); +} + +struct select_x_1 +{ + std::unique_ptr<int> i; + select_x_1() : i(new int(2)) + {} + template<class T> + auto operator()(T&& x) const BOOST_HOF_RETURNS(x.x * (*i)); +}; + +struct sum_1 +{ + std::unique_ptr<int> i; + sum_1() : i(new int(1)) + {} + template<class T, class U> + auto operator()(T&& x, U&& y) const BOOST_HOF_RETURNS(x + y + *i); +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::proj(select_x_1(), sum_1())(foo(1), foo(2)) == 7); +} + +BOOST_HOF_TEST_CASE() +{ + std::string s; + auto f = [&](const std::string& x) + { + s += x; + }; + boost::hof::proj(f)("hello", "-", "world"); + BOOST_HOF_TEST_CHECK(s == "hello-world"); + boost::hof::proj(f)(); + BOOST_HOF_TEST_CHECK(s == "hello-world"); +} + +BOOST_HOF_TEST_CASE() +{ + std::string s; + auto f = [&](const std::string& x) + { + s += x; + return s; + }; + auto last = [](const std::string& x, const std::string& y, const std::string& z) + { + BOOST_HOF_TEST_CHECK(x == "hello"); + BOOST_HOF_TEST_CHECK(y == "hello-"); + BOOST_HOF_TEST_CHECK(z == "hello-world"); + return z; + }; + BOOST_HOF_TEST_CHECK(boost::hof::proj(f, last)("hello", "-", "world") == "hello-world"); +} + +template<bool B> +struct bool_ +{ + static const bool value = B; +}; + +struct constexpr_check +{ + template<class T> + constexpr int operator()(T) const + { + static_assert(T::value, "Failed"); + return 0; + } +}; + +struct constexpr_check_each +{ + template<class T> + constexpr bool operator()(T x) const + { + return boost::hof::proj(constexpr_check())(x, x), true; + } +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(constexpr_check_each()(bool_<true>())); +} + +BOOST_HOF_TEST_CASE() +{ + boost::hof::proj(boost::hof::identity, boost::hof::identity)(0); +} + +struct bar {}; + +BOOST_HOF_TEST_CASE() +{ + auto f = boost::hof::proj(bar{}); + static_assert(!boost::hof::is_invocable<decltype(f), int>::value, "Not sfinae friendly"); + static_assert(!boost::hof::is_invocable<decltype(f), int, int>::value, "Not sfinae friendly"); + static_assert(!boost::hof::is_invocable<decltype(f), int, int, int>::value, "Not sfinae friendly"); +} + +BOOST_HOF_TEST_CASE() +{ + auto f = boost::hof::proj(bar{}, bar{}); + static_assert(!boost::hof::is_invocable<decltype(f), int>::value, "Not sfinae friendly"); + static_assert(!boost::hof::is_invocable<decltype(f), int, int>::value, "Not sfinae friendly"); + static_assert(!boost::hof::is_invocable<decltype(f), int, int, int>::value, "Not sfinae friendly"); + static_assert(!boost::hof::is_invocable<decltype(f)>::value, "Not sfinae friendly"); +} diff --git a/src/boost/libs/hof/test/protect.cpp b/src/boost/libs/hof/test/protect.cpp new file mode 100644 index 000000000..3059572d1 --- /dev/null +++ b/src/boost/libs/hof/test/protect.cpp @@ -0,0 +1,302 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + protect.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 <boost/hof/protect.hpp> +#include <boost/hof/lazy.hpp> +#include <boost/hof/placeholders.hpp> +#include <memory> +#include "test.hpp" + +#include <boost/hof/function.hpp> + +int f(int x) +{ + return x; +} + +int& g(int& x) +{ + return x; +} + +template<class T> +const T& constify(const T& arg) +{ + return arg; +} + +BOOST_HOF_TEST_CASE() +{ + int i[9] = {0,1,2,3,4,5,6,7,8}; + + // non-const + + // test nullary + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(1))() == 1); + + // test lvalues + + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0]) == &i[0]); + + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1]) == &i[0]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1]) == &i[1]); + + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1], i[2]) == &i[0]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1], i[2]) == &i[1]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))(i[0], i[1], i[2]) == &i[2]); + + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1], i[2], i[3]) == &i[0]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1], i[2], i[3]) == &i[1]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))(i[0], i[1], i[2], i[3]) == &i[2]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4))(i[0], i[1], i[2], i[3]) == &i[3]); + + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1], i[2], i[3], i[4]) == &i[0]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1], i[2], i[3], i[4]) == &i[1]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))(i[0], i[1], i[2], i[3], i[4]) == &i[2]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4))(i[0], i[1], i[2], i[3], i[4]) == &i[3]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5))(i[0], i[1], i[2], i[3], i[4]) == &i[4]); + + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[0]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[1]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[2]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[3]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[4]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[5]); + + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[0]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[1]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[2]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[3]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[4]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[5]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_7))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[6]); + + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[0]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[1]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[2]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[3]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[4]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[5]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_7))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[6]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_8))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[7]); + + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[0]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[1]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[2]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[3]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[4]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[5]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_7))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[6]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_8))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[7]); + BOOST_HOF_TEST_CHECK(&boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_9))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[8]); + + // test rvalues + + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0) == 0); + + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1) == 0); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1) == 1); + + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1, 2) == 0); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1, 2) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3))(0, 1, 2) == 2); + + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1, 2, 3) == 0); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1, 2, 3) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3))(0, 1, 2, 3) == 2); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4))(0, 1, 2, 3) == 3); + + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1, 2, 3, 4) == 0); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1, 2, 3, 4) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3))(0, 1, 2, 3, 4) == 2); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4))(0, 1, 2, 3, 4) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5))(0, 1, 2, 3, 4) == 4); + + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1, 2, 3, 4, 5) == 0); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1, 2, 3, 4, 5) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3))(0, 1, 2, 3, 4, 5) == 2); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4))(0, 1, 2, 3, 4, 5) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5))(0, 1, 2, 3, 4, 5) == 4); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6))(0, 1, 2, 3, 4, 5) == 5); + + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1, 2, 3, 4, 5, 6) == 0); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1, 2, 3, 4, 5, 6) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3))(0, 1, 2, 3, 4, 5, 6) == 2); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4))(0, 1, 2, 3, 4, 5, 6) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5))(0, 1, 2, 3, 4, 5, 6) == 4); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6))(0, 1, 2, 3, 4, 5, 6) == 5); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_7))(0, 1, 2, 3, 4, 5, 6) == 6); + + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1, 2, 3, 4, 5, 6, 7) == 0); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1, 2, 3, 4, 5, 6, 7) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3))(0, 1, 2, 3, 4, 5, 6, 7) == 2); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4))(0, 1, 2, 3, 4, 5, 6, 7) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5))(0, 1, 2, 3, 4, 5, 6, 7) == 4); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6))(0, 1, 2, 3, 4, 5, 6, 7) == 5); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_7))(0, 1, 2, 3, 4, 5, 6, 7) == 6); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_8))(0, 1, 2, 3, 4, 5, 6, 7) == 7); + + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 0); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 2); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 3); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 4); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 5); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_7))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 6); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_8))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 7); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_9))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 8); + + // test mixed perfect forwarding + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(i[0], 1) == 0); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(i[0], 1) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1))(0, i[1]) == 0); + BOOST_HOF_TEST_CHECK(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2))(0, i[1]) == 1); + + // const + + // test nullary + BOOST_HOF_TEST_CHECK(constify(constify(boost::hof::protect(boost::hof::lazy(f)(1))))() == 1); + + // test lvalues + BOOST_HOF_TEST_CHECK(&constify(constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))))(i[0]) == &i[0]); + + BOOST_HOF_TEST_CHECK(&constify(constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))))(i[0], i[1]) == &i[0]); + BOOST_HOF_TEST_CHECK(&constify(constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))))(i[0], i[1]) == &i[1]); + + BOOST_HOF_TEST_CHECK(&constify(constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1))))(i[0], i[1], i[2]) == &i[0]); + BOOST_HOF_TEST_CHECK(&constify(constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2))))(i[0], i[1], i[2]) == &i[1]); + BOOST_HOF_TEST_CHECK(&constify(constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3))))(i[0], i[1], i[2]) == &i[2]); + + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1)))(i[0], i[1], i[2], i[3]) == &i[0]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2)))(i[0], i[1], i[2], i[3]) == &i[1]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3)))(i[0], i[1], i[2], i[3]) == &i[2]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4)))(i[0], i[1], i[2], i[3]) == &i[3]); + + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1)))(i[0], i[1], i[2], i[3], i[4]) == &i[0]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2)))(i[0], i[1], i[2], i[3], i[4]) == &i[1]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3)))(i[0], i[1], i[2], i[3], i[4]) == &i[2]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4)))(i[0], i[1], i[2], i[3], i[4]) == &i[3]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5)))(i[0], i[1], i[2], i[3], i[4]) == &i[4]); + + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[0]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[1]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[2]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[3]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[4]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[5]); + + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[0]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[1]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[2]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[3]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[4]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[5]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_7)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[6]); + + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[0]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[1]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[2]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[3]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[4]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[5]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_7)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[6]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_8)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[7]); + + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_1)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[0]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_2)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[1]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_3)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[2]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_4)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[3]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_5)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[4]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_6)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[5]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_7)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[6]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_8)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[7]); + BOOST_HOF_TEST_CHECK(&constify(boost::hof::protect(boost::hof::lazy(g)(std::placeholders::_9)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[8]); + + // test rvalues + + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0) == 0); + + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1) == 0); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1) == 1); + + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1, 2) == 0); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1, 2) == 1); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3)))(0, 1, 2) == 2); + + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1, 2, 3) == 0); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1, 2, 3) == 1); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3)))(0, 1, 2, 3) == 2); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4)))(0, 1, 2, 3) == 3); + + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1, 2, 3, 4) == 0); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1, 2, 3, 4) == 1); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3)))(0, 1, 2, 3, 4) == 2); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4)))(0, 1, 2, 3, 4) == 3); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5)))(0, 1, 2, 3, 4) == 4); + + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1, 2, 3, 4, 5) == 0); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1, 2, 3, 4, 5) == 1); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3)))(0, 1, 2, 3, 4, 5) == 2); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4)))(0, 1, 2, 3, 4, 5) == 3); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5)))(0, 1, 2, 3, 4, 5) == 4); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6)))(0, 1, 2, 3, 4, 5) == 5); + + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1, 2, 3, 4, 5, 6) == 0); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1, 2, 3, 4, 5, 6) == 1); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3)))(0, 1, 2, 3, 4, 5, 6) == 2); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4)))(0, 1, 2, 3, 4, 5, 6) == 3); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5)))(0, 1, 2, 3, 4, 5, 6) == 4); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6)))(0, 1, 2, 3, 4, 5, 6) == 5); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_7)))(0, 1, 2, 3, 4, 5, 6) == 6); + + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1, 2, 3, 4, 5, 6, 7) == 0); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1, 2, 3, 4, 5, 6, 7) == 1); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3)))(0, 1, 2, 3, 4, 5, 6, 7) == 2); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4)))(0, 1, 2, 3, 4, 5, 6, 7) == 3); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5)))(0, 1, 2, 3, 4, 5, 6, 7) == 4); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6)))(0, 1, 2, 3, 4, 5, 6, 7) == 5); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_7)))(0, 1, 2, 3, 4, 5, 6, 7) == 6); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_8)))(0, 1, 2, 3, 4, 5, 6, 7) == 7); + + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 0); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 1); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_3)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 2); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_4)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 3); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_5)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 4); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_6)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 5); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_7)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 6); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_8)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 7); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_9)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 8); + + // test mixed perfect forwarding + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(i[0], 1) == 0); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(i[0], 1) == 1); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_1)))(0, i[1]) == 0); + BOOST_HOF_TEST_CHECK(constify(boost::hof::protect(boost::hof::lazy(f)(std::placeholders::_2)))(0, i[1]) == 1); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::lazy(boost::hof::apply)(boost::hof::protect(boost::hof::lazy(boost::hof::identity)(boost::hof::_1)), boost::hof::_1)(17) == 17); + BOOST_HOF_TEST_CHECK(boost::hof::lazy(boost::hof::apply)(boost::hof::protect(boost::hof::lazy(boost::hof::identity)(boost::hof::_1)), 17)() == 17); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::lazy(boost::hof::apply)(boost::hof::protect(boost::hof::lazy(boost::hof::identity)(boost::hof::_1)), boost::hof::_1)(17) == 17); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::lazy(boost::hof::apply)(boost::hof::protect(boost::hof::lazy(boost::hof::identity)(boost::hof::_1)), 17)() == 17); +} + +namespace test1 { + +int id(int x) +{ + return x; +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::lazy(boost::hof::apply)(boost::hof::protect(boost::hof::lazy(id)(std::placeholders::_1)), std::placeholders::_1)(17) == 17); + BOOST_HOF_TEST_CHECK(boost::hof::lazy(boost::hof::apply)(boost::hof::protect(boost::hof::lazy(id)(std::placeholders::_1)), 17)() == 17); +} + +} diff --git a/src/boost/libs/hof/test/repeat.cpp b/src/boost/libs/hof/test/repeat.cpp new file mode 100644 index 000000000..19b3b51d7 --- /dev/null +++ b/src/boost/libs/hof/test/repeat.cpp @@ -0,0 +1,66 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + repeat.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 <boost/hof/repeat.hpp> +#include <limits> +#include "test.hpp" + +// TODO: Add tests for multiple parameters + +struct increment +{ + template<class T> + constexpr T operator()(T x) const noexcept + { + return x + 1; + } +}; + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::repeat(std::integral_constant<int, 5>())(increment())(1)), "noexcept repeat"); + static_assert(noexcept(boost::hof::repeat(5)(increment())(1)), "noexcept repeat"); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::repeat(std::integral_constant<int, 5>())(increment())(1) == 6); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::repeat(std::integral_constant<int, 5>())(increment())(1) == 6); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::repeat(5)(increment())(1) == 6); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::repeat(5)(increment())(1) == 6); +} + +BOOST_HOF_TEST_CASE() +{ + int i = 5; + BOOST_HOF_TEST_CHECK(boost::hof::repeat(i)(increment())(1) == 6); +} + +BOOST_HOF_TEST_CASE() +{ + static const int i = 5; + BOOST_HOF_TEST_CHECK(boost::hof::repeat(i)(increment())(1) == 6); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::repeat(i)(increment())(1) == 6); +} + +// BOOST_HOF_TEST_CASE() +// { +// BOOST_HOF_TEST_CHECK(boost::hof::repeat(std::numeric_limits<int>::max()/4)(increment())(0) == std::numeric_limits<int>::max()/4); +// } + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::repeat(BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH+4)(increment())(0) == BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH+4); +#if BOOST_HOF_HAS_RELAXED_CONSTEXPR + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::repeat(BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH+4)(increment())(0) == BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH+4); +#endif +} diff --git a/src/boost/libs/hof/test/repeat_while.cpp b/src/boost/libs/hof/test/repeat_while.cpp new file mode 100644 index 000000000..3b1d9fc1f --- /dev/null +++ b/src/boost/libs/hof/test/repeat_while.cpp @@ -0,0 +1,95 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + repeat_while.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 <boost/hof/repeat_while.hpp> +#include <boost/hof/reveal.hpp> +#include "test.hpp" + +// TODO: Test default construction, and static initialization + +struct increment_constant +{ + template<class T> + constexpr std::integral_constant<int, T::value + 1> operator()(T) const noexcept + { + return std::integral_constant<int, T::value + 1>(); + } +}; + +struct increment +{ + template<class T> + constexpr T operator()(T x) const noexcept + { + return x + 1; + } +}; + +struct not_6_constant +{ + template<class T> + constexpr std::integral_constant<bool, (T::value != 6)> + operator()(T) const noexcept + { + return std::integral_constant<bool, (T::value != 6)>(); + } +}; + +struct not_6 +{ + template<class T> + constexpr bool operator()(T x) const noexcept + { + return x != 6; + } +}; + +struct not_limit +{ + template<class T> + constexpr bool operator()(T x) const + { + return x != (BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH+4); + } +}; + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::repeat_while(not_6())(increment())(1)), "noexcept repeat_while"); + static_assert(noexcept(boost::hof::repeat_while(not_6_constant())(increment_constant())(std::integral_constant<int, 1>())), "noexcept repeat_while"); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + static_assert + ( + std::is_same< + std::integral_constant<int, 6>, + decltype(boost::hof::repeat_while(not_6_constant())(increment_constant())(std::integral_constant<int, 1>())) + >::value, + "Error" + ); + + std::integral_constant<int, 6> x = boost::hof::repeat_while(not_6_constant())(increment_constant())(std::integral_constant<int, 1>()); + boost::hof::test::unused(x); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::repeat_while(not_6())(increment())(1) == 6); + BOOST_HOF_TEST_CHECK(boost::hof::repeat_while(not_6())(increment())(1) == 6); + BOOST_HOF_TEST_CHECK(boost::hof::reveal(boost::hof::repeat_while(not_6())(increment()))(1) == 6); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::repeat_while(not_limit())(increment())(1) == BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH+4); +#if BOOST_HOF_HAS_RELAXED_CONSTEXPR + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::repeat_while(not_limit())(increment())(1) == BOOST_HOF_RECURSIVE_CONSTEXPR_DEPTH+4); +#endif +} diff --git a/src/boost/libs/hof/test/result.cpp b/src/boost/libs/hof/test/result.cpp new file mode 100644 index 000000000..cae0bb78d --- /dev/null +++ b/src/boost/libs/hof/test/result.cpp @@ -0,0 +1,26 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + result.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 <boost/hof/result.hpp> +#include <boost/hof/static.hpp> +#include "test.hpp" + + +static constexpr boost::hof::result_adaptor<int, unary_class> unary_int = {}; + +BOOST_HOF_TEST_CASE() +{ + STATIC_ASSERT_SAME(decltype(unary_int(false)), int); + BOOST_HOF_TEST_CHECK(unary_int(false) == 0); + BOOST_HOF_STATIC_TEST_CHECK(unary_int(false) == 0); +} + +static constexpr boost::hof::result_adaptor<void, unary_class> unary_void = {}; + +BOOST_HOF_TEST_CASE() +{ + STATIC_ASSERT_SAME(decltype(unary_void(false)), void); +} diff --git a/src/boost/libs/hof/test/returns.cpp b/src/boost/libs/hof/test/returns.cpp new file mode 100644 index 000000000..aec77819b --- /dev/null +++ b/src/boost/libs/hof/test/returns.cpp @@ -0,0 +1,56 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + returns.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 <boost/hof/returns.hpp> +#include "test.hpp" + +#if !defined (__GNUC__) || defined (__clang__) +struct add_1 +{ + int a; + add_1() : a(1) {} + + BOOST_HOF_RETURNS_CLASS(add_1); + + template<class T> + auto operator()(T x) const + BOOST_HOF_RETURNS(x+BOOST_HOF_CONST_THIS->a); +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == add_1()(2)); +} +#endif +// TODO: check noexcept +struct id +{ + template<class T> + constexpr auto operator()(T x) const BOOST_HOF_RETURNS + (x); +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(id{}(3) == 3); + BOOST_HOF_STATIC_TEST_CHECK(id{}(3) == 3); +} + +struct void_ {}; +constexpr void_ no_op() { return void_{}; } + +struct id_comma +{ + template<class T> + constexpr auto operator()(T&& x) const BOOST_HOF_RETURNS + (no_op(), boost::hof::forward<T>(x)); +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(id_comma{}(3) == 3); + BOOST_HOF_STATIC_TEST_CHECK(id_comma{}(3) == 3); +} diff --git a/src/boost/libs/hof/test/reveal.cpp b/src/boost/libs/hof/test/reveal.cpp new file mode 100644 index 000000000..9e7014d26 --- /dev/null +++ b/src/boost/libs/hof/test/reveal.cpp @@ -0,0 +1,157 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + reveal.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 "test.hpp" +#include <boost/hof/reveal.hpp> +#include <boost/hof/first_of.hpp> +#include <boost/hof/static.hpp> +#include <boost/hof/lambda.hpp> +#include <boost/hof/fix.hpp> + +namespace reveal_test { + +#define CONDITIONAL_FUNCTION(n) \ +struct t ## n {}; \ +struct f ## n \ +{ \ + constexpr int operator()(t ## n) const \ + { \ + return n; \ + } \ +}; + +CONDITIONAL_FUNCTION(1) +CONDITIONAL_FUNCTION(2) +CONDITIONAL_FUNCTION(3) + +typedef boost::hof::first_of_adaptor<f1, f2, f3> f_type; +static constexpr boost::hof::static_<f_type> f = {}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::reveal(f)(t1()) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::reveal(f)(t2()) == 2); + BOOST_HOF_TEST_CHECK(boost::hof::reveal(f)(t3()) == 3); + + + static_assert(boost::hof::is_invocable<boost::hof::reveal_adaptor<f_type>, t1>::value, "Invocable"); + static_assert(boost::hof::is_invocable<boost::hof::reveal_adaptor<f_type>, t2>::value, "Invocable"); + static_assert(boost::hof::is_invocable<boost::hof::reveal_adaptor<f_type>, t3>::value, "Invocable"); + + static_assert(!boost::hof::is_invocable<boost::hof::reveal_adaptor<f_type>, int>::value, "Invocable"); + // boost::hof::reveal(f)(1); +} + +#ifndef _MSC_VER +static constexpr auto lam = boost::hof::first_of( + BOOST_HOF_STATIC_LAMBDA(t1) + { + return 1; + }, + BOOST_HOF_STATIC_LAMBDA(t2) + { + return 2; + }, + BOOST_HOF_STATIC_LAMBDA(t3) + { + return 3; + } +); + +BOOST_HOF_TEST_CASE() +{ + STATIC_ASSERT_EMPTY(lam); + STATIC_ASSERT_EMPTY(boost::hof::reveal(lam)); + BOOST_HOF_TEST_CHECK(boost::hof::reveal(lam)(t1()) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::reveal(lam)(t2()) == 2); + BOOST_HOF_TEST_CHECK(boost::hof::reveal(lam)(t3()) == 3); + + // boost::hof::reveal(lam)(1); + // lam(1); +} +#endif + +BOOST_HOF_STATIC_LAMBDA_FUNCTION(static_fun) = boost::hof::first_of( + [](t1) + { + return 1; + }, + [](t2) + { + return 2; + }, + [](t3) + { + return 3; + } +); + +BOOST_HOF_TEST_CASE() +{ +#ifndef _MSC_VER + STATIC_ASSERT_EMPTY(static_fun); + // STATIC_ASSERT_EMPTY(boost::hof::reveal(static_fun)); +#endif + BOOST_HOF_TEST_CHECK(boost::hof::reveal(static_fun)(t1()) == 1); + BOOST_HOF_TEST_CHECK(boost::hof::reveal(static_fun)(t2()) == 2); + BOOST_HOF_TEST_CHECK(boost::hof::reveal(static_fun)(t3()) == 3); + + BOOST_HOF_TEST_CHECK(static_fun(t1()) == 1); + BOOST_HOF_TEST_CHECK(static_fun(t2()) == 2); + BOOST_HOF_TEST_CHECK(static_fun(t3()) == 3); + + // boost::hof::reveal(static_fun)(1); +} + +struct integral_type +{ + template<class T> + BOOST_HOF_USING_TYPENAME(failure_alias, std::enable_if<std::is_integral<T>::value>::type); + + struct failure + : boost::hof::as_failure<failure_alias> + {}; + + template<class T, class=typename std::enable_if<std::is_integral<T>::value>::type> + constexpr T operator()(T x) const + { + return x; + } +}; +struct foo {}; +struct dont_catch {}; + +struct catch_all +{ + template<class T> + BOOST_HOF_USING_TYPENAME(failure_alias, std::enable_if<!std::is_same<T, dont_catch>::value>::type); + + struct failure + : boost::hof::as_failure<failure_alias> + {}; + + template<class T, class=typename std::enable_if<!std::is_same<T, dont_catch>::value>::type> + constexpr int operator()(T) const + { + return -1; + } +}; + +static constexpr boost::hof::reveal_adaptor<boost::hof::first_of_adaptor<integral_type, catch_all>> check_failure = {}; + + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(check_failure(5) == 5); + BOOST_HOF_TEST_CHECK(check_failure(foo()) == -1); + + static_assert(!boost::hof::is_invocable<decltype(check_failure), dont_catch>::value, "Invocable"); + static_assert(!boost::hof::is_invocable<decltype(check_failure), int, int>::value, "Invocable"); + + // check_failure(dont_catch()); +} + +} diff --git a/src/boost/libs/hof/test/reverse_fold.cpp b/src/boost/libs/hof/test/reverse_fold.cpp new file mode 100644 index 000000000..9238e433e --- /dev/null +++ b/src/boost/libs/hof/test/reverse_fold.cpp @@ -0,0 +1,93 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + reverse_fold.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 <boost/hof/reverse_fold.hpp> +#include "test.hpp" + +struct max_f +{ + template<class T, class U> + constexpr T operator()(T x, U y) const noexcept + { + return x > y ? x : y; + } +}; + +struct sum_f +{ + template<class T, class U> + constexpr T operator()(T x, U y) const BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(x+y) + { + return x + y; + } +}; + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::reverse_fold(max_f(), 0)(2, 3, 4, 5)), "noexcept reverse_fold"); + static_assert(noexcept(boost::hof::reverse_fold(sum_f(), 0)(2, 3, 4, 5)), "noexcept reverse_fold"); + static_assert(!noexcept(boost::hof::reverse_fold(sum_f(), std::string())("hello", "-", "world")), "noexcept reverse_fold"); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(2, 3, 4, 5) == 5); + BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(5, 4, 3, 2) == 5); + BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(2, 3, 5, 4) == 5); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(2, 3, 4, 5) == 5); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(5, 4, 3, 2) == 5); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(2, 3, 5, 4) == 5); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)() == 0); + BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(5) == 5); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)() == 0); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f(), 0)(5) == 5); +} + +template<class... Ts> +constexpr auto find_positive_max(Ts... xs) BOOST_HOF_RETURNS +( + boost::hof::reverse_fold(max_f(), 0)(xs...) +); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(find_positive_max() == 0); + BOOST_HOF_TEST_CHECK(find_positive_max(5) == 5); + + BOOST_HOF_STATIC_TEST_CHECK(find_positive_max() == 0); + BOOST_HOF_STATIC_TEST_CHECK(find_positive_max(5) == 5); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f())(5) == 5); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f())(5) == 5); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f())(2, 3, 4, 5) == 5); + BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f())(5, 4, 3, 2) == 5); + BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(max_f())(2, 3, 5, 4) == 5); + + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f())(2, 3, 4, 5) == 5); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f())(5, 4, 3, 2) == 5); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::reverse_fold(max_f())(2, 3, 5, 4) == 5); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::reverse_fold(sum_f(), std::string())("hello", "-", "world") == "world-hello"); +} diff --git a/src/boost/libs/hof/test/rotate.cpp b/src/boost/libs/hof/test/rotate.cpp new file mode 100644 index 000000000..13f15806d --- /dev/null +++ b/src/boost/libs/hof/test/rotate.cpp @@ -0,0 +1,71 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + rotate.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 <boost/hof/rotate.hpp> +#include <boost/hof/placeholders.hpp> +#include <boost/hof/compose.hpp> +#include <boost/hof/repeat.hpp> +#include "test.hpp" + +struct head +{ + template<class T, class... Ts> + constexpr T operator()(T x, Ts&&...) const + BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(x) + { + return x; + } +}; + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::rotate(head{})(1, 2, 3, 4)), "noexcept rotate"); + static_assert(noexcept(boost::hof::repeat(std::integral_constant<int, 5>{})(boost::hof::rotate)(head{})(1, 2, 3, 4, 5, 6, 7, 8, 9)), "noexcept rotate"); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(2 == boost::hof::rotate(head{})(1, 2, 3, 4)); + BOOST_HOF_STATIC_TEST_CHECK(2 == boost::hof::rotate(head{})(1, 2, 3, 4)); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == boost::hof::compose(boost::hof::rotate, boost::hof::rotate)(head{})(1, 2, 3, 4)); + BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::compose(boost::hof::rotate, boost::hof::rotate)(head{})(1, 2, 3, 4)); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(6 == boost::hof::repeat(std::integral_constant<int, 5>{})(boost::hof::rotate)(head{})(1, 2, 3, 4, 5, 6, 7, 8, 9)); + BOOST_HOF_STATIC_TEST_CHECK(6 == boost::hof::repeat(std::integral_constant<int, 5>{})(boost::hof::rotate)(head{})(1, 2, 3, 4, 5, 6, 7, 8, 9)); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == boost::hof::rotate(boost::hof::_ - boost::hof::_)(2, 5)); + BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::rotate(boost::hof::_ - boost::hof::_)(2, 5)); +} + +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7 +#define FINAL +#else +#define FINAL final +#endif + + +struct f FINAL { + int operator()(int i, void *) const { + return i; + } +}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::rotate(f())(nullptr, 2) == 2); +} diff --git a/src/boost/libs/hof/test/static.cpp b/src/boost/libs/hof/test/static.cpp new file mode 100644 index 000000000..f718dd404 --- /dev/null +++ b/src/boost/libs/hof/test/static.cpp @@ -0,0 +1,24 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + static.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 <boost/hof/static.hpp> +#include "test.hpp" + +// TODO: Test infix + +static constexpr boost::hof::static_<binary_class> binary_static = {}; + +static constexpr boost::hof::static_<void_class> void_static = {}; + +static constexpr boost::hof::static_<mono_class> mono_static = {}; + + +BOOST_HOF_TEST_CASE() +{ + void_static(1); + BOOST_HOF_TEST_CHECK(3 == binary_static(1, 2)); + BOOST_HOF_TEST_CHECK(3 == mono_static(2)); +} diff --git a/src/boost/libs/hof/test/static_def/static_def.cpp b/src/boost/libs/hof/test/static_def/static_def.cpp new file mode 100644 index 000000000..83e9c7978 --- /dev/null +++ b/src/boost/libs/hof/test/static_def/static_def.cpp @@ -0,0 +1,59 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + static_def.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 <cstdio> +#include "static_def.hpp" + +extern int f(); + +extern void* f_sum_lambda_addr(); +extern void* f_sum_fo_addr(); + +extern void* sum_lambda_addr(); +extern void* sum_fo_addr(); + +extern void* f_sum_var_addr(); +extern void* f_sum_constexpr_fo_addr(); + +extern void* sum_var_addr(); +extern void* sum_constexpr_fo_addr(); + +void* sum_lambda_addr() +{ + return (void*)&fit_test::fit_sum_lambda; +} +void* sum_fo_addr() +{ + return (void*)&fit_test::fit_sum_fo; +} + +void* sum_var_addr() +{ + return (void*)&fit_test::fit_sum_var; +} +void* sum_constexpr_fo_addr() +{ + return (void*)&fit_test::fit_sum_constexpr_fo; +} + +int main() +{ + if (fit_test::fit_sum_fo(1, 2) != 3) printf("FAILED\n"); + if (fit_test::fit_sum_lambda(1, 2) != 3) printf("FAILED\n"); + if (fit_test::fit_sum(1, 2) != 3) printf("FAILED\n"); + +#if BOOST_HOF_HAS_UNIQUE_STATIC_LAMBDA_FUNCTION_ADDR + if (sum_lambda_addr() != f_sum_lambda_addr()) printf("FAILED: Lambda\n"); + if (sum_fo_addr() != f_sum_fo_addr()) printf("FAILED: Function object\n"); +#endif + +#if BOOST_HOF_HAS_UNIQUE_STATIC_VAR + if (sum_var_addr() != f_sum_var_addr()) printf("FAILED: Lambda\n"); + if (sum_constexpr_fo_addr() != f_sum_constexpr_fo_addr()) printf("FAILED: Function object\n"); +#endif + return f(); +} diff --git a/src/boost/libs/hof/test/static_def/static_def.hpp b/src/boost/libs/hof/test/static_def/static_def.hpp new file mode 100644 index 000000000..10574c64d --- /dev/null +++ b/src/boost/libs/hof/test/static_def/static_def.hpp @@ -0,0 +1,61 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + static_def.hpp + 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 GUARD_STATIC_DEF +#define GUARD_STATIC_DEF + +#include <boost/hof/function.hpp> +#include <boost/hof/lambda.hpp> + +// MSVC seems to not support unique addressing at all +#if defined (_MSC_VER) +#define BOOST_HOF_HAS_UNIQUE_STATIC_VAR 0 +#define BOOST_HOF_HAS_UNIQUE_STATIC_LAMBDA_FUNCTION_ADDR 0 +// Gcc 4.6 only supports unique addressing for non-lambdas +#elif defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7 +#define BOOST_HOF_HAS_UNIQUE_STATIC_VAR 1 +#define BOOST_HOF_HAS_UNIQUE_STATIC_LAMBDA_FUNCTION_ADDR 0 +#else +#define BOOST_HOF_HAS_UNIQUE_STATIC_VAR 1 +#define BOOST_HOF_HAS_UNIQUE_STATIC_LAMBDA_FUNCTION_ADDR 1 +#endif + +namespace fit_test { + +BOOST_HOF_STATIC_LAMBDA_FUNCTION(fit_sum_lambda) = [](int x, int y) +{ + return x + y; +}; + +struct fit_sum_f +{ + constexpr int operator()(int x, int y) const + { + return x + y; + } +}; + +BOOST_HOF_STATIC_LAMBDA_FUNCTION(fit_sum_fo) = fit_sum_f(); + +BOOST_HOF_STATIC_FUNCTION(fit_sum_constexpr_fo) = fit_sum_f(); + +BOOST_HOF_DECLARE_STATIC_VAR(fit_sum_var, fit_sum_f); + +// BOOST_HOF_STATIC_FUNCTION(fit_sum) = [](auto x, auto y) +// { +// return x + y; +// }; + +template<class T> +T fit_sum(T x, T y) +{ + return x + y; +}; + +} + +#endif diff --git a/src/boost/libs/hof/test/static_def/static_def2.cpp b/src/boost/libs/hof/test/static_def/static_def2.cpp new file mode 100644 index 000000000..b5e86e56c --- /dev/null +++ b/src/boost/libs/hof/test/static_def/static_def2.cpp @@ -0,0 +1,58 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + static_def2.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 <cstdio> +#include "static_def.hpp" + +extern void* f_sum_lambda_addr(); +extern void* f_sum_fo_addr(); + +extern void* sum_lambda_addr(); +extern void* sum_fo_addr(); + +extern void* f_sum_var_addr(); +extern void* f_sum_constexpr_fo_addr(); + +extern void* sum_var_addr(); +extern void* sum_constexpr_fo_addr(); + +void* f_sum_lambda_addr() +{ + return (void*)&fit_test::fit_sum_lambda; +} +void* f_sum_fo_addr() +{ + return (void*)&fit_test::fit_sum_fo; +} + +void* f_sum_var_addr() +{ + return (void*)&fit_test::fit_sum_var; +} +void* f_sum_constexpr_fo_addr() +{ + return (void*)&fit_test::fit_sum_constexpr_fo; +} + +int f() +{ + if (fit_test::fit_sum_fo(1, 2) != 3) printf("FAILED\n"); + if (fit_test::fit_sum_lambda(1, 2) != 3) printf("FAILED\n"); + if (fit_test::fit_sum(1, 2) != 3) printf("FAILED\n"); + +#if BOOST_HOF_HAS_UNIQUE_STATIC_LAMBDA_FUNCTION_ADDR + if (sum_lambda_addr() != f_sum_lambda_addr()) printf("FAILED: Lambda\n"); + if (sum_fo_addr() != f_sum_fo_addr()) printf("FAILED: Function object\n"); +#endif + +#if BOOST_HOF_HAS_UNIQUE_STATIC_VAR + if (sum_var_addr() != f_sum_var_addr()) printf("FAILED: Lambda\n"); + if (sum_constexpr_fo_addr() != f_sum_constexpr_fo_addr()) printf("FAILED: Function object\n"); +#endif + return 0; +} + diff --git a/src/boost/libs/hof/test/tap.cpp b/src/boost/libs/hof/test/tap.cpp new file mode 100644 index 000000000..25a92e4d0 --- /dev/null +++ b/src/boost/libs/hof/test/tap.cpp @@ -0,0 +1,25 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + tap.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 <boost/hof/tap.hpp> +#include "test.hpp" + +struct sum_f +{ + template<class T, class U> + constexpr T operator()(T x, U y) const + { + return x+y; + } +}; + +static constexpr boost::hof::pipable_adaptor<sum_f> sum = {}; +// TODO: Test constexpr +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == (1 | sum(2))); + BOOST_HOF_TEST_CHECK(5 == (1 | sum(2) | boost::hof::tap([](int i) { BOOST_HOF_TEST_CHECK(3 == i); }) | sum(2))); +} diff --git a/src/boost/libs/hof/test/test.hpp b/src/boost/libs/hof/test/test.hpp new file mode 100644 index 000000000..17fbd3676 --- /dev/null +++ b/src/boost/libs/hof/test/test.hpp @@ -0,0 +1,190 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + test.hpp + 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 GUARD_TEST_H +#define GUARD_TEST_H + +#include <type_traits> +#include <tuple> +#include <iostream> +#include <functional> +#include <vector> +#include <memory> +#include <boost/hof/detail/forward.hpp> + +#ifndef BOOST_HOF_HAS_STATIC_TEST_CHECK +#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7) || defined(_MSC_VER) +#define BOOST_HOF_HAS_STATIC_TEST_CHECK 0 +#else +#define BOOST_HOF_HAS_STATIC_TEST_CHECK 1 +#endif +#endif + + +#define BOOST_HOF_PP_CAT(x, y) BOOST_HOF_PP_PRIMITIVE_CAT(x, y) +#define BOOST_HOF_PP_PRIMITIVE_CAT(x, y) x ## y + +namespace boost { namespace hof { namespace test { + +typedef std::function<void()> test_case; +static std::vector<test_case> test_cases; + +struct auto_register +{ + auto_register(test_case tc) + { + test_cases.push_back(tc); + } +}; + +#define BOOST_HOF_DETAIL_TEST_CASE(name) \ +struct name \ +{ void operator()() const; }; \ +static boost::hof::test::auto_register BOOST_HOF_PP_CAT(name, _register) = boost::hof::test::auto_register(name()); \ +void name::operator()() const + +template<class T> +T bare(const T&); + +template<class T> +inline void unused(T&&) {} + +}}} // namespace boost::hof + +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7 +#define BOOST_HOF_STATIC_AUTO constexpr auto +#else +#define BOOST_HOF_STATIC_AUTO const constexpr auto +#endif + +#define STATIC_ASSERT_SAME(...) static_assert(std::is_same<__VA_ARGS__>::value, "Types are not the same") +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7 +#define STATIC_ASSERT_MOVE_ONLY(T) +#else +#define STATIC_ASSERT_MOVE_ONLY(T) static_assert(!std::is_copy_constructible<T>::value && std::is_move_constructible<T>::value, "Not movable") +#endif +#if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7 +#define STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(T) +#else +#define STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(T) static_assert(!std::is_default_constructible<T>::value, "Default constructible") +#endif +#define STATIC_ASSERT_EMPTY(x) static_assert(std::is_empty<decltype(boost::hof::test::bare(x))>::value, "Not empty"); + + +#define BOOST_HOF_TEST_CASE() BOOST_HOF_DETAIL_TEST_CASE(BOOST_HOF_PP_CAT(test_, __LINE__)) +#define BOOST_HOF_STATIC_TEST_CASE() struct BOOST_HOF_PP_CAT(test_, __LINE__) + +#define BOOST_HOF_TEST_TEMPLATE(...) typedef std::integral_constant<int, sizeof(__VA_ARGS__)> BOOST_HOF_PP_CAT(test_template_, __LINE__) + +#define BOOST_HOF_TEST_CHECK(...) if (!(__VA_ARGS__)) std::cout << "***** FAILED *****: " << #__VA_ARGS__ << "@" << __FILE__ << ": " << __LINE__ << std::endl +#define BOOST_HOF_STRINGIZE(...) #__VA_ARGS__ + +#if BOOST_HOF_HAS_STATIC_TEST_CHECK +#define BOOST_HOF_STATIC_TEST_CHECK(...) static_assert(__VA_ARGS__, BOOST_HOF_STRINGIZE(__VA_ARGS__)) +#else +#define BOOST_HOF_STATIC_TEST_CHECK(...) +#endif + +#ifndef BOOST_HOF_HAS_CONSTEXPR_TUPLE +#define BOOST_HOF_HAS_CONSTEXPR_TUPLE BOOST_HOF_HAS_STD_14 +#endif + +struct binary_class +{ + template<class T, class U> + constexpr T operator()(T x, U y) const noexcept + { + return x+y; + } + +}; + +struct mutable_class +{ + template<class F> + struct result; + + template<class F, class T, class U> + struct result<F(T&, U)> + { + typedef T type; + }; + + template<class T, class U> + T operator()(T & x, U y) const + { + return x+=y; + } + +}; + +struct unary_class +{ + template<class T> + constexpr T&& operator()(T&& x) const noexcept + { + return boost::hof::forward<T>(x); + } + +}; + +struct void_class +{ + template<class T> + void operator()(T) const + { + } +}; + +struct mono_class +{ + constexpr int operator()(int x) const + { + return x+1; + } +}; + +struct tuple_class +{ + // Note: Taking the tuple by value causes the compiler to ICE on gcc 4.7 + // when called in a constexpr context. + template<class T> + constexpr int operator()(const T& t) const + { + return std::get<0>(t) + 1; + } +}; + +template<class R> +struct explicit_class +{ + template<class T> + R operator()(T x) + { + return static_cast<R>(x); + } +}; + +struct move_class +{ + std::unique_ptr<int> i; + move_class() : i(new int(0)) + {} + + template<class T, class U> + constexpr T operator()(T x, U y) const + { + return x+y+*i; + } +}; + +int main() +{ + for(const auto& tc: boost::hof::test::test_cases) tc(); + return 0; +} + +#endif diff --git a/src/boost/libs/hof/test/tuple_for_each.cpp b/src/boost/libs/hof/test/tuple_for_each.cpp new file mode 100644 index 000000000..e784c1f2e --- /dev/null +++ b/src/boost/libs/hof/test/tuple_for_each.cpp @@ -0,0 +1,247 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + tuple_for_each.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 <boost/hof/unpack.hpp> +#include <boost/hof/proj.hpp> +#include <boost/hof/function.hpp> +#include <boost/hof/reveal.hpp> +#include "test.hpp" + +struct tuple_for_each_f +{ + template<class Sequence, class F> + constexpr auto operator()(Sequence&& s, F && f) const BOOST_HOF_RETURNS + ( + boost::hof::unpack(boost::hof::proj(boost::hof::forward<F>(f)))(boost::hof::forward<Sequence>(s)), boost::hof::forward<F>(f) + ); +}; + +BOOST_HOF_STATIC_FUNCTION(tuple_for_each) = tuple_for_each_f{}; + +BOOST_HOF_TEST_CASE() +{ + std::tuple<int, short, char> tp{ 1, 2, 3 }; + + { + int s = 0; + + tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 123 ); + } + + { + int s = 0; + + tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 123 ); + } +} +BOOST_HOF_TEST_CASE() +{ + std::tuple<int, short, char> const tp{ 1, 2, 3 }; + + { + int s = 0; + + tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 123 ); + } + + { + int s = 0; + + tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 123 ); + } +} + +// #if defined( __clang_major__ ) && __clang_major__ == 3 && __clang_minor__ < 8 +// #else +BOOST_HOF_TEST_CASE() +{ + std::tuple<std::unique_ptr<int>, std::unique_ptr<int>, std::unique_ptr<int>> tp{ std::unique_ptr<int>(new int(1)), std::unique_ptr<int>(new int(2)), std::unique_ptr<int>(new int(3)) }; + + int s = 0; + + tuple_for_each( std::move(tp), [&]( std::unique_ptr<int> p ){ s = s * 10 + *p; } ); + + BOOST_HOF_TEST_CHECK( s == 123 ); +} + +BOOST_HOF_TEST_CASE() +{ + auto tp = boost::hof::pack(1, 2, 3); + + { + int s = 0; + + tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 123 ); + } + + { + int s = 0; + + tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 123 ); + } +} +BOOST_HOF_TEST_CASE() +{ + const auto tp = boost::hof::pack(1, 2, 3); + + { + int s = 0; + + tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 123 ); + } + + { + int s = 0; + + tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 123 ); + } +} +// #endif +BOOST_HOF_TEST_CASE() +{ + std::pair<int, short> tp{ 1, 2 }; + + { + int s = 0; + + tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 12 ); + } + + { + int s = 0; + + tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 12 ); + } +} +BOOST_HOF_TEST_CASE() +{ + std::pair<int, short> const tp{ 1, 2 }; + + { + int s = 0; + + tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 12 ); + } + + { + int s = 0; + + tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 12 ); + } +} +BOOST_HOF_TEST_CASE() +{ + std::array<int, 3> tp{{ 1, 2, 3 }}; + + { + int s = 0; + + tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 123 ); + } + + { + int s = 0; + + tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 123 ); + } +} +BOOST_HOF_TEST_CASE() +{ + std::array<int, 3> const tp{{ 1, 2, 3 }}; + + { + int s = 0; + + tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 123 ); + } + + { + int s = 0; + + tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } ); + + BOOST_HOF_TEST_CHECK( s == 123 ); + } +} +BOOST_HOF_TEST_CASE() +{ + std::tuple<> tp; + + BOOST_HOF_TEST_CHECK( tuple_for_each( tp, 11 ) == 11 ); + BOOST_HOF_TEST_CHECK( tuple_for_each( std::move( tp ), 12 ) == 12 ); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK( tuple_for_each( boost::hof::pack(), 11 ) == 11 ); + BOOST_HOF_STATIC_TEST_CHECK( tuple_for_each( boost::hof::pack(), 11 ) == 11 ); +} +BOOST_HOF_TEST_CASE() +{ + std::array<int, 0> tp; + + BOOST_HOF_TEST_CHECK( tuple_for_each( tp, 11 ) == 11 ); + BOOST_HOF_TEST_CHECK( tuple_for_each( std::move( tp ), 12 ) == 12 ); +} + +struct assert_is_integral +{ + template<class T> constexpr bool operator()( T ) const + { + BOOST_HOF_STATIC_TEST_CHECK( std::is_integral<T>::value ); + return true; + } +}; + +BOOST_HOF_TEST_CASE() +{ +#if !BOOST_HOF_HAS_CONSTEXPR_TUPLE + auto r = tuple_for_each( std::tuple<int, short, char>{1, 2, 3}, assert_is_integral() ); +#else + constexpr auto r = tuple_for_each( std::tuple<int, short, char>{1, 2, 3}, assert_is_integral() ); +#endif + (void)r; +} + +BOOST_HOF_TEST_CASE() +{ +#if !BOOST_HOF_HAS_CONSTEXPR_TUPLE + auto r = tuple_for_each( boost::hof::pack(1, 2, 3), assert_is_integral() ); +#else + constexpr auto r = tuple_for_each( boost::hof::pack(1, 2, 3), assert_is_integral() ); +#endif + (void)r; +} diff --git a/src/boost/libs/hof/test/tuple_transform.cpp b/src/boost/libs/hof/test/tuple_transform.cpp new file mode 100644 index 000000000..d6aef66f4 --- /dev/null +++ b/src/boost/libs/hof/test/tuple_transform.cpp @@ -0,0 +1,90 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + tuple_transform.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 <boost/hof/proj.hpp> +#include <boost/hof/construct.hpp> +#include <boost/hof/unpack.hpp> +#include <boost/hof/function.hpp> +#include <boost/hof/placeholders.hpp> +#include <boost/hof/compose.hpp> +// Disable static checks for gcc 4.7 +#ifndef BOOST_HOF_HAS_STATIC_TEST_CHECK +#if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 8) +#define BOOST_HOF_HAS_STATIC_TEST_CHECK 0 +#endif +#endif +#include "test.hpp" + +struct tuple_transform_f +{ + template<class Sequence, class F> + constexpr auto operator()(Sequence&& s, F f) const BOOST_HOF_RETURNS + ( + boost::hof::unpack(boost::hof::proj(f, boost::hof::construct<std::tuple>()))(boost::hof::forward<Sequence>(s)) + ); +}; + +struct pack_transform_f +{ + template<class Sequence, class F> + constexpr auto operator()(Sequence&& s, F f) const BOOST_HOF_RETURNS + ( + boost::hof::unpack(boost::hof::proj(f, boost::hof::pack()))(boost::hof::forward<Sequence>(s)) + ); +}; + +BOOST_HOF_STATIC_FUNCTION(tuple_transform) = tuple_transform_f{}; +// BOOST_HOF_STATIC_FUNCTION(pack_transform) = pack_transform_f{}; + +#if !BOOST_HOF_HAS_CONSTEXPR_TUPLE +#define TUPLE_TRANSFORM_STATIC_CHECK(...) +#else +#define TUPLE_TRANSFORM_STATIC_CHECK BOOST_HOF_STATIC_TEST_CHECK + +#endif + +BOOST_HOF_TEST_CASE() +{ + auto t = std::make_tuple(1, 2); + auto r = tuple_transform(t, [](int i) { return i*i; }); + BOOST_HOF_TEST_CHECK(r == std::make_tuple(1, 4)); +} + +BOOST_HOF_TEST_CASE() +{ + TUPLE_TRANSFORM_STATIC_CHECK(tuple_transform(std::make_tuple(1, 2), boost::hof::_1 * boost::hof::_1) == std::make_tuple(1, 4)); +} + +#define TUPLE_TRANSFORM_CHECK_ID(x) \ +BOOST_HOF_TEST_CHECK(tuple_transform(x, boost::hof::identity) == x); \ +TUPLE_TRANSFORM_STATIC_CHECK(tuple_transform(x, boost::hof::identity) == x); + +BOOST_HOF_TEST_CASE() +{ + TUPLE_TRANSFORM_CHECK_ID(std::make_tuple(1, 2)); + TUPLE_TRANSFORM_CHECK_ID(std::make_tuple(1)); + TUPLE_TRANSFORM_CHECK_ID(std::make_tuple()); +} + +BOOST_HOF_TEST_CASE() +{ + auto x = tuple_transform(std::make_tuple(std::unique_ptr<int>(new int(3))), boost::hof::identity); + auto y = std::make_tuple(std::unique_ptr<int>(new int(3))); + BOOST_HOF_TEST_CHECK(x != y); + BOOST_HOF_TEST_CHECK(tuple_transform(x, *boost::hof::_1) == tuple_transform(y, *boost::hof::_1)); +} + +#define TUPLE_TRANSFORM_CHECK_COMPOSE(x, f, g) \ +BOOST_HOF_TEST_CHECK(tuple_transform(x, boost::hof::compose(f, g)) == tuple_transform(tuple_transform(x, g), f)); \ +TUPLE_TRANSFORM_STATIC_CHECK(tuple_transform(x, boost::hof::compose(f, g)) == tuple_transform(tuple_transform(x, g), f)); + +BOOST_HOF_TEST_CASE() +{ + TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(1, 2, 3, 4), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1); + TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(1, 2, 3), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1); + TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(1), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1); + TUPLE_TRANSFORM_CHECK_COMPOSE(std::make_tuple(), boost::hof::_1 * boost::hof::_1, boost::hof::_1 + boost::hof::_1); +} diff --git a/src/boost/libs/hof/test/unpack.cpp b/src/boost/libs/hof/test/unpack.cpp new file mode 100644 index 000000000..8d1e948e0 --- /dev/null +++ b/src/boost/libs/hof/test/unpack.cpp @@ -0,0 +1,255 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + unpack.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 <boost/hof/unpack.hpp> +#include <boost/hof/static.hpp> +#include <boost/hof/lambda.hpp> +#include "test.hpp" + +#include <memory> + +static constexpr boost::hof::static_<boost::hof::unpack_adaptor<unary_class> > unary_unpack = {}; +static constexpr boost::hof::static_<boost::hof::unpack_adaptor<binary_class> > binary_unpack = {}; + +BOOST_HOF_STATIC_AUTO unary_unpack_constexpr = boost::hof::unpack_adaptor<unary_class>(); +#if BOOST_HOF_HAS_CONSTEXPR_TUPLE +BOOST_HOF_STATIC_AUTO binary_unpack_constexpr = boost::hof::unpack_adaptor<binary_class>(); +#endif + +BOOST_HOF_STATIC_AUTO unary_unpack_reveal = boost::hof::reveal_adaptor<boost::hof::unpack_adaptor<unary_class>>(); +BOOST_HOF_STATIC_AUTO binary_unpack_reveal = boost::hof::reveal_adaptor<boost::hof::unpack_adaptor<binary_class>>(); + +#if BOOST_HOF_HAS_NOEXCEPT_DEDUCTION +BOOST_HOF_TEST_CASE() +{ + static_assert(noexcept(boost::hof::unpack(unary_class())(boost::hof::pack(3))), "noexcept unpack"); + static_assert(noexcept(unary_unpack(boost::hof::pack(3))), "noexcept unpack"); + static_assert(noexcept(binary_unpack(boost::hof::pack(3), boost::hof::pack(2))), "noexcept unpack"); +} +#endif + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(unary_class())(std::make_tuple(3))); + BOOST_HOF_TEST_CHECK(3 == unary_unpack(std::make_tuple(3))); + BOOST_HOF_TEST_CHECK(3 == unary_unpack_reveal(std::make_tuple(3))); + int ifu = 3; + BOOST_HOF_TEST_CHECK(3 == unary_unpack(std::tuple<int&>(ifu))); + +#if BOOST_HOF_HAS_CONSTEXPR_TUPLE + BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::unpack(unary_class())(std::make_tuple(3))); + BOOST_HOF_STATIC_TEST_CHECK(3 == unary_unpack_constexpr(std::make_tuple(3))); + BOOST_HOF_STATIC_TEST_CHECK(3 == unary_unpack_reveal(std::make_tuple(3))); +#endif +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(unary_class())(boost::hof::pack(3))); + BOOST_HOF_TEST_CHECK(3 == unary_unpack(boost::hof::pack(3))); + BOOST_HOF_TEST_CHECK(3 == unary_unpack_reveal(boost::hof::pack(3))); + int ifu = 3; + BOOST_HOF_TEST_CHECK(3 == unary_unpack(boost::hof::pack_forward(ifu))); + + BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::unpack(unary_class())(boost::hof::pack(3))); + BOOST_HOF_STATIC_TEST_CHECK(3 == unary_unpack_constexpr(boost::hof::pack(3))); + BOOST_HOF_STATIC_TEST_CHECK(3 == unary_unpack_reveal(boost::hof::pack(3))); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1, 2))); + BOOST_HOF_TEST_CHECK(3 == binary_unpack(std::make_tuple(1, 2))); + BOOST_HOF_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1, 2))); + + BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1), std::make_tuple(2))); + BOOST_HOF_TEST_CHECK(3 == binary_unpack(std::make_tuple(1), std::make_tuple(2))); + BOOST_HOF_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(2))); + + BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); + BOOST_HOF_TEST_CHECK(3 == binary_unpack(std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); + BOOST_HOF_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); + + BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); + BOOST_HOF_TEST_CHECK(3 == binary_unpack(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); + BOOST_HOF_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); + + BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple())); + BOOST_HOF_TEST_CHECK(3 == binary_unpack(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple())); + BOOST_HOF_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple())); + +#if BOOST_HOF_HAS_CONSTEXPR_TUPLE + BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1, 2))); + BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_constexpr(std::make_tuple(1, 2))); + BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1, 2))); + + BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1), std::make_tuple(2))); + BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_constexpr(std::make_tuple(1), std::make_tuple(2))); + BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(2))); + + BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); + BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_constexpr(std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); + BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); + + BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); + BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_constexpr(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); + BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); + + BOOST_HOF_STATIC_TEST_CHECK(3 == boost::hof::unpack(binary_class())(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple())); + BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_constexpr(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple())); + BOOST_HOF_STATIC_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple())); +#endif +} + +BOOST_HOF_TEST_CASE() +{ + auto p1 = boost::hof::pack_basic(1, 2); + static_assert(boost::hof::is_unpackable<decltype(p1)>::value, "Not unpackable"); + static_assert(boost::hof::is_unpackable<decltype((p1))>::value, "Not unpackable"); + + auto p2 = boost::hof::pack_forward(1, 2); + static_assert(boost::hof::is_unpackable<decltype(p2)>::value, "Not unpackable"); + static_assert(boost::hof::is_unpackable<decltype((p2))>::value, "Not unpackable"); + + auto p3 = boost::hof::pack(1, 2); + static_assert(boost::hof::is_unpackable<decltype(p3)>::value, "Not unpackable"); + static_assert(boost::hof::is_unpackable<decltype((p3))>::value, "Not unpackable"); + + static_assert(boost::hof::is_unpackable<std::tuple<int>>::value, "Not unpackable"); + + static_assert(!boost::hof::is_unpackable<int>::value, "Unpackable"); + static_assert(!boost::hof::is_unpackable<void>::value, "Unpackable"); +} + +BOOST_HOF_TEST_CASE() +{ + typedef std::tuple<int, int> tuple_type; + static_assert(boost::hof::is_unpackable<tuple_type>::value, "Not unpackable"); + static_assert(boost::hof::is_unpackable<tuple_type&>::value, "Not unpackable"); + static_assert(boost::hof::is_unpackable<const tuple_type&>::value, "Not unpackable"); + static_assert(boost::hof::is_unpackable<tuple_type&&>::value, "Not unpackable"); + +} + +BOOST_HOF_STATIC_AUTO lambda_unary_unpack = boost::hof::unpack(BOOST_HOF_STATIC_LAMBDA(int x) +{ + return x; +}); + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == lambda_unary_unpack(std::make_tuple(3))); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == lambda_unary_unpack(boost::hof::pack(3))); +} + +struct unary_move +{ + std::unique_ptr<int> i; + unary_move() + : i(new int(2)) + {} + + template<class T> + T operator()(T x) const + { + return x + *i; + } +}; + +static constexpr boost::hof::static_<boost::hof::unpack_adaptor<unary_move> > unary_move_unpack = {}; + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(unary_move())(std::make_tuple(1))); + BOOST_HOF_TEST_CHECK(3 == unary_move_unpack(std::make_tuple(1))); +} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(unary_move())(boost::hof::pack(1))); + BOOST_HOF_TEST_CHECK(3 == unary_move_unpack(boost::hof::pack(1))); +} + +struct indirect_sum_f +{ + template<class T, class U> + auto operator()(T x, U y) const + BOOST_HOF_RETURNS(*x + *y); +}; + +#define MAKE_UNIQUE_PTR(x) std::unique_ptr<int>(new int(x)) + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(indirect_sum_f())(boost::hof::pack_basic(MAKE_UNIQUE_PTR(1), MAKE_UNIQUE_PTR(2)))); + BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(indirect_sum_f())(boost::hof::pack_forward(MAKE_UNIQUE_PTR(1), MAKE_UNIQUE_PTR(2)))); + BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(indirect_sum_f())(boost::hof::pack(MAKE_UNIQUE_PTR(1), MAKE_UNIQUE_PTR(2)))); + BOOST_HOF_TEST_CHECK(3 == boost::hof::unpack(indirect_sum_f())(std::make_tuple(MAKE_UNIQUE_PTR(1), MAKE_UNIQUE_PTR(2)))); +} + +template<class...> +struct deduce_types +{}; + +struct deducer +{ + template<class... Ts> + deduce_types<Ts...> operator()(Ts&&...) const; +}; + +static constexpr boost::hof::unpack_adaptor<deducer> deduce = {}; + +BOOST_HOF_TEST_CASE() +{ + STATIC_ASSERT_SAME(deduce_types<int, int>, decltype(deduce(std::make_tuple(1, 2)))); + STATIC_ASSERT_SAME(deduce_types<int, int>, decltype(deduce(std::make_tuple(1), std::make_tuple(2)))); + STATIC_ASSERT_SAME(deduce_types<int, int, int>, decltype(deduce(std::make_tuple(1), std::make_tuple(2), std::make_tuple(3)))); + STATIC_ASSERT_SAME(std::tuple<int&&, int&&>, decltype(std::forward_as_tuple(1, 2))); + // Disable this test, it seems that rvalue references get swalllowed by type deduction + // STATIC_ASSERT_SAME(deduce_types<int&&, int&&>, decltype(deduce(std::forward_as_tuple(1, 2)))); + + + STATIC_ASSERT_SAME(deduce_types<int, int>, decltype(deduce(boost::hof::pack_basic(1, 2)))); + STATIC_ASSERT_SAME(deduce_types<int, int>, decltype(deduce(boost::hof::pack_basic(1), boost::hof::pack_basic(2)))); + STATIC_ASSERT_SAME(deduce_types<int, int, int>, decltype(deduce(boost::hof::pack_basic(1), boost::hof::pack_basic(2), boost::hof::pack_basic(3)))); + // STATIC_ASSERT_SAME(deduce_types<int&&, int&&>, decltype(deduce(boost::hof::pack_forward(1, 2)))); +} + +struct not_unpackable +{}; + +BOOST_HOF_TEST_CASE() +{ + auto f = boost::hof::unpack(boost::hof::always(1)); + + static_assert(!boost::hof::is_invocable<decltype(f), not_unpackable>::value, "SFINAE for unpack failed"); +} + +struct simple_unpackable +{}; + +namespace boost { namespace hof { + +template<> +struct unpack_sequence<simple_unpackable> +{ + template<class F, class S> + constexpr static auto apply(F&& f, S&&) BOOST_HOF_RETURNS + ( + f(1) + ); +}; +}} // namespace boost::hof + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::unpack(boost::hof::identity)(simple_unpackable{}) == 1); + BOOST_HOF_STATIC_TEST_CHECK(boost::hof::unpack(boost::hof::identity)(simple_unpackable{}) == 1); +} diff --git a/src/boost/libs/hof/test/virtual_base.cpp b/src/boost/libs/hof/test/virtual_base.cpp new file mode 100644 index 000000000..b686b9762 --- /dev/null +++ b/src/boost/libs/hof/test/virtual_base.cpp @@ -0,0 +1,37 @@ +/*============================================================================= + Copyright (c) 2017 Paul Fultz II + virtual_base.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 <boost/hof/flip.hpp> +#include <boost/hof/proj.hpp> +#include <boost/hof/construct.hpp> +#include <boost/hof/pipable.hpp> +#include <boost/hof/rotate.hpp> +#include "test.hpp" + +struct base { + base(int) {} + base(const base&) {} + virtual ~base(); +}; + +base::~base() {} + +struct derived : virtual base { + derived() : base(1) {} + derived(const derived&) : base(1) {} + int operator()(int i, void *) const { + return i; + } + ~derived(); +}; +derived::~derived() {} + +BOOST_HOF_TEST_CASE() +{ + BOOST_HOF_TEST_CHECK(boost::hof::flip(derived())(nullptr, 2) == 2); + BOOST_HOF_TEST_CHECK(boost::hof::rotate(derived())(nullptr, 2) == 2); + BOOST_HOF_TEST_CHECK((2 | boost::hof::pipable(derived())(nullptr)) == 2); +} |