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/hana/test/_include | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.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/hana/test/_include')
69 files changed, 9861 insertions, 0 deletions
diff --git a/src/boost/libs/hana/test/_include/auto/README.md b/src/boost/libs/hana/test/_include/auto/README.md new file mode 100644 index 000000000..082906c28 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/README.md @@ -0,0 +1,44 @@ +The headers in this directory provide facilities for automatic unit testing. +Basically, each header defines unit tests for an algorithm or a set of related +algorithms. To get the tests for these algorithms, simply include the header +at global scope. However, before including the header, you must define the +following macros: + + `MAKE_TUPLE(...)` + Must expand to a sequence holding `__VA_ARGS__`. A valid definition + would be `hana::make_tuple(__VA_ARGS__)`. + + `TUPLE_TYPE(...)` + Must expand to the type of a sequence holding objects of type `__VA_ARGS__`. + A valid definition would be `hana::tuple<__VA_ARGS__>`. + + `TUPLE_TAG` + Must expand to the tag of the sequence. A valid definition would + be `hana::tuple_tag`. + + +The following macros may or may not be defined: + + `MAKE_TUPLE_NO_CONSTEXPR` + Must be defined if the `MAKE_TUPLE` macro can't be used inside a + constant expression. Otherwise, `MAKE_TUPLE` is assumed to be able + to construct a `constexpr` container. + +The following directories contain automatic unit tests, and the following is +sufficient when adding a new automatic unit test (in a file `${FILE}`): + +```sh +DIRECTORIES=$(find test -type d -name auto | grep -v test/_include/auto) +for d in ${DIRECTORIES}; do + cat > ${d}/${FILE}.cpp <<EOF +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#include "_specs.hpp" +#include <auto/${FILE}.hpp> + +int main() { } +EOF +done +``` diff --git a/src/boost/libs/hana/test/_include/auto/all_of.hpp b/src/boost/libs/hana/test/_include/auto/all_of.hpp new file mode 100644 index 000000000..b1bdc1125 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/all_of.hpp @@ -0,0 +1,120 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_ALL_OF_HPP +#define BOOST_HANA_TEST_AUTO_ALL_OF_HPP + +#include <boost/hana/all_of.hpp> +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/not.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> + + +TestCase test_all_of{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::all_of( + MAKE_TUPLE(), + [](auto) { return hana::false_c; } + )); + + BOOST_HANA_CONSTANT_CHECK(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}), + [](auto) { return hana::true_c; } + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}), + [](auto) { return hana::false_c; } + ))); + BOOST_HANA_CONSTANT_CHECK(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}), + hana::equal.to(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}), + hana::equal.to(ct_eq<999>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + [](auto) { return hana::true_c; } + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + [](auto) { return hana::false_c; } + ))); + BOOST_HANA_CONSTANT_CHECK(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}), + hana::equal.to(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + hana::equal.to(ct_eq<0>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + [](auto) { return hana::true_c; } + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + [](auto) { return hana::false_c; } + ))); + BOOST_HANA_CONSTANT_CHECK(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{}), + hana::equal.to(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<0>{}), + hana::equal.to(ct_eq<0>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{}), + hana::equal.to(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of( + MAKE_TUPLE(ct_eq<999>{}, ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{}), + hana::equal.to(ct_eq<0>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<999>{}, ct_eq<0>{}, ct_eq<0>{}), + hana::equal.to(ct_eq<0>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<999>{}, ct_eq<0>{}), + hana::equal.to(ct_eq<0>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::all_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{}, ct_eq<999>{}), + hana::equal.to(ct_eq<0>{}) + ))); + + // Make sure `all_of` short-circuits with runtime predicates + // See http://stackoverflow.com/q/42012512/627587 + { + { + int counter = 0; + auto tuple = MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}); + hana::all_of(tuple, [&](auto) { ++counter; return false; }); + BOOST_HANA_RUNTIME_CHECK(counter == 1); + } + { + int counter = 0; + auto tuple = MAKE_TUPLE(ct_eq<0>{}, ct_eq<999>{}, ct_eq<0>{}); + hana::all_of(tuple, [&](auto x) -> bool { + ++counter; + return hana::equal(x, ct_eq<0>{}); + }); + BOOST_HANA_RUNTIME_CHECK(counter == 2); + } + } +}}; + +#endif // !BOOST_HANA_TEST_AUTO_ALL_OF_HPP diff --git a/src/boost/libs/hana/test/_include/auto/any_of.hpp b/src/boost/libs/hana/test/_include/auto/any_of.hpp new file mode 100644 index 000000000..400b5a3b1 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/any_of.hpp @@ -0,0 +1,173 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_ANY_OF_HPP +#define BOOST_HANA_TEST_AUTO_ANY_OF_HPP + +#include <boost/hana/any_of.hpp> +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/not.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> + + +TestCase test_any_of{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( + MAKE_TUPLE(), + [](auto) { return hana::true_c; } + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}), + [](auto) { return hana::true_c; } + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}), + [](auto) { return hana::false_c; } + ))); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}), + hana::equal.to(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}), + hana::equal.to(ct_eq<999>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + [](auto) { return hana::false_c; } + ))); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + [](auto) { return hana::true_c; } + )); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + hana::equal.to(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + hana::equal.to(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + hana::equal.to(ct_eq<999>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + [](auto) { return hana::false_c; } + ))); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + [](auto) { return hana::true_c; } + )); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + hana::equal.to(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + hana::equal.to(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + hana::equal.to(ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + hana::equal.to(ct_eq<999>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + [](auto) { return hana::false_c; } + ))); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + [](auto) { return hana::true_c; } + )); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + hana::equal.to(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + hana::equal.to(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + hana::equal.to(ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + hana::equal.to(ct_eq<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + hana::equal.to(ct_eq<999>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + [](auto) { return hana::false_c; } + ))); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + [](auto) { return hana::true_c; } + )); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::equal.to(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::equal.to(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::equal.to(ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::equal.to(ct_eq<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::equal.to(ct_eq<4>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::equal.to(ct_eq<999>{}) + ))); + + // Make sure `any_of` short-circuits with runtime predicates + // See http://stackoverflow.com/q/42012512/627587 + { + { + int counter = 0; + auto tuple = MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}); + hana::any_of(tuple, [&](auto) { ++counter; return true; }); + BOOST_HANA_RUNTIME_CHECK(counter == 1); + } + { + int counter = 0; + auto tuple = MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + hana::any_of(tuple, [&](auto x) -> bool { + ++counter; + return hana::equal(x, ct_eq<1>{}); + }); + BOOST_HANA_RUNTIME_CHECK(counter == 2); + } + } +}}; + +#endif // !BOOST_HANA_TEST_AUTO_ANY_OF_HPP diff --git a/src/boost/libs/hana/test/_include/auto/ap.hpp b/src/boost/libs/hana/test/_include/auto/ap.hpp new file mode 100644 index 000000000..7fe0fc5be --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/ap.hpp @@ -0,0 +1,76 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_AP_HPP +#define BOOST_HANA_TEST_AUTO_AP_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/ap.hpp> +#include <boost/hana/equal.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> + + +TestCase test_ap{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + hana::test::_injection<0> f{}; + hana::test::_injection<1> g{}; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(MAKE_TUPLE(), MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{})), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(MAKE_TUPLE(f), MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(MAKE_TUPLE(f), MAKE_TUPLE(ct_eq<0>{})), + MAKE_TUPLE(f(ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(MAKE_TUPLE(f), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(MAKE_TUPLE(f), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(MAKE_TUPLE(f, g), MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(MAKE_TUPLE(f, g), MAKE_TUPLE(ct_eq<0>{})), + MAKE_TUPLE(f(ct_eq<0>{}), g(ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(MAKE_TUPLE(f, g), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{}), g(ct_eq<0>{}), g(ct_eq<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(MAKE_TUPLE(f, g), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{}), + g(ct_eq<0>{}), g(ct_eq<1>{}), g(ct_eq<2>{})) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_AP_HPP diff --git a/src/boost/libs/hana/test/_include/auto/at.hpp b/src/boost/libs/hana/test/_include/auto/at.hpp new file mode 100644 index 000000000..66574a361 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/at.hpp @@ -0,0 +1,91 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_AT_HPP +#define BOOST_HANA_TEST_AUTO_AT_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/at.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/integral_constant.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> +#include <support/tracked.hpp> + + +namespace _test_at_detail { template <int> struct invalid { }; } + + +TestCase test_at{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + using _test_at_detail::invalid; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>), + ct_eq<0>{} + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(MAKE_TUPLE(ct_eq<0>{}, invalid<1>{}), hana::size_c<0>), + ct_eq<0>{} + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(MAKE_TUPLE(invalid<0>{}, ct_eq<1>{}), hana::size_c<1>), + ct_eq<1>{} + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(MAKE_TUPLE(invalid<0>{}, ct_eq<1>{}, invalid<2>{}), hana::size_c<1>), + ct_eq<1>{} + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(MAKE_TUPLE(invalid<0>{}, invalid<1>{}, ct_eq<2>{}), hana::size_c<2>), + ct_eq<2>{} + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(MAKE_TUPLE(invalid<0>{}, invalid<1>{}, ct_eq<2>{}, invalid<3>{}), hana::size_c<2>), + ct_eq<2>{} + )); + +#ifndef MAKE_TUPLE_NO_CONSTEXPR + static_assert(hana::equal( + hana::at(MAKE_TUPLE(1), hana::size_c<0>), + 1 + ), ""); + static_assert(hana::equal( + hana::at(MAKE_TUPLE(1, '2'), hana::size_c<0>), + 1 + ), ""); + static_assert(hana::equal( + hana::at(MAKE_TUPLE(1, '2', 3.3), hana::size_c<0>), + 1 + ), ""); + + static_assert(hana::equal( + hana::at(MAKE_TUPLE(1, '2'), hana::size_c<1>), + '2' + ), ""); + static_assert(hana::equal( + hana::at(MAKE_TUPLE(1, '2', 3.3), hana::size_c<1>), + '2' + ), ""); + + static_assert(hana::equal( + hana::at(MAKE_TUPLE(1, '2', 3.3), hana::size_c<2>), + 3.3 + ), ""); +#endif + + // make sure we can use non-pods on both sides + { + // store the result to make sure `at` is executed. + auto result = hana::at(MAKE_TUPLE(Tracked{0}, ct_eq<1>{}, Tracked{1}), hana::size_c<1>);; + BOOST_HANA_CONSTANT_CHECK(hana::equal(result, ct_eq<1>{})); + } + +}}; + +#endif // !BOOST_HANA_TEST_AUTO_AT_HPP diff --git a/src/boost/libs/hana/test/_include/auto/cartesian_product.hpp b/src/boost/libs/hana/test/_include/auto/cartesian_product.hpp new file mode 100644 index 000000000..8aecf3649 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/cartesian_product.hpp @@ -0,0 +1,234 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_CARTESIAN_PRODUCT_HPP +#define BOOST_HANA_TEST_AUTO_CARTESIAN_PRODUCT_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/cartesian_product.hpp> +#include <boost/hana/equal.hpp> + +#include <laws/base.hpp> +#include "test_case.hpp" + + +TestCase test_cartesian_product{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + // 0 lists + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::cartesian_product(MAKE_TUPLE()), + MAKE_TUPLE() + )); + + // 1 list + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE() + )), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}) + )), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}) + ) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}), + MAKE_TUPLE(ct_eq<1>{}) + ) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}) + )), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}), + MAKE_TUPLE(ct_eq<1>{}), + MAKE_TUPLE(ct_eq<2>{}) + ) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}) + )), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}), + MAKE_TUPLE(ct_eq<1>{}), + MAKE_TUPLE(ct_eq<2>{}), + MAKE_TUPLE(ct_eq<3>{}) + ) + )); + + // 2 lists + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(), + MAKE_TUPLE() + )), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(ct_eq<00>{}), + MAKE_TUPLE() + )), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(ct_eq<00>{}), + MAKE_TUPLE(ct_eq<10>{}) + )), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}) + ) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(ct_eq<00>{}, ct_eq<01>{}), + MAKE_TUPLE(ct_eq<10>{}) + )), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}), + MAKE_TUPLE(ct_eq<01>{}, ct_eq<10>{}) + ) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(ct_eq<00>{}), + MAKE_TUPLE(ct_eq<10>{}, ct_eq<11>{}) + )), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}), + MAKE_TUPLE(ct_eq<00>{}, ct_eq<11>{}) + ) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(ct_eq<00>{}, ct_eq<01>{}), + MAKE_TUPLE(ct_eq<10>{}, ct_eq<11>{}) + )), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}), + MAKE_TUPLE(ct_eq<00>{}, ct_eq<11>{}), + MAKE_TUPLE(ct_eq<01>{}, ct_eq<10>{}), + MAKE_TUPLE(ct_eq<01>{}, ct_eq<11>{}) + ) + )); + + // misc + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(ct_eq<00>{}), + MAKE_TUPLE(ct_eq<10>{}), + MAKE_TUPLE(ct_eq<20>{}), + MAKE_TUPLE(ct_eq<30>{}, ct_eq<31>{}) + )), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}, ct_eq<20>{}, ct_eq<30>{}), + MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}, ct_eq<20>{}, ct_eq<31>{}) + ) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(ct_eq<00>{}), + MAKE_TUPLE(ct_eq<10>{}), + MAKE_TUPLE(ct_eq<20>{}, ct_eq<21>{}), + MAKE_TUPLE(ct_eq<30>{}, ct_eq<31>{}) + )), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}, ct_eq<20>{}, ct_eq<30>{}), + MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}, ct_eq<20>{}, ct_eq<31>{}), + MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}, ct_eq<21>{}, ct_eq<30>{}), + MAKE_TUPLE(ct_eq<00>{}, ct_eq<10>{}, ct_eq<21>{}, ct_eq<31>{}) + ) + )); + + + // cartesian_product in a constexpr context +#ifndef MAKE_TUPLE_NO_CONSTEXPR + static_assert(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(1), + MAKE_TUPLE('a', 'b') + )), + MAKE_TUPLE( + MAKE_TUPLE(1, 'a'), + MAKE_TUPLE(1, 'b') + ) + ), ""); + + static_assert(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(1, 2), + MAKE_TUPLE('a') + )), + MAKE_TUPLE( + MAKE_TUPLE(1, 'a'), + MAKE_TUPLE(2, 'a') + ) + ), ""); + + static_assert(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(1, 2), + MAKE_TUPLE('a', 'b') + )), + MAKE_TUPLE( + MAKE_TUPLE(1, 'a'), + MAKE_TUPLE(1, 'b'), + MAKE_TUPLE(2, 'a'), + MAKE_TUPLE(2, 'b') + ) + ), ""); + + static_assert(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(1), + MAKE_TUPLE('a'), + MAKE_TUPLE(1.f), + MAKE_TUPLE(1l, 2l) + )), + MAKE_TUPLE( + MAKE_TUPLE(1, 'a', 1.f, 1l), + MAKE_TUPLE(1, 'a', 1.f, 2l) + ) + ), ""); + + static_assert(hana::equal( + hana::cartesian_product(MAKE_TUPLE( + MAKE_TUPLE(1), + MAKE_TUPLE('a'), + MAKE_TUPLE(1.f), + MAKE_TUPLE(1l, 2l), + MAKE_TUPLE(nullptr) + )), + MAKE_TUPLE( + MAKE_TUPLE(1, 'a', 1.f, 1l, nullptr), + MAKE_TUPLE(1, 'a', 1.f, 2l, nullptr) + ) + ), ""); +#endif +}}; + +#endif // !BOOST_HANA_TEST_AUTO_CARTESIAN_PRODUCT_HPP diff --git a/src/boost/libs/hana/test/_include/auto/drop_back.hpp b/src/boost/libs/hana/test/_include/auto/drop_back.hpp new file mode 100644 index 000000000..e3ea42e0c --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/drop_back.hpp @@ -0,0 +1,99 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_DROP_BACK_HPP +#define BOOST_HANA_TEST_AUTO_DROP_BACK_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/drop_back.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/integral_constant.hpp> + +#include <laws/base.hpp> +#include "test_case.hpp" + + +TestCase test_drop_back{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(), hana::size_c<0>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(), hana::size_c<1>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(), hana::size_c<2>), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<2>), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<2>), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<0>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<1>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<2>), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<3>), + MAKE_TUPLE() + )); + + // make sure hana::drop_back(xs) == hana::drop_back(xs, hana::size_c<1>) + BOOST_HANA_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE()), + hana::drop_back(MAKE_TUPLE(), hana::size_c<1>) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(ct_eq<0>{})), + hana::drop_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{})), + hana::drop_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}), hana::size_c<1>) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_DROP_BACK_HPP diff --git a/src/boost/libs/hana/test/_include/auto/drop_front.hpp b/src/boost/libs/hana/test/_include/auto/drop_front.hpp new file mode 100644 index 000000000..05988ace2 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/drop_front.hpp @@ -0,0 +1,160 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_DROP_FRONT_HPP +#define BOOST_HANA_TEST_AUTO_DROP_FRONT_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/drop_front.hpp> +#include <boost/hana/drop_front_exactly.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/integral_constant.hpp> + +#include <laws/base.hpp> +#include "test_case.hpp" + + +TestCase test_drop_front{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(), hana::size_c<0>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(), hana::size_c<1>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(), hana::size_c<2>), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<2>), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>), + MAKE_TUPLE(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<2>), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<0>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<1>), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<2>), + MAKE_TUPLE(ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<3>), + MAKE_TUPLE() + )); + + // make sure hana::drop_front(xs) == hana::drop_front(xs, size_c<1>) + BOOST_HANA_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE()), + hana::drop_front(MAKE_TUPLE(), hana::size_c<1>) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(ct_eq<0>{})), + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{})), + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}), hana::size_c<1>) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}) + )); +}}; + +TestCase test_drop_front_exactly{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front_exactly(MAKE_TUPLE(), hana::size_c<0>), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>), + MAKE_TUPLE(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<2>), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front_exactly( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, + ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}), hana::size_c<4>), + MAKE_TUPLE(ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}) + )); + + // make sure drop_front_exactly(xs) == drop_front_exactly(xs, size_c<1>) + BOOST_HANA_CHECK(hana::equal( + hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{})), + hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{})), + hana::drop_front_exactly(MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}), hana::size_c<1>) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_DROP_FRONT_HPP diff --git a/src/boost/libs/hana/test/_include/auto/drop_while.hpp b/src/boost/libs/hana/test/_include/auto/drop_while.hpp new file mode 100644 index 000000000..054d79be0 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/drop_while.hpp @@ -0,0 +1,72 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_DROP_WHILE_HPP +#define BOOST_HANA_TEST_AUTO_DROP_WHILE_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/drop_while.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/functional/id.hpp> +#include <boost/hana/not_equal.hpp> + +#include <laws/base.hpp> +#include "test_case.hpp" + + +TestCase test_drop_while{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_while(MAKE_TUPLE(), hana::id), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_while(MAKE_TUPLE(hana::true_c), hana::id), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_while(MAKE_TUPLE(hana::false_c), hana::id), + MAKE_TUPLE(hana::false_c) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_while(MAKE_TUPLE(hana::true_c, hana::true_c), hana::id), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_while(MAKE_TUPLE(hana::true_c, hana::false_c), hana::id), + MAKE_TUPLE(hana::false_c) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_while(MAKE_TUPLE(hana::false_c, hana::true_c), hana::id), + MAKE_TUPLE(hana::false_c, hana::true_c) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_while(MAKE_TUPLE(hana::false_c, hana::false_c), hana::id), + MAKE_TUPLE(hana::false_c, hana::false_c) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_while(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::not_equal.to(ct_eq<99>{})), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_while(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::not_equal.to(ct_eq<1>{})), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_while(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::not_equal.to(ct_eq<3>{})), + MAKE_TUPLE(ct_eq<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_while(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::not_equal.to(ct_eq<0>{})), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_DROP_WHILE_HPP diff --git a/src/boost/libs/hana/test/_include/auto/for_each.hpp b/src/boost/libs/hana/test/_include/auto/for_each.hpp new file mode 100644 index 000000000..4e36e9853 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/for_each.hpp @@ -0,0 +1,64 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_FOR_EACH_HPP +#define BOOST_HANA_TEST_AUTO_FOR_EACH_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/for_each.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> + +#include <vector> + + +TestCase test_for_each{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + // Make sure the function is applied in left-to-right order. + { + auto check = [](auto ...xs) { + std::vector<int> seen{}; + hana::for_each(MAKE_TUPLE(xs...), [&](int x) { + seen.push_back(x); + }); + BOOST_HANA_RUNTIME_CHECK(seen == std::vector<int>{xs...}); + }; + + check(); + check(0); + check(0, 1); + check(0, 1, 2); + check(0, 1, 2, 3); + check(0, 1, 2, 3, 4); + } + + // Make sure the function is never called when the sequence is empty. + { + struct undefined { }; + hana::for_each(MAKE_TUPLE(), undefined{}); + } + + // Make sure it works with heterogeneous sequences. + { + hana::for_each(MAKE_TUPLE(ct_eq<0>{}), [](auto) { }); + hana::for_each(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), [](auto) { }); + hana::for_each(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), [](auto) { }); + hana::for_each(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), [](auto) { }); + } + + // Make sure for_each is constexpr when used with a constexpr function + // and constexpr arguments. This used not to be the case. +#ifndef MAKE_TUPLE_NO_CONSTEXPR + { + struct f { constexpr void operator()(int) const { } }; + constexpr int i = (hana::for_each(MAKE_TUPLE(1, 2, 3), f{}), 0); + (void)i; + } +#endif +}}; + +#endif // !BOOST_HANA_TEST_AUTO_FOR_EACH_HPP diff --git a/src/boost/libs/hana/test/_include/auto/group.hpp b/src/boost/libs/hana/test/_include/auto/group.hpp new file mode 100644 index 000000000..1802ebd33 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/group.hpp @@ -0,0 +1,150 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_GROUP_HPP +#define BOOST_HANA_TEST_AUTO_GROUP_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/group.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> +#include <support/equivalence_class.hpp> + + +TestCase test_group{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + struct undefined { }; + + // Test without a custom predicate + { + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE()), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE(ct_eq<0>{})), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{})), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}), + MAKE_TUPLE(ct_eq<1>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{})), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<1>{})), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}), + MAKE_TUPLE(ct_eq<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<0>{})), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}), + MAKE_TUPLE(ct_eq<1>{}), + MAKE_TUPLE(ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE(ct_eq<1>{}, ct_eq<0>{}, ct_eq<0>{})), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<1>{}), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<1>{}, ct_eq<1>{})), + MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<1>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<2>{}, ct_eq<2>{})), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<1>{}), + MAKE_TUPLE(ct_eq<2>{}, ct_eq<2>{}, ct_eq<2>{})) + )); + } + + // Test with a custom predicate + { + auto a = [](auto z) { return ::equivalence_class(ct_eq<999>{}, z); }; + auto b = [](auto z) { return ::equivalence_class(ct_eq<888>{}, z); }; + + auto pred = [](auto x, auto y) { + return hana::equal(x.unwrap, y.unwrap); + }; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE(), undefined{}), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE(a(ct_eq<0>{})), pred), + MAKE_TUPLE( + MAKE_TUPLE(a(ct_eq<0>{}))) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{})), pred), + MAKE_TUPLE( + MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{}))) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{}), a(ct_eq<1>{})), pred), + MAKE_TUPLE( + MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{})), + MAKE_TUPLE(a(ct_eq<1>{}))) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{}), a(ct_eq<1>{}), b(ct_eq<1>{})), pred), + MAKE_TUPLE( + MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{})), + MAKE_TUPLE(a(ct_eq<1>{}), b(ct_eq<1>{}))) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{}), a(ct_eq<1>{}), b(ct_eq<1>{}), b(ct_eq<0>{})), pred), + MAKE_TUPLE( + MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{})), + MAKE_TUPLE(a(ct_eq<1>{}), b(ct_eq<1>{})), + MAKE_TUPLE(b(ct_eq<0>{}))) + )); + + // Test group.by syntactic sugar + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group.by(pred, MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{}), a(ct_eq<1>{}), b(ct_eq<1>{}), b(ct_eq<0>{}))), + MAKE_TUPLE( + MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{})), + MAKE_TUPLE(a(ct_eq<1>{}), b(ct_eq<1>{})), + MAKE_TUPLE(b(ct_eq<0>{}))) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::group.by(pred)(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{}), a(ct_eq<1>{}), b(ct_eq<1>{}), b(ct_eq<0>{}))), + MAKE_TUPLE( + MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{})), + MAKE_TUPLE(a(ct_eq<1>{}), b(ct_eq<1>{})), + MAKE_TUPLE(b(ct_eq<0>{}))) + )); + } +}}; + +#endif // !BOOST_HANA_TEST_AUTO_GROUP_HPP diff --git a/src/boost/libs/hana/test/_include/auto/index_if.hpp b/src/boost/libs/hana/test/_include/auto/index_if.hpp new file mode 100644 index 000000000..af7c86bbc --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/index_if.hpp @@ -0,0 +1,81 @@ +// Copyright Louis Dionne 2013-2017 +// Copyright Jason Rice 2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_INDEX_IF_HPP +#define BOOST_HANA_TEST_AUTO_INDEX_IF_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/index_if.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/optional.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> +#include <support/tracked.hpp> + + +namespace _test_index_if_detail { template <int> struct invalid { }; } + + +TestCase test_index_if{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + using _test_index_if_detail::invalid; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::index_if(MAKE_TUPLE(), hana::equal.to(ct_eq<0>{})), + hana::nothing + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::index_if(MAKE_TUPLE(ct_eq<0>{}), hana::equal.to(ct_eq<0>{})), + hana::just(hana::size_c<0>) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::index_if(MAKE_TUPLE(ct_eq<0>{}), hana::equal.to(ct_eq<42>{})), + hana::nothing + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::index_if(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(ct_eq<0>{})), + hana::just(hana::size_c<0>) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::index_if(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(ct_eq<1>{})), + hana::just(hana::size_c<1>) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::index_if(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(ct_eq<2>{})), + hana::just(hana::size_c<2>) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::index_if(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(ct_eq<42>{})), + hana::nothing + )); + +#ifndef MAKE_TUPLE_NO_CONSTEXPR + auto type_equal = [](auto type) { return [=](auto&& value) { + return hana::equal(hana::typeid_(value), type); + };}; + + static_assert(decltype(hana::equal( + hana::index_if(MAKE_TUPLE(1, '2', 3.3), type_equal(hana::type_c<int>)), + hana::just(hana::size_c<0>) + )){}, ""); + static_assert(decltype(hana::equal( + hana::index_if(MAKE_TUPLE(1, '2', 3.3), type_equal(hana::type_c<char>)), + hana::just(hana::size_c<1>) + )){}, ""); + static_assert(decltype(hana::equal( + hana::index_if(MAKE_TUPLE(1, '2', 3.3), type_equal(hana::type_c<double>)), + hana::just(hana::size_c<2>) + )){}, ""); + static_assert(decltype(hana::equal( + hana::index_if(MAKE_TUPLE(1, '2', 3.3), type_equal(hana::type_c<invalid<42>>)), + hana::nothing + )){}, ""); +#endif +}}; + +#endif // !BOOST_HANA_TEST_AUTO_INDEX_IF_HPP diff --git a/src/boost/libs/hana/test/_include/auto/insert.hpp b/src/boost/libs/hana/test/_include/auto/insert.hpp new file mode 100644 index 000000000..c9715452a --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/insert.hpp @@ -0,0 +1,84 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_INSERT_HPP +#define BOOST_HANA_TEST_AUTO_INSERT_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/insert.hpp> +#include <boost/hana/integral_constant.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> + + +TestCase test_insert{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + auto z = ct_eq<999>{}; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>, z), + MAKE_TUPLE(z, ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>, z), + MAKE_TUPLE(ct_eq<0>{}, z) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>, z), + MAKE_TUPLE(z, ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>, z), + MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<2>, z), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, z) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<0>, z), + MAKE_TUPLE(z, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<1>, z), + MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<2>, z), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, z, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::size_c<3>, z), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, z) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::size_c<0>, z), + MAKE_TUPLE(z, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::size_c<1>, z), + MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::size_c<2>, z), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, z, ct_eq<2>{}, ct_eq<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::size_c<3>, z), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, z, ct_eq<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::size_c<4>, z), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, z) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_INSERT_HPP diff --git a/src/boost/libs/hana/test/_include/auto/insert_range.hpp b/src/boost/libs/hana/test/_include/auto/insert_range.hpp new file mode 100644 index 000000000..ac929d7ed --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/insert_range.hpp @@ -0,0 +1,105 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_INSERT_RANGE_HPP +#define BOOST_HANA_TEST_AUTO_INSERT_RANGE_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/insert_range.hpp> +#include <boost/hana/integral_constant.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> +#include <support/seq.hpp> + + +TestCase test_insert_range{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + auto foldable = ::seq; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert_range( + MAKE_TUPLE(ct_eq<1>{}), + hana::size_c<0>, + foldable()), + MAKE_TUPLE(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert_range( + MAKE_TUPLE(ct_eq<1>{}), + hana::size_c<0>, + foldable(ct_eq<-1>{})), + MAKE_TUPLE(ct_eq<-1>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert_range( + MAKE_TUPLE(ct_eq<1>{}), + hana::size_c<0>, + foldable(ct_eq<-1>{}, ct_eq<-2>{})), + MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert_range( + MAKE_TUPLE(ct_eq<1>{}), + hana::size_c<0>, + foldable(ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<-3>{})), + MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<-3>{}, ct_eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert_range( + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), + hana::size_c<0>, + foldable()), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert_range( + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), + hana::size_c<0>, + foldable(ct_eq<-1>{})), + MAKE_TUPLE(ct_eq<-1>{}, ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert_range( + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), + hana::size_c<0>, + foldable(ct_eq<-1>{}, ct_eq<-2>{})), + MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert_range( + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), + hana::size_c<1>, + foldable()), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert_range( + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), + hana::size_c<1>, + foldable(ct_eq<-1>{})), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<-1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert_range( + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), + hana::size_c<1>, + foldable(ct_eq<-1>{}, ct_eq<-2>{})), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<2>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::insert_range( + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::size_c<2>, + foldable(ct_eq<-1>{}, ct_eq<-2>{})), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<3>{}, ct_eq<4>{}) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_INSERT_RANGE_HPP diff --git a/src/boost/libs/hana/test/_include/auto/intersperse.hpp b/src/boost/libs/hana/test/_include/auto/intersperse.hpp new file mode 100644 index 000000000..83e7e8148 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/intersperse.hpp @@ -0,0 +1,54 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_INTERSPERSE_HPP +#define BOOST_HANA_TEST_AUTO_INTERSPERSE_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/intersperse.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> + + +TestCase test_intersperse{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + struct undefined { }; + + auto z = ct_eq<999>{}; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::intersperse(MAKE_TUPLE(), undefined{}), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::intersperse(MAKE_TUPLE(ct_eq<0>{}), undefined{}), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::intersperse(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), z), + MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::intersperse(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), z), + MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{}, z, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::intersperse(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), z), + MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{}, z, ct_eq<2>{}, z, ct_eq<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::intersperse(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), z), + MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{}, z, ct_eq<2>{}, z, ct_eq<3>{}, z, ct_eq<4>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::intersperse(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}), z), + MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<1>{}, z, ct_eq<2>{}, z, ct_eq<3>{}, z, ct_eq<4>{}, z, ct_eq<5>{}) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_INTERSPERSE_HPP diff --git a/src/boost/libs/hana/test/_include/auto/is_empty.hpp b/src/boost/libs/hana/test/_include/auto/is_empty.hpp new file mode 100644 index 000000000..99ae879dd --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/is_empty.hpp @@ -0,0 +1,55 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_IS_EMPTY_HPP +#define BOOST_HANA_TEST_AUTO_IS_EMPTY_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/is_empty.hpp> +#include <boost/hana/not.hpp> + +#include "test_case.hpp" + + +namespace _test_is_empty_detail { template <int i> struct undefined { }; } + +TestCase test_is_empty{[]{ + namespace hana = boost::hana; + using _test_is_empty_detail::undefined; + + BOOST_HANA_CONSTANT_CHECK(hana::is_empty( + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty( + MAKE_TUPLE(undefined<0>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty( + MAKE_TUPLE(undefined<0>{}, undefined<1>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty( + MAKE_TUPLE(undefined<0>{}, undefined<1>{}, undefined<2>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty( + MAKE_TUPLE(undefined<0>{}, undefined<1>{}, undefined<2>{}, undefined<3>{}) + ))); + + // Check with a runtime value + { + int i = 3; // <- runtime value + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(MAKE_TUPLE(i)))); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(MAKE_TUPLE(i, i)))); + } + +#ifndef MAKE_TUPLE_NO_CONSTEXPR + static_assert(hana::is_empty(MAKE_TUPLE()), ""); + static_assert(hana::not_(hana::is_empty(MAKE_TUPLE(undefined<0>{}))), ""); + static_assert(hana::not_(hana::is_empty(MAKE_TUPLE(undefined<0>{}, undefined<1>{}))), ""); +#endif +}}; + +#endif // !BOOST_HANA_TEST_AUTO_IS_EMPTY_HPP diff --git a/src/boost/libs/hana/test/_include/auto/length.hpp b/src/boost/libs/hana/test/_include/auto/length.hpp new file mode 100644 index 000000000..25f75dc4d --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/length.hpp @@ -0,0 +1,48 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_LENGTH_HPP +#define BOOST_HANA_TEST_AUTO_LENGTH_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/length.hpp> + +#include "test_case.hpp" + + +namespace _test_length_detail { template <int> struct undefined { }; } + +TestCase test_length{[]{ + namespace hana = boost::hana; + using _test_length_detail::undefined; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(MAKE_TUPLE()), + hana::size_c<0> + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(MAKE_TUPLE(undefined<1>{})), + hana::size_c<1> + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(MAKE_TUPLE(undefined<1>{}, undefined<2>{})), + hana::size_c<2> + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(MAKE_TUPLE(undefined<1>{}, undefined<2>{}, undefined<3>{})), + hana::size_c<3> + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(MAKE_TUPLE(undefined<1>{}, undefined<2>{}, undefined<3>{}, undefined<4>{}, undefined<5>{}, undefined<6>{})), + hana::size_c<6> + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_LENGTH_HPP diff --git a/src/boost/libs/hana/test/_include/auto/lexicographical_compare.hpp b/src/boost/libs/hana/test/_include/auto/lexicographical_compare.hpp new file mode 100644 index 000000000..83870d561 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/lexicographical_compare.hpp @@ -0,0 +1,109 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_LEXICOGRAPHICAL_COMPARE_HPP +#define BOOST_HANA_TEST_AUTO_LEXICOGRAPHICAL_COMPARE_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/lexicographical_compare.hpp> +#include <boost/hana/not.hpp> + +#include <laws/base.hpp> +#include "test_case.hpp" + + +TestCase test_lexicographical_compare{[]{ + namespace hana = boost::hana; + using hana::test::ct_ord; + + struct undefined { }; + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare( + MAKE_TUPLE(), + MAKE_TUPLE() + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::lexicographical_compare( + MAKE_TUPLE(), + MAKE_TUPLE(undefined{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare( + MAKE_TUPLE(undefined{}), + MAKE_TUPLE() + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare( + MAKE_TUPLE(ct_ord<0>{}), + MAKE_TUPLE(ct_ord<0>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::lexicographical_compare( + MAKE_TUPLE(ct_ord<0>{}), + MAKE_TUPLE(ct_ord<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare( + MAKE_TUPLE(ct_ord<1>{}), + MAKE_TUPLE(ct_ord<0>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare( + MAKE_TUPLE(ct_ord<0>{}, undefined{}), + MAKE_TUPLE(ct_ord<0>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::lexicographical_compare( + MAKE_TUPLE(ct_ord<0>{}), + MAKE_TUPLE(ct_ord<0>{}, undefined{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::lexicographical_compare( + MAKE_TUPLE(ct_ord<0>{}, ct_ord<0>{}), + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare( + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}), + MAKE_TUPLE(ct_ord<0>{}, ct_ord<0>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare( + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}), + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare( + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, undefined{}), + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::lexicographical_compare( + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}), + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, undefined{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare( + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<3>{}, undefined{}), + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, undefined{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::lexicographical_compare( + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, undefined{}), + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<3>{}, undefined{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::lexicographical_compare( + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, undefined{}), + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<3>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::lexicographical_compare( + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<3>{}), + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, undefined{}) + ))); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_LEXICOGRAPHICAL_COMPARE_HPP diff --git a/src/boost/libs/hana/test/_include/auto/make.hpp b/src/boost/libs/hana/test/_include/auto/make.hpp new file mode 100644 index 000000000..83536edfd --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/make.hpp @@ -0,0 +1,41 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_MAKE_HPP +#define BOOST_HANA_TEST_AUTO_MAKE_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/core/make.hpp> +#include <boost/hana/equal.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> + + +TestCase test_make{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + MAKE_TUPLE(), + hana::make<TUPLE_TAG>() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + MAKE_TUPLE(ct_eq<0>{}), + hana::make<TUPLE_TAG>(ct_eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + hana::make<TUPLE_TAG>(ct_eq<0>{}, ct_eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + hana::make<TUPLE_TAG>(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_MAKE_HPP diff --git a/src/boost/libs/hana/test/_include/auto/none_of.hpp b/src/boost/libs/hana/test/_include/auto/none_of.hpp new file mode 100644 index 000000000..7e1dff2d8 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/none_of.hpp @@ -0,0 +1,90 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_NONE_OF_HPP +#define BOOST_HANA_TEST_AUTO_NONE_OF_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/none_of.hpp> +#include <boost/hana/not.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> + + +TestCase test_none_of{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::none_of( + MAKE_TUPLE(), + [](auto) { return hana::false_c; } + )); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::none_of( + MAKE_TUPLE(ct_eq<0>{}), + [](auto) { return hana::true_c; } + ))); + BOOST_HANA_CONSTANT_CHECK(hana::none_of( + MAKE_TUPLE(ct_eq<0>{}), + [](auto) { return hana::false_c; } + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::none_of( + MAKE_TUPLE(ct_eq<0>{}), + hana::equal.to(ct_eq<0>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(hana::none_of( + MAKE_TUPLE(ct_eq<0>{}), + hana::equal.to(ct_eq<999>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::none_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::equal.to(ct_eq<0>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::none_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::equal.to(ct_eq<1>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::none_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::equal.to(ct_eq<2>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::none_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::equal.to(ct_eq<3>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::none_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::equal.to(ct_eq<4>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(hana::none_of( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::equal.to(ct_eq<999>{}) + )); + + // Make sure `none_of` short-circuits with runtime predicates + // See http://stackoverflow.com/q/42012512/627587 + { + { + int counter = 0; + auto tuple = MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}); + hana::none_of(tuple, [&](auto) { ++counter; return true; }); + BOOST_HANA_RUNTIME_CHECK(counter == 1); + } + { + int counter = 0; + auto tuple = MAKE_TUPLE(ct_eq<999>{}, ct_eq<0>{}, ct_eq<999>{}); + hana::none_of(tuple, [&](auto x) -> bool { + ++counter; + return hana::equal(x, ct_eq<0>{}); + }); + BOOST_HANA_RUNTIME_CHECK(counter == 2); + } + } +}}; + +#endif // !BOOST_HANA_TEST_AUTO_NONE_OF_HPP diff --git a/src/boost/libs/hana/test/_include/auto/partition.hpp b/src/boost/libs/hana/test/_include/auto/partition.hpp new file mode 100644 index 000000000..d1fa7212e --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/partition.hpp @@ -0,0 +1,74 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_PARTITION_HPP +#define BOOST_HANA_TEST_AUTO_PARTITION_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/contains.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/partition.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> +#include <support/minimal_product.hpp> + + +TestCase test_partition{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + struct undefined { }; + + auto pair = ::minimal_product; + auto pred = hana::in ^ MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<-3>{}, ct_eq<-4>{}, ct_eq<-5>{}); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::partition(MAKE_TUPLE(), undefined{}), + pair(MAKE_TUPLE(), MAKE_TUPLE()) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::partition(MAKE_TUPLE(ct_eq<0>{}), pred), + pair(MAKE_TUPLE(), + MAKE_TUPLE(ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::partition(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), pred), + pair(MAKE_TUPLE(), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::partition(MAKE_TUPLE(ct_eq<-1>{}), pred), + pair(MAKE_TUPLE(ct_eq<-1>{}), + MAKE_TUPLE()) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::partition(MAKE_TUPLE(ct_eq<-1>{}, ct_eq<0>{}, ct_eq<2>{}), pred), + pair(MAKE_TUPLE(ct_eq<-1>{}), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::partition(MAKE_TUPLE(ct_eq<0>{}, ct_eq<-3>{}, ct_eq<2>{}, ct_eq<-5>{}, ct_eq<6>{}), pred), + pair(MAKE_TUPLE(ct_eq<-3>{}, ct_eq<-5>{}), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<6>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::partition(MAKE_TUPLE(ct_eq<-1>{}, ct_eq<2>{}, ct_eq<-3>{}, ct_eq<0>{}, ct_eq<-3>{}, ct_eq<4>{}), pred), + pair(MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-3>{}, ct_eq<-3>{}), + MAKE_TUPLE(ct_eq<2>{}, ct_eq<0>{}, ct_eq<4>{})) + )); + + // partition.by + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::partition.by(pred, MAKE_TUPLE(ct_eq<-1>{}, ct_eq<0>{}, ct_eq<2>{})), + hana::partition(MAKE_TUPLE(ct_eq<-1>{}, ct_eq<0>{}, ct_eq<2>{}), pred) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::partition.by(pred)(MAKE_TUPLE(ct_eq<-1>{}, ct_eq<0>{}, ct_eq<2>{})), + hana::partition(MAKE_TUPLE(ct_eq<-1>{}, ct_eq<0>{}, ct_eq<2>{}), pred) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_PARTITION_HPP diff --git a/src/boost/libs/hana/test/_include/auto/permutations.hpp b/src/boost/libs/hana/test/_include/auto/permutations.hpp new file mode 100644 index 000000000..d854103ac --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/permutations.hpp @@ -0,0 +1,87 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_PERMUTATIONS_HPP +#define BOOST_HANA_TEST_AUTO_PERMUTATIONS_HPP + +#include <boost/hana/and.hpp> +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/is_subset.hpp> +#include <boost/hana/permutations.hpp> + +#include <laws/base.hpp> +#include "test_case.hpp" + + +TestCase test_permutations{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + auto is_permutation = [](auto xs, auto ys) { + return hana::and_(hana::is_subset(xs, ys), hana::is_subset(ys, xs)); + }; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::permutations(MAKE_TUPLE()), + MAKE_TUPLE(MAKE_TUPLE()) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::permutations(MAKE_TUPLE(ct_eq<0>{})), + MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(is_permutation( + hana::permutations(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<0>{}) + ) + )); + + BOOST_HANA_CONSTANT_CHECK(is_permutation( + hana::permutations(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<1>{}), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<0>{}, ct_eq<2>{}), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<0>{}), + MAKE_TUPLE(ct_eq<2>{}, ct_eq<0>{}, ct_eq<1>{}), + MAKE_TUPLE(ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{}) + ) + )); + + BOOST_HANA_CONSTANT_CHECK(is_permutation( + hana::permutations(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})), + MAKE_TUPLE( + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<3>{}, ct_eq<2>{}), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<1>{}, ct_eq<3>{}), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<1>{}), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<3>{}, ct_eq<1>{}, ct_eq<2>{}), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<3>{}, ct_eq<2>{}, ct_eq<1>{}), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<0>{}, ct_eq<2>{}, ct_eq<3>{}), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<0>{}, ct_eq<3>{}, ct_eq<2>{}), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<0>{}, ct_eq<3>{}), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<0>{}), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<3>{}, ct_eq<0>{}, ct_eq<2>{}), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<3>{}, ct_eq<2>{}, ct_eq<0>{}), + MAKE_TUPLE(ct_eq<2>{}, ct_eq<0>{}, ct_eq<1>{}, ct_eq<3>{}), + MAKE_TUPLE(ct_eq<2>{}, ct_eq<0>{}, ct_eq<3>{}, ct_eq<1>{}), + MAKE_TUPLE(ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{}, ct_eq<3>{}), + MAKE_TUPLE(ct_eq<2>{}, ct_eq<1>{}, ct_eq<3>{}, ct_eq<0>{}), + MAKE_TUPLE(ct_eq<2>{}, ct_eq<3>{}, ct_eq<0>{}, ct_eq<1>{}), + MAKE_TUPLE(ct_eq<2>{}, ct_eq<3>{}, ct_eq<1>{}, ct_eq<0>{}), + MAKE_TUPLE(ct_eq<3>{}, ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + MAKE_TUPLE(ct_eq<3>{}, ct_eq<0>{}, ct_eq<2>{}, ct_eq<1>{}), + MAKE_TUPLE(ct_eq<3>{}, ct_eq<1>{}, ct_eq<0>{}, ct_eq<2>{}), + MAKE_TUPLE(ct_eq<3>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<0>{}), + MAKE_TUPLE(ct_eq<3>{}, ct_eq<2>{}, ct_eq<0>{}, ct_eq<1>{}), + MAKE_TUPLE(ct_eq<3>{}, ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{}) + ) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_PERMUTATIONS_HPP diff --git a/src/boost/libs/hana/test/_include/auto/remove_at.hpp b/src/boost/libs/hana/test/_include/auto/remove_at.hpp new file mode 100644 index 000000000..296b989e8 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/remove_at.hpp @@ -0,0 +1,130 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_REMOVE_AT_HPP +#define BOOST_HANA_TEST_AUTO_REMOVE_AT_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/remove_at.hpp> + +#include <laws/base.hpp> +#include "test_case.hpp" + + +TestCase test_remove_at{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at(MAKE_TUPLE(ct_eq<0>{}), + hana::size_c<0>), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + hana::size_c<0>), + MAKE_TUPLE(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + hana::size_c<1>), + MAKE_TUPLE(ct_eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + hana::size_c<0>), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + hana::size_c<1>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + hana::size_c<2>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + hana::size_c<0>), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + hana::size_c<1>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + hana::size_c<2>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + hana::size_c<3>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::size_c<0>), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::size_c<1>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::size_c<2>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<3>{}, ct_eq<4>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::size_c<3>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<4>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + hana::size_c<4>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}) + )); + + // remove_at_c + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at_c<0>(MAKE_TUPLE(ct_eq<0>{})), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at_c<0>(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + MAKE_TUPLE(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at_c<1>(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + MAKE_TUPLE(ct_eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at_c<0>(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at_c<1>(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_at_c<2>(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_REMOVE_AT_HPP diff --git a/src/boost/libs/hana/test/_include/auto/remove_range.hpp b/src/boost/libs/hana/test/_include/auto/remove_range.hpp new file mode 100644 index 000000000..51bbf9133 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/remove_range.hpp @@ -0,0 +1,114 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_REMOVE_RANGE_HPP +#define BOOST_HANA_TEST_AUTO_REMOVE_RANGE_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/remove_range.hpp> + +#include <laws/base.hpp> +#include "test_case.hpp" + + +TestCase test_remove_range{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(), hana::size_c<0>, hana::size_c<0>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(), hana::size_c<1>, hana::size_c<1>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(), hana::size_c<2>, hana::size_c<2>), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>, hana::size_c<0>), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>, hana::size_c<1>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>, hana::size_c<1>), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<2>, hana::size_c<2>), + MAKE_TUPLE(ct_eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>, hana::size_c<0>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>, hana::size_c<1>), + MAKE_TUPLE(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>, hana::size_c<2>), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>, hana::size_c<2>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<2>, hana::size_c<2>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + hana::size_c<9999>, hana::size_c<9999>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + hana::size_c<0>, hana::size_c<2>), + MAKE_TUPLE(ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + hana::size_c<1>, hana::size_c<3>), + MAKE_TUPLE(ct_eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + hana::size_c<0>, hana::size_c<2>), + MAKE_TUPLE(ct_eq<2>{}, ct_eq<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + hana::size_c<2>, hana::size_c<3>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<3>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, + ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}), + hana::size_c<4>, hana::size_c<7>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}) + )); + + // remove_range_c + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::remove_range_c<4, 7>(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, + ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{})), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_REMOVE_RANGE_HPP diff --git a/src/boost/libs/hana/test/_include/auto/reverse.hpp b/src/boost/libs/hana/test/_include/auto/reverse.hpp new file mode 100644 index 000000000..c0c2000c5 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/reverse.hpp @@ -0,0 +1,55 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_REVERSE_HPP +#define BOOST_HANA_TEST_AUTO_REVERSE_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/reverse.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> + + +TestCase test_reverse{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + using hana::test::cx_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::reverse(MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::reverse(MAKE_TUPLE(ct_eq<0>{})), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::reverse(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::reverse(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + MAKE_TUPLE(ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{}) + )); + + +#ifndef MAKE_TUPLE_NO_CONSTEXPR + static_assert(hana::equal( + hana::reverse(MAKE_TUPLE(cx_eq<1>{})), + MAKE_TUPLE(cx_eq<1>{}) + ), ""); + static_assert(hana::equal( + hana::reverse(MAKE_TUPLE(cx_eq<1>{}, cx_eq<2>{})), + MAKE_TUPLE(cx_eq<2>{}, cx_eq<1>{}) + ), ""); + static_assert(hana::equal( + hana::reverse(MAKE_TUPLE(cx_eq<1>{}, cx_eq<2>{}, cx_eq<3>{})), + MAKE_TUPLE(cx_eq<3>{}, cx_eq<2>{}, cx_eq<1>{}) + ), ""); +#endif +}}; + +#endif // !BOOST_HANA_TEST_AUTO_REVERSE_HPP diff --git a/src/boost/libs/hana/test/_include/auto/scans.hpp b/src/boost/libs/hana/test/_include/auto/scans.hpp new file mode 100644 index 000000000..5c5c0dd6a --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/scans.hpp @@ -0,0 +1,216 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_SCANS_HPP +#define BOOST_HANA_TEST_AUTO_SCANS_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/scan_left.hpp> +#include <boost/hana/scan_right.hpp> + +#include <laws/base.hpp> +#include "test_case.hpp" + + +TestCase test_scan_left{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + struct undefined { }; + hana::test::_injection<0> f{}; + + // Without initial state + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_left(MAKE_TUPLE(), undefined{}), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_left(MAKE_TUPLE(ct_eq<0>{}), undefined{}), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), f), + MAKE_TUPLE(ct_eq<0>{}, f(ct_eq<0>{}, ct_eq<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), f), + MAKE_TUPLE( + ct_eq<0>{}, + f(ct_eq<0>{}, ct_eq<1>{}), + f(f(ct_eq<0>{}, ct_eq<1>{}), ct_eq<2>{}) + ) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), f), + MAKE_TUPLE( + ct_eq<0>{}, + f(ct_eq<0>{}, ct_eq<1>{}), + f(f(ct_eq<0>{}, ct_eq<1>{}), ct_eq<2>{}), + f(f(f(ct_eq<0>{}, ct_eq<1>{}), ct_eq<2>{}), ct_eq<3>{}) + ) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), f), + MAKE_TUPLE( + ct_eq<0>{}, + f(ct_eq<0>{}, ct_eq<1>{}), + f(f(ct_eq<0>{}, ct_eq<1>{}), ct_eq<2>{}), + f(f(f(ct_eq<0>{}, ct_eq<1>{}), ct_eq<2>{}), ct_eq<3>{}), + f(f(f(f(ct_eq<0>{}, ct_eq<1>{}), ct_eq<2>{}), ct_eq<3>{}), ct_eq<4>{}) + ) + )); + + // With initial state + auto s = ct_eq<999>{}; + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_left(MAKE_TUPLE(), s, undefined{}), + MAKE_TUPLE(s) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_left(MAKE_TUPLE(ct_eq<0>{}), s, f), + MAKE_TUPLE(s, f(s, ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), s, f), + MAKE_TUPLE(s, f(s, ct_eq<0>{}), f(f(s, ct_eq<0>{}), ct_eq<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), s, f), + MAKE_TUPLE( + s, + f(s, ct_eq<0>{}), + f(f(s, ct_eq<0>{}), ct_eq<1>{}), + f(f(f(s, ct_eq<0>{}), ct_eq<1>{}), ct_eq<2>{}) + ) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), s, f), + MAKE_TUPLE( + s, + f(s, ct_eq<0>{}), + f(f(s, ct_eq<0>{}), ct_eq<1>{}), + f(f(f(s, ct_eq<0>{}), ct_eq<1>{}), ct_eq<2>{}), + f(f(f(f(s, ct_eq<0>{}), ct_eq<1>{}), ct_eq<2>{}), ct_eq<3>{}) + ) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_left(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), s, f), + MAKE_TUPLE( + s, + f(s, ct_eq<0>{}), + f(f(s, ct_eq<0>{}), ct_eq<1>{}), + f(f(f(s, ct_eq<0>{}), ct_eq<1>{}), ct_eq<2>{}), + f(f(f(f(s, ct_eq<0>{}), ct_eq<1>{}), ct_eq<2>{}), ct_eq<3>{}), + f(f(f(f(f(s, ct_eq<0>{}), ct_eq<1>{}), ct_eq<2>{}), ct_eq<3>{}), ct_eq<4>{}) + ) + )); +}}; + + +TestCase test_scan_right{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + struct undefined { }; + hana::test::_injection<0> f{}; + + // Without initial state + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_right(MAKE_TUPLE(), undefined{}), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_right(MAKE_TUPLE(ct_eq<0>{}), undefined{}), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), f), + MAKE_TUPLE( + f(ct_eq<0>{}, ct_eq<1>{}), + ct_eq<1>{} + ) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), f), + MAKE_TUPLE( + f(ct_eq<0>{}, f(ct_eq<1>{}, ct_eq<2>{})), + f(ct_eq<1>{}, ct_eq<2>{}), + ct_eq<2>{} + ) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), f), + MAKE_TUPLE( + f(ct_eq<0>{}, f(ct_eq<1>{}, f(ct_eq<2>{}, ct_eq<3>{}))), + f(ct_eq<1>{}, f(ct_eq<2>{}, ct_eq<3>{})), + f(ct_eq<2>{}, ct_eq<3>{}), + ct_eq<3>{} + ) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), f), + MAKE_TUPLE( + f(ct_eq<0>{}, f(ct_eq<1>{}, f(ct_eq<2>{}, f(ct_eq<3>{}, ct_eq<4>{})))), + f(ct_eq<1>{}, f(ct_eq<2>{}, f(ct_eq<3>{}, ct_eq<4>{}))), + f(ct_eq<2>{}, f(ct_eq<3>{}, ct_eq<4>{})), + f(ct_eq<3>{}, ct_eq<4>{}), + ct_eq<4>{} + ) + )); + + // With initial state + auto s = ct_eq<999>{}; + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_right(MAKE_TUPLE(), s, undefined{}), + MAKE_TUPLE(s) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_right(MAKE_TUPLE(ct_eq<0>{}), s, f), + MAKE_TUPLE( + f(ct_eq<0>{}, s), + s + ) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), s, f), + MAKE_TUPLE( + f(ct_eq<0>{}, f(ct_eq<1>{}, s)), + f(ct_eq<1>{}, s), + s + ) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), s, f), + MAKE_TUPLE( + f(ct_eq<0>{}, f(ct_eq<1>{}, f(ct_eq<2>{}, s))), + f(ct_eq<1>{}, f(ct_eq<2>{}, s)), + f(ct_eq<2>{}, s), + s + ) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), s, f), + MAKE_TUPLE( + f(ct_eq<0>{}, f(ct_eq<1>{}, f(ct_eq<2>{}, f(ct_eq<3>{}, s)))), + f(ct_eq<1>{}, f(ct_eq<2>{}, f(ct_eq<3>{}, s))), + f(ct_eq<2>{}, f(ct_eq<3>{}, s)), + f(ct_eq<3>{}, s), + s + ) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::scan_right(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), s, f), + MAKE_TUPLE( + f(ct_eq<0>{}, f(ct_eq<1>{}, f(ct_eq<2>{}, f(ct_eq<3>{}, f(ct_eq<4>{}, s))))), + f(ct_eq<1>{}, f(ct_eq<2>{}, f(ct_eq<3>{}, f(ct_eq<4>{}, s)))), + f(ct_eq<2>{}, f(ct_eq<3>{}, f(ct_eq<4>{}, s))), + f(ct_eq<3>{}, f(ct_eq<4>{}, s)), + f(ct_eq<4>{}, s), + s + ) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_SCANS_HPP diff --git a/src/boost/libs/hana/test/_include/auto/sequence.hpp b/src/boost/libs/hana/test/_include/auto/sequence.hpp new file mode 100644 index 000000000..280b7355b --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/sequence.hpp @@ -0,0 +1,13 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_SEQUENCE_HPP +#define BOOST_HANA_TEST_AUTO_SEQUENCE_HPP + +#include <boost/hana/concept/sequence.hpp> + + +static_assert(boost::hana::Sequence<TUPLE_TAG>::value, ""); + +#endif // !BOOST_HANA_TEST_AUTO_SEQUENCE_HPP diff --git a/src/boost/libs/hana/test/_include/auto/slice.hpp b/src/boost/libs/hana/test/_include/auto/slice.hpp new file mode 100644 index 000000000..3beb2ef0a --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/slice.hpp @@ -0,0 +1,182 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_SLICE_HPP +#define BOOST_HANA_TEST_AUTO_SLICE_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/range.hpp> +#include <boost/hana/slice.hpp> +#include <boost/hana/tuple.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> +#include <support/seq.hpp> + +#include <cstddef> + + +TestCase test_slice{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + constexpr auto foldable = ::seq; + + struct undefined { }; + + ////////////////////////////////////////////////////////////////////////// + // Test with arbitrary indices + ////////////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(), + foldable()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(undefined{}), + foldable()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(undefined{}, undefined{}), + foldable()), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(ct_eq<0>{}), + foldable(hana::size_c<0>)), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(ct_eq<0>{}, undefined{}), + foldable(hana::size_c<0>)), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(undefined{}, ct_eq<1>{}), + foldable(hana::size_c<1>)), + MAKE_TUPLE(ct_eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + foldable(hana::size_c<0>, hana::size_c<1>)), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + foldable(hana::size_c<1>, hana::size_c<0>)), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + foldable(hana::size_c<0>, hana::size_c<0>)), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + foldable(hana::size_c<1>, hana::size_c<1>)), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + foldable(hana::size_c<0>, hana::size_c<1>, hana::size_c<2>)), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + foldable(hana::size_c<0>, hana::size_c<2>, hana::size_c<1>)), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + foldable(hana::size_c<0>, hana::size_c<2>, hana::size_c<1>, hana::size_c<0>)), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + foldable(hana::size_c<0>, hana::size_c<2>, hana::size_c<1>, hana::size_c<0>, hana::size_c<1>)), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<2>{}, ct_eq<1>{}, ct_eq<0>{}, ct_eq<1>{}) + )); + + // Try with a tuple_c + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + hana::tuple_c<unsigned, 1, 3, 2>), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<3>{}, ct_eq<2>{}) + )); + + + + ////////////////////////////////////////////////////////////////////////// + // Test with a `range` (check the optimization for contiguous indices) + ////////////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(), + hana::range_c<std::size_t, 0, 0>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(undefined{}), + hana::range_c<std::size_t, 0, 0>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(undefined{}, undefined{}), + hana::range_c<std::size_t, 0, 0>), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(ct_eq<0>{}), + hana::range_c<std::size_t, 0, 1>), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(ct_eq<0>{}, undefined{}), + hana::range_c<std::size_t, 0, 1>), + MAKE_TUPLE(ct_eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(undefined{}, ct_eq<1>{}), + hana::range_c<std::size_t, 1, 2>), + MAKE_TUPLE(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(undefined{}, ct_eq<1>{}, undefined{}), + hana::range_c<std::size_t, 1, 2>), + MAKE_TUPLE(ct_eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + hana::range_c<std::size_t, 0, 2>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, undefined{}), + hana::range_c<std::size_t, 0, 2>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(undefined{}, ct_eq<1>{}, ct_eq<2>{}), + hana::range_c<std::size_t, 1, 3>), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::slice(MAKE_TUPLE(undefined{}, ct_eq<1>{}, ct_eq<2>{}, undefined{}), + hana::range_c<std::size_t, 1, 3>), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_SLICE_HPP diff --git a/src/boost/libs/hana/test/_include/auto/sort.hpp b/src/boost/libs/hana/test/_include/auto/sort.hpp new file mode 100644 index 000000000..398584fef --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/sort.hpp @@ -0,0 +1,111 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_SORT_HPP +#define BOOST_HANA_TEST_AUTO_SORT_HPP + +#include <boost/hana/all_of.hpp> +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/less.hpp> +#include <boost/hana/permutations.hpp> +#include <boost/hana/sort.hpp> +#include <boost/hana/transform.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> +#include <support/equivalence_class.hpp> + + +TestCase test_sort{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + using hana::test::ct_ord; + + // Test without a custom predicate + { + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::sort(MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::sort(MAKE_TUPLE(ct_ord<0>{})), + MAKE_TUPLE(ct_ord<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::sort(MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{})), + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::sort(MAKE_TUPLE(ct_ord<1>{}, ct_ord<0>{})), + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::sort(MAKE_TUPLE(ct_ord<1>{}, ct_ord<0>{}, ct_ord<4>{}, ct_ord<2>{})), + MAKE_TUPLE(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, ct_ord<4>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::sort(MAKE_TUPLE(ct_ord<1>{}, ct_ord<0>{}, ct_ord<-4>{}, ct_ord<2>{})), + MAKE_TUPLE(ct_ord<-4>{}, ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}) + )); + } + + // Test with a custom predicate + { + auto pred = [](auto x, auto y) { + return hana::less(x.unwrap, y.unwrap); + }; + auto a = [](auto z) { return ::equivalence_class(ct_eq<999>{}, z); }; + auto b = [](auto z) { return ::equivalence_class(ct_eq<888>{}, z); }; + + auto check = [=](auto ...sorted) { + auto perms = hana::transform( + hana::permutations(MAKE_TUPLE(a(sorted)...)), + hana::sort.by(pred) + ); + BOOST_HANA_CONSTANT_CHECK(hana::all_of(perms, [=](auto xs) { + return hana::equal(xs, MAKE_TUPLE(a(sorted)...)); + })); + }; + + check(); + check(ct_ord<1>{}); + check(ct_ord<1>{}, ct_ord<2>{}); + check(ct_ord<1>{}, ct_ord<2>{}, ct_ord<3>{}); + + // check stability + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::sort(MAKE_TUPLE(a(ct_ord<1>{}), b(ct_ord<1>{})), pred), + MAKE_TUPLE(a(ct_ord<1>{}), b(ct_ord<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::sort(MAKE_TUPLE(b(ct_ord<1>{}), a(ct_ord<1>{})), pred), + MAKE_TUPLE(b(ct_ord<1>{}), a(ct_ord<1>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::sort(MAKE_TUPLE(a(ct_ord<1>{}), b(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<2>{})), pred), + MAKE_TUPLE(a(ct_ord<1>{}), b(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<2>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::sort(MAKE_TUPLE(a(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<1>{}), b(ct_ord<2>{})), pred), + MAKE_TUPLE(a(ct_ord<1>{}), b(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<2>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::sort(MAKE_TUPLE(b(ct_ord<1>{}), a(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<2>{})), pred), + MAKE_TUPLE(b(ct_ord<1>{}), a(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<2>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::sort(MAKE_TUPLE(a(ct_ord<2>{}), b(ct_ord<1>{}), b(ct_ord<2>{}), a(ct_ord<1>{})), pred), + MAKE_TUPLE(b(ct_ord<1>{}), a(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<2>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::sort(MAKE_TUPLE(a(ct_ord<1>{}), a(ct_ord<3>{}), b(ct_ord<1>{}), a(ct_ord<2>{}), b(ct_ord<3>{})), pred), + MAKE_TUPLE(a(ct_ord<1>{}), b(ct_ord<1>{}), a(ct_ord<2>{}), a(ct_ord<3>{}), b(ct_ord<3>{})) + )); + } +}}; + +#endif // !BOOST_HANA_TEST_AUTO_SORT_HPP diff --git a/src/boost/libs/hana/test/_include/auto/span.hpp b/src/boost/libs/hana/test/_include/auto/span.hpp new file mode 100644 index 000000000..1a15d408b --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/span.hpp @@ -0,0 +1,84 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_SPAN_HPP +#define BOOST_HANA_TEST_AUTO_SPAN_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/span.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> +#include <support/minimal_product.hpp> + + +TestCase test_span{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + auto z = ct_eq<999>{}; + auto pair = ::minimal_product; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::span(MAKE_TUPLE(), hana::equal.to(z)), + pair(MAKE_TUPLE(), MAKE_TUPLE()) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::span(MAKE_TUPLE(ct_eq<0>{}), hana::equal.to(z)), + pair(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::span(MAKE_TUPLE(z), hana::equal.to(z)), + pair(MAKE_TUPLE(z), MAKE_TUPLE()) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::span(MAKE_TUPLE(ct_eq<0>{}, z), hana::equal.to(z)), + pair(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{}, z)) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::span(MAKE_TUPLE(z, ct_eq<0>{}), hana::equal.to(z)), + pair(MAKE_TUPLE(z), MAKE_TUPLE(ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::span(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::equal.to(z)), + pair(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::span(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(z)), + pair(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::span(MAKE_TUPLE(z, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(z)), + pair(MAKE_TUPLE(z), MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::span(MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<2>{}), hana::equal.to(z)), + pair(MAKE_TUPLE(), MAKE_TUPLE(ct_eq<0>{}, z, ct_eq<2>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::span(MAKE_TUPLE(z, z, ct_eq<2>{}), hana::equal.to(z)), + pair(MAKE_TUPLE(z, z), MAKE_TUPLE(ct_eq<2>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::span(MAKE_TUPLE(z, z, z), hana::equal.to(z)), + pair(MAKE_TUPLE(z, z, z), MAKE_TUPLE()) + )); + + // span.by + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::span.by(hana::equal.to(z), MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + hana::span(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(z)) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::span.by(hana::equal.to(z))(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + hana::span(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), hana::equal.to(z)) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_SPAN_HPP diff --git a/src/boost/libs/hana/test/_include/auto/take_back.hpp b/src/boost/libs/hana/test/_include/auto/take_back.hpp new file mode 100644 index 000000000..11a795e00 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/take_back.hpp @@ -0,0 +1,82 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_TAKE_BACK_HPP +#define BOOST_HANA_TEST_AUTO_TAKE_BACK_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/take_back.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> + + +TestCase test_take_back{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_back(MAKE_TUPLE(), hana::size_c<0>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_back(MAKE_TUPLE(), hana::size_c<1>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_back(MAKE_TUPLE(), hana::size_c<2>), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<2>), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_back(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<3>), + MAKE_TUPLE(ct_eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>), + MAKE_TUPLE(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<2>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<3>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_back(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::size_c<3>), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_back(MAKE_TUPLE( + ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, + ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}), + hana::size_c<5>), + MAKE_TUPLE(ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_TAKE_BACK_HPP diff --git a/src/boost/libs/hana/test/_include/auto/take_front.hpp b/src/boost/libs/hana/test/_include/auto/take_front.hpp new file mode 100644 index 000000000..5e9b67338 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/take_front.hpp @@ -0,0 +1,77 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_TAKE_FRONT_HPP +#define BOOST_HANA_TEST_AUTO_TAKE_FRONT_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/take_front.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> + + +TestCase test_take{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_front(MAKE_TUPLE(), hana::size_c<0>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_front(MAKE_TUPLE(), hana::size_c<1>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_front(MAKE_TUPLE(), hana::size_c<2>), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<0>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<1>), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<2>), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_front(MAKE_TUPLE(ct_eq<0>{}), hana::size_c<3>), + MAKE_TUPLE(ct_eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<0>), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<1>), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<2>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_front(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), hana::size_c<3>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_front(MAKE_TUPLE( + ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}, ct_eq<6>{}, + ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}, ct_eq<10>{}, ct_eq<11>{}, ct_eq<12>{}, ct_eq<13>{}), + hana::size_c<10>), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, + ct_eq<5>{}, ct_eq<6>{}, ct_eq<7>{}, ct_eq<8>{}, ct_eq<9>{}) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_TAKE_FRONT_HPP diff --git a/src/boost/libs/hana/test/_include/auto/take_while.hpp b/src/boost/libs/hana/test/_include/auto/take_while.hpp new file mode 100644 index 000000000..72d0b8b11 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/take_while.hpp @@ -0,0 +1,68 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_TAKE_WHILE_HPP +#define BOOST_HANA_TEST_AUTO_TAKE_WHILE_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/not_equal.hpp> +#include <boost/hana/take_while.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> + + +TestCase test_take_while{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + auto z = ct_eq<999>{}; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_while(MAKE_TUPLE(), hana::not_equal.to(z)), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_while(MAKE_TUPLE(ct_eq<1>{}), hana::not_equal.to(z)), + MAKE_TUPLE(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_while(MAKE_TUPLE(z), hana::not_equal.to(z)), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_while(MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), hana::not_equal.to(z)), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_while(MAKE_TUPLE(ct_eq<1>{}, z), hana::not_equal.to(z)), + MAKE_TUPLE(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_while(MAKE_TUPLE(z, ct_eq<2>{}), hana::not_equal.to(z)), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_while(MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), hana::not_equal.to(z)), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_while(MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, z), hana::not_equal.to(z)), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_while(MAKE_TUPLE(ct_eq<1>{}, z, ct_eq<3>{}), hana::not_equal.to(z)), + MAKE_TUPLE(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::take_while(MAKE_TUPLE(z, ct_eq<2>{}, ct_eq<3>{}), hana::not_equal.to(z)), + MAKE_TUPLE() + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_TAKE_WHILE_HPP diff --git a/src/boost/libs/hana/test/_include/auto/test_case.hpp b/src/boost/libs/hana/test/_include/auto/test_case.hpp new file mode 100644 index 000000000..03de19ac0 --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/test_case.hpp @@ -0,0 +1,13 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_TEST_CASE_HPP +#define BOOST_HANA_TEST_AUTO_TEST_CASE_HPP + +struct TestCase { + template <typename F> + explicit TestCase(F const& f) { f(); } +}; + +#endif // !BOOST_HANA_TEST_AUTO_TEST_CASE_HPP diff --git a/src/boost/libs/hana/test/_include/auto/transform.hpp b/src/boost/libs/hana/test/_include/auto/transform.hpp new file mode 100644 index 000000000..478d725ac --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/transform.hpp @@ -0,0 +1,74 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_TRANSFORM_HPP +#define BOOST_HANA_TEST_AUTO_TRANSFORM_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/transform.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> + + +TestCase test_transform{[] { + namespace hana = boost::hana; + using hana::test::ct_eq; + struct undefined { }; + constexpr hana::test::_injection<0> f{}; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::transform(MAKE_TUPLE(), undefined{}), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::transform(MAKE_TUPLE(ct_eq<1>{}), f), + MAKE_TUPLE(f(ct_eq<1>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::transform(MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), f), + MAKE_TUPLE(f(ct_eq<1>{}), f(ct_eq<2>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::transform(MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), f), + MAKE_TUPLE(f(ct_eq<1>{}), f(ct_eq<2>{}), f(ct_eq<3>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::transform(MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), f), + MAKE_TUPLE(f(ct_eq<1>{}), f(ct_eq<2>{}), f(ct_eq<3>{}), f(ct_eq<4>{})) + )); + +#ifndef MAKE_TUPLE_NO_CONSTEXPR + struct incr { + constexpr int operator()(int i) const { return i + 1; } + }; + + static_assert(hana::equal( + hana::transform(MAKE_TUPLE(1), incr{}), + MAKE_TUPLE(2) + ), ""); + + static_assert(hana::equal( + hana::transform(MAKE_TUPLE(1, 2), incr{}), + MAKE_TUPLE(2, 3) + ), ""); + + static_assert(hana::equal( + hana::transform(MAKE_TUPLE(1, 2, 3), incr{}), + MAKE_TUPLE(2, 3, 4) + ), ""); + + static_assert(hana::equal( + hana::transform(MAKE_TUPLE(1, 2, 3, 4), incr{}), + MAKE_TUPLE(2, 3, 4, 5) + ), ""); +#endif +}}; + +#endif // !BOOST_HANA_TEST_AUTO_TRANSFORM_HPP diff --git a/src/boost/libs/hana/test/_include/auto/unfolds.hpp b/src/boost/libs/hana/test/_include/auto/unfolds.hpp new file mode 100644 index 000000000..afa01d3fc --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/unfolds.hpp @@ -0,0 +1,170 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_UNFOLDS_HPP +#define BOOST_HANA_TEST_AUTO_UNFOLDS_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/fold_left.hpp> +#include <boost/hana/fold_right.hpp> +#include <boost/hana/if.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/optional.hpp> +#include <boost/hana/plus.hpp> +#include <boost/hana/unfold_left.hpp> +#include <boost/hana/unfold_right.hpp> + +#include <laws/base.hpp> +#include <support/minimal_product.hpp> +#include "test_case.hpp" + + +TestCase test_unfold_left{[]{ + namespace hana = boost::hana; + + hana::test::_injection<0> f{}; + auto stop_at = [=](auto stop) { + return [=](auto x) { + return hana::if_(hana::equal(stop, x), + hana::nothing, + hana::just(::minimal_product(x + hana::int_c<1>, f(x))) + ); + }; + }; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_left<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<0>)), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_left<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<1>)), + MAKE_TUPLE(f(hana::int_c<0>)) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_left<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<2>)), + MAKE_TUPLE(f(hana::int_c<1>), f(hana::int_c<0>)) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_left<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<3>)), + MAKE_TUPLE(f(hana::int_c<2>), f(hana::int_c<1>), f(hana::int_c<0>)) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_left<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<4>)), + MAKE_TUPLE(f(hana::int_c<3>), f(hana::int_c<2>), f(hana::int_c<1>), f(hana::int_c<0>)) + )); +}}; + + +TestCase test_unfold_right{[]{ + namespace hana = boost::hana; + + hana::test::_injection<0> f{}; + auto stop_at = [=](auto stop) { + return [=](auto x) { + return hana::if_(hana::equal(stop, x), + hana::nothing, + hana::just(::minimal_product(f(x), x + hana::int_c<1>)) + ); + }; + }; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_right<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<0>)), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_right<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<1>)), + MAKE_TUPLE(f(hana::int_c<0>)) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_right<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<2>)), + MAKE_TUPLE(f(hana::int_c<0>), f(hana::int_c<1>)) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_right<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<3>)), + MAKE_TUPLE(f(hana::int_c<0>), f(hana::int_c<1>), f(hana::int_c<2>)) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_right<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<4>)), + MAKE_TUPLE(f(hana::int_c<0>), f(hana::int_c<1>), f(hana::int_c<2>), f(hana::int_c<3>)) + )); +}}; + +// Make sure unfolds can be reversed under certain conditions. +TestCase test_unfold_undo{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + auto z = ct_eq<999>{}; + auto f = ::minimal_product; + auto g = [=](auto k) { + return hana::if_(hana::equal(k, z), + hana::nothing, + hana::just(k) + ); + }; + + // Make sure the special conditions are met + BOOST_HANA_CONSTANT_CHECK(hana::equal( + g(z), + hana::nothing + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + g(f(ct_eq<0>{}, z)), + hana::just(::minimal_product(ct_eq<0>{}, z)) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + g(f(z, ct_eq<0>{})), + hana::just(::minimal_product(z, ct_eq<0>{})) + )); + + // Make sure the reversing works + { + auto xs = MAKE_TUPLE(); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_left<TUPLE_TAG>(hana::fold_left(xs, z, f), g), + xs + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_right<TUPLE_TAG>(hana::fold_right(xs, z, f), g), + xs + )); + } + { + auto xs = MAKE_TUPLE(ct_eq<0>{}); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_left<TUPLE_TAG>(hana::fold_left(xs, z, f), g), + xs + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_right<TUPLE_TAG>(hana::fold_right(xs, z, f), g), + xs + )); + } + { + auto xs = MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_left<TUPLE_TAG>(hana::fold_left(xs, z, f), g), + xs + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_right<TUPLE_TAG>(hana::fold_right(xs, z, f), g), + xs + )); + } + { + auto xs = MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_left<TUPLE_TAG>(hana::fold_left(xs, z, f), g), + xs + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unfold_right<TUPLE_TAG>(hana::fold_right(xs, z, f), g), + xs + )); + } +}}; + +#endif // !BOOST_HANA_TEST_AUTO_UNFOLDS_HPP diff --git a/src/boost/libs/hana/test/_include/auto/unique.hpp b/src/boost/libs/hana/test/_include/auto/unique.hpp new file mode 100644 index 000000000..8ef7076fb --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/unique.hpp @@ -0,0 +1,158 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_UNIQUE_HPP +#define BOOST_HANA_TEST_AUTO_UNIQUE_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/unique.hpp> + +#include "test_case.hpp" +#include <laws/base.hpp> +#include <support/equivalence_class.hpp> + + +TestCase test_unique{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE()), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(ct_eq<0>{})), + MAKE_TUPLE(ct_eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{})), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<0>{})), + MAKE_TUPLE(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(ct_eq<0>{}, ct_eq<0>{}, ct_eq<1>{})), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<0>{})), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<1>{})), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE( + ct_eq<0>{}, ct_eq<0>{}, + ct_eq<1>{}, + ct_eq<2>{}, ct_eq<2>{}, ct_eq<2>{}, + ct_eq<3>{}, ct_eq<3>{}, ct_eq<3>{}, + ct_eq<0>{})), + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<0>{}) + )); +}}; + +TestCase test_unique_by{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + struct undefined { }; + + auto a = [](auto z) { return ::equivalence_class(ct_eq<999>{}, z); }; + auto b = [](auto z) { return ::equivalence_class(ct_eq<888>{}, z); }; + auto c = [](auto z) { return ::equivalence_class(ct_eq<777>{}, z); }; + + auto pred = [](auto x, auto y) { + return hana::equal(x.unwrap, y.unwrap); + }; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(), undefined{}), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(a(ct_eq<0>{})), pred), + MAKE_TUPLE(a(ct_eq<0>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{})), pred), + MAKE_TUPLE(a(ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{})), pred), + MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{}), c(ct_eq<0>{})), pred), + MAKE_TUPLE(a(ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<0>{}), c(ct_eq<1>{})), pred), + MAKE_TUPLE(a(ct_eq<0>{}), c(ct_eq<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<0>{})), pred), + MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<1>{}), b(ct_eq<1>{})), pred), + MAKE_TUPLE(a(ct_eq<0>{}), b(ct_eq<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<2>{})), pred), + MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<2>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique(MAKE_TUPLE( + a(ct_eq<0>{}), b(ct_eq<0>{}), + a(ct_eq<1>{}), + a(ct_eq<2>{}), b(ct_eq<2>{}), c(ct_eq<2>{}), + a(ct_eq<3>{}), b(ct_eq<3>{}), c(ct_eq<3>{}), + a(ct_eq<0>{})), pred), + MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<2>{}), a(ct_eq<3>{}), a(ct_eq<0>{})) + )); + + // unique.by + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique.by(pred, MAKE_TUPLE( + a(ct_eq<0>{}), b(ct_eq<0>{}), + a(ct_eq<1>{}), + a(ct_eq<2>{}), b(ct_eq<2>{}), c(ct_eq<2>{}), + a(ct_eq<3>{}), b(ct_eq<3>{}), c(ct_eq<3>{}), + a(ct_eq<0>{}))), + MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<2>{}), a(ct_eq<3>{}), a(ct_eq<0>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unique.by(pred)(MAKE_TUPLE( + a(ct_eq<0>{}), b(ct_eq<0>{}), + a(ct_eq<1>{}), + a(ct_eq<2>{}), b(ct_eq<2>{}), c(ct_eq<2>{}), + a(ct_eq<3>{}), b(ct_eq<3>{}), c(ct_eq<3>{}), + a(ct_eq<0>{}))), + MAKE_TUPLE(a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<2>{}), a(ct_eq<3>{}), a(ct_eq<0>{})) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_UNIQUE_HPP diff --git a/src/boost/libs/hana/test/_include/auto/zips.hpp b/src/boost/libs/hana/test/_include/auto/zips.hpp new file mode 100644 index 000000000..3d129c90d --- /dev/null +++ b/src/boost/libs/hana/test/_include/auto/zips.hpp @@ -0,0 +1,342 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_AUTO_ZIPS_HPP +#define BOOST_HANA_TEST_AUTO_ZIPS_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/zip.hpp> +#include <boost/hana/zip_shortest.hpp> +#include <boost/hana/zip_shortest_with.hpp> +#include <boost/hana/zip_with.hpp> + +#include <laws/base.hpp> +#include "test_case.hpp" + + +TestCase test_zip_shortest_with{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + hana::test::_injection<0> f{}; + auto zip = hana::zip_shortest_with; + struct undefined { }; + + // zip 1 + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(undefined{}, MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(f, MAKE_TUPLE(ct_eq<0>{})), + MAKE_TUPLE(f(ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(f, MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(f, MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{})) + )); + + // zip 2 + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(undefined{}, MAKE_TUPLE(), MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(undefined{}, MAKE_TUPLE(undefined{}), MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(undefined{}, MAKE_TUPLE(), MAKE_TUPLE(undefined{})), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(f, MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<-1>{})), + MAKE_TUPLE(f(ct_eq<1>{}, ct_eq<-1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(f, MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), MAKE_TUPLE(ct_eq<-1>{})), + MAKE_TUPLE(f(ct_eq<1>{}, ct_eq<-1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(f, MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{})), + MAKE_TUPLE(f(ct_eq<1>{}, ct_eq<-1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(f, MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{})), + MAKE_TUPLE(f(ct_eq<1>{}, ct_eq<-1>{}), f(ct_eq<2>{}, ct_eq<-2>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(f, MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), + MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<-3>{})), + MAKE_TUPLE(f(ct_eq<1>{}, ct_eq<-1>{}), + f(ct_eq<2>{}, ct_eq<-2>{}), + f(ct_eq<3>{}, ct_eq<-3>{})) + )); + + // zip 3 + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(undefined{}, MAKE_TUPLE(), MAKE_TUPLE(), MAKE_TUPLE()), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(undefined{}, MAKE_TUPLE(undefined{}), MAKE_TUPLE(), MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(undefined{}, MAKE_TUPLE(), MAKE_TUPLE(undefined{}), MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(undefined{}, MAKE_TUPLE(), MAKE_TUPLE(), MAKE_TUPLE(undefined{})), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(undefined{}, MAKE_TUPLE(), MAKE_TUPLE(undefined{}), MAKE_TUPLE(undefined{})), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(undefined{}, MAKE_TUPLE(undefined{}), MAKE_TUPLE(), MAKE_TUPLE(undefined{})), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(undefined{}, MAKE_TUPLE(undefined{}), MAKE_TUPLE(undefined{}), MAKE_TUPLE()), + MAKE_TUPLE() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(f, MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<2>{})), + MAKE_TUPLE(f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})) + )); + + // zip 4 + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(f, + MAKE_TUPLE(ct_eq<11>{}, ct_eq<12>{}, ct_eq<13>{}, ct_eq<14>{}), + MAKE_TUPLE(ct_eq<21>{}, ct_eq<22>{}, ct_eq<23>{}), + MAKE_TUPLE(ct_eq<31>{}, ct_eq<32>{}, ct_eq<33>{}, ct_eq<34>{}), + MAKE_TUPLE(ct_eq<41>{}, ct_eq<42>{}, ct_eq<43>{}, ct_eq<44>{}, ct_eq<45>{}) + ), + MAKE_TUPLE( + f(ct_eq<11>{}, ct_eq<21>{}, ct_eq<31>{}, ct_eq<41>{}), + f(ct_eq<12>{}, ct_eq<22>{}, ct_eq<32>{}, ct_eq<42>{}), + f(ct_eq<13>{}, ct_eq<23>{}, ct_eq<33>{}, ct_eq<43>{}) + ) + )); + + // zip 5 + BOOST_HANA_CONSTANT_CHECK(hana::equal( + zip(f, + MAKE_TUPLE(ct_eq<11>{}, ct_eq<12>{}, ct_eq<13>{}, ct_eq<14>{}), + MAKE_TUPLE(ct_eq<21>{}, ct_eq<22>{}, ct_eq<23>{}, ct_eq<24>{}, ct_eq<25>{}), + MAKE_TUPLE(ct_eq<31>{}, ct_eq<32>{}, ct_eq<33>{}, ct_eq<34>{}), + MAKE_TUPLE(ct_eq<41>{}, ct_eq<42>{}, ct_eq<43>{}, ct_eq<44>{}, ct_eq<45>{}, ct_eq<46>{}), + MAKE_TUPLE(ct_eq<51>{}, ct_eq<52>{}, ct_eq<53>{}, ct_eq<54>{}, ct_eq<55>{}) + ), + MAKE_TUPLE( + f(ct_eq<11>{}, ct_eq<21>{}, ct_eq<31>{}, ct_eq<41>{}, ct_eq<51>{}), + f(ct_eq<12>{}, ct_eq<22>{}, ct_eq<32>{}, ct_eq<42>{}, ct_eq<52>{}), + f(ct_eq<13>{}, ct_eq<23>{}, ct_eq<33>{}, ct_eq<43>{}, ct_eq<53>{}), + f(ct_eq<14>{}, ct_eq<24>{}, ct_eq<34>{}, ct_eq<44>{}, ct_eq<54>{}) + ) + )); +}}; + +TestCase test_zip_with{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + hana::test::_injection<0> f{}; + struct undefined { }; + + // zip 1 + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_with(undefined{}, MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_with(f, MAKE_TUPLE(ct_eq<0>{})), + MAKE_TUPLE(f(ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_with(f, MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_with(f, MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + MAKE_TUPLE(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{})) + )); + + // zip 2 + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_with(undefined{}, MAKE_TUPLE(), MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_with(f, MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<-1>{})), + MAKE_TUPLE(f(ct_eq<1>{}, ct_eq<-1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_with(f, MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}), MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{})), + MAKE_TUPLE(f(ct_eq<1>{}, ct_eq<-1>{}), f(ct_eq<2>{}, ct_eq<-2>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_with(f, + MAKE_TUPLE(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), + MAKE_TUPLE(ct_eq<-1>{}, ct_eq<-2>{}, ct_eq<-3>{})), + MAKE_TUPLE( + f(ct_eq<1>{}, ct_eq<-1>{}), + f(ct_eq<2>{}, ct_eq<-2>{}), + f(ct_eq<3>{}, ct_eq<-3>{})) + )); + + // zip 3 + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_with(undefined{}, MAKE_TUPLE(), MAKE_TUPLE(), MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_with(f, MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<2>{})), + MAKE_TUPLE(f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_with(f, + MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}), + MAKE_TUPLE(ct_eq<2>{}, ct_eq<3>{}), + MAKE_TUPLE(ct_eq<4>{}, ct_eq<5>{}) + ), + MAKE_TUPLE( + f(ct_eq<0>{}, ct_eq<2>{}, ct_eq<4>{}), + f(ct_eq<1>{}, ct_eq<3>{}, ct_eq<5>{}) + ) + )); + + // zip 4 + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_with(f, + MAKE_TUPLE(ct_eq<11>{}, ct_eq<12>{}, ct_eq<13>{}), + MAKE_TUPLE(ct_eq<21>{}, ct_eq<22>{}, ct_eq<23>{}), + MAKE_TUPLE(ct_eq<31>{}, ct_eq<32>{}, ct_eq<33>{}), + MAKE_TUPLE(ct_eq<41>{}, ct_eq<42>{}, ct_eq<43>{}) + ), + MAKE_TUPLE( + f(ct_eq<11>{}, ct_eq<21>{}, ct_eq<31>{}, ct_eq<41>{}), + f(ct_eq<12>{}, ct_eq<22>{}, ct_eq<32>{}, ct_eq<42>{}), + f(ct_eq<13>{}, ct_eq<23>{}, ct_eq<33>{}, ct_eq<43>{}) + ) + )); + + // zip 5 + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_with(f, + MAKE_TUPLE(ct_eq<11>{}, ct_eq<12>{}, ct_eq<13>{}, ct_eq<14>{}), + MAKE_TUPLE(ct_eq<21>{}, ct_eq<22>{}, ct_eq<23>{}, ct_eq<24>{}), + MAKE_TUPLE(ct_eq<31>{}, ct_eq<32>{}, ct_eq<33>{}, ct_eq<34>{}), + MAKE_TUPLE(ct_eq<41>{}, ct_eq<42>{}, ct_eq<43>{}, ct_eq<44>{}), + MAKE_TUPLE(ct_eq<51>{}, ct_eq<52>{}, ct_eq<53>{}, ct_eq<54>{}) + ), + MAKE_TUPLE( + f(ct_eq<11>{}, ct_eq<21>{}, ct_eq<31>{}, ct_eq<41>{}, ct_eq<51>{}), + f(ct_eq<12>{}, ct_eq<22>{}, ct_eq<32>{}, ct_eq<42>{}, ct_eq<52>{}), + f(ct_eq<13>{}, ct_eq<23>{}, ct_eq<33>{}, ct_eq<43>{}, ct_eq<53>{}), + f(ct_eq<14>{}, ct_eq<24>{}, ct_eq<34>{}, ct_eq<44>{}, ct_eq<54>{}) + ) + )); +}}; + +TestCase test_zip{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip(MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip(MAKE_TUPLE(ct_eq<0>{})), + MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<2>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip(MAKE_TUPLE(), MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip(MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{})), + MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip(MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<2>{})), + MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip(MAKE_TUPLE(ct_eq<0>{}, ct_eq<3>{}), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<4>{}), + MAKE_TUPLE(ct_eq<2>{}, ct_eq<5>{})), + MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + MAKE_TUPLE(ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{})) + )); +}}; + +TestCase test_zip_shortest{[]{ + namespace hana = boost::hana; + using hana::test::ct_eq; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_shortest(MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_shortest(MAKE_TUPLE(ct_eq<0>{})), + MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_shortest(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})), + MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_shortest(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{}), MAKE_TUPLE(ct_eq<2>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_shortest(MAKE_TUPLE(), MAKE_TUPLE()), + MAKE_TUPLE() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_shortest(MAKE_TUPLE(ct_eq<0>{}), MAKE_TUPLE(ct_eq<1>{})), + MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_shortest(MAKE_TUPLE(ct_eq<0>{}), + MAKE_TUPLE(ct_eq<1>{}), + MAKE_TUPLE(ct_eq<2>{})), + MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::zip_shortest(MAKE_TUPLE(ct_eq<0>{}, ct_eq<3>{}), + MAKE_TUPLE(ct_eq<1>{}, ct_eq<4>{}), + MAKE_TUPLE(ct_eq<2>{}, ct_eq<5>{}, ct_eq<8>{})), + MAKE_TUPLE(MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), + MAKE_TUPLE(ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{})) + )); +}}; + +#endif // !BOOST_HANA_TEST_AUTO_ZIPS_HPP diff --git a/src/boost/libs/hana/test/_include/laws/applicative.hpp b/src/boost/libs/hana/test/_include/laws/applicative.hpp new file mode 100644 index 000000000..a7de47b9d --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/applicative.hpp @@ -0,0 +1,196 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_APPLICATIVE_HPP +#define BOOST_HANA_TEST_LAWS_APPLICATIVE_HPP + +#include <boost/hana/ap.hpp> +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/concept/applicative.hpp> +#include <boost/hana/concept/comparable.hpp> +#include <boost/hana/core/make.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/for_each.hpp> +#include <boost/hana/functional/capture.hpp> +#include <boost/hana/functional/compose.hpp> +#include <boost/hana/functional/curry.hpp> +#include <boost/hana/functional/id.hpp> +#include <boost/hana/functional/placeholder.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/lift.hpp> +#include <boost/hana/take_front.hpp> +#include <boost/hana/transform.hpp> + +#include <laws/base.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename F, typename = when<true>> + struct TestApplicative : TestApplicative<F, laws> { + using TestApplicative<F, laws>::TestApplicative; + }; + + template <typename F> + struct TestApplicative<F, laws> { + template <typename Applicatives> + TestApplicative(Applicatives applicatives) { + hana::for_each(applicatives, [](auto a) { + static_assert(Applicative<decltype(a)>{}, ""); + }); + + auto functions1 = hana::take_front( + hana::transform(applicatives, [](auto xs) { + return hana::transform(xs, hana::curry<2>(test::_injection<0>{})); + }), hana::int_c<3>); + + auto functions2 = hana::take_front( + hana::transform(applicatives, [](auto xs) { + return hana::transform(xs, hana::curry<2>(test::_injection<1>{})); + }), hana::int_c<3>); + + // identity + { + hana::for_each(applicatives, [](auto xs) { + BOOST_HANA_CHECK(hana::equal( + hana::ap(hana::lift<F>(hana::id), xs), + xs + )); + }); + } + + // composition + { + hana::for_each(applicatives, hana::capture(functions1, functions2)( + [](auto functions1, auto functions2, auto xs) { + hana::for_each(functions1, hana::capture(functions2, xs)( + [](auto functions2, auto xs, auto fs) { + hana::for_each(functions2, hana::capture(xs, fs)( + [](auto xs, auto fs, auto gs) { + BOOST_HANA_CHECK(hana::equal( + hana::ap(hana::ap(hana::lift<F>(compose), fs, gs), xs), + hana::ap(fs, hana::ap(gs, xs)) + )); + }));}));})); + } + + // homomorphism + { + test::_injection<0> f{}; + test::ct_eq<3> x{}; + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(hana::lift<F>(f), hana::lift<F>(x)), + hana::lift<F>(f(x)) + )); + } + + // interchange + { + hana::for_each(functions1, [](auto fs) { + test::ct_eq<4> x{}; + BOOST_HANA_CHECK(hana::equal( + hana::ap(fs, hana::lift<F>(x)), + hana::ap(hana::lift<F>(hana::_(x)), fs) + )); + }); + } + + // definition of transform + { + hana::for_each(applicatives, [](auto xs) { + test::_injection<0> f{}; + BOOST_HANA_CHECK(hana::equal( + hana::transform(xs, f), + hana::ap(hana::lift<F>(f), xs) + )); + }); + } + } + }; + + template <typename S> + struct TestApplicative<S, when<Sequence<S>::value>> + : TestApplicative<S, laws> + { + template <typename Applicatives> + TestApplicative(Applicatives applicatives) + : TestApplicative<S, laws>{applicatives} + { + _injection<0> f{}; + _injection<1> g{}; + using test::ct_eq; + constexpr auto list = make<S>; + + ////////////////////////////////////////////////////////////////// + // ap + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(list(), list()), + list() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(list(), list(ct_eq<0>{})), + list() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(list(), list(ct_eq<0>{}, ct_eq<1>{})), + list() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(list(), list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(list(f), list()), + list() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(list(f), list(ct_eq<0>{})), + list(f(ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(list(f), list(ct_eq<0>{}, ct_eq<1>{})), + list(f(ct_eq<0>{}), f(ct_eq<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(list(f), list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + list(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(list(f, g), list()), + list() + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(list(f, g), list(ct_eq<0>{})), + list(f(ct_eq<0>{}), g(ct_eq<0>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(list(f, g), list(ct_eq<0>{}, ct_eq<1>{})), + list(f(ct_eq<0>{}), f(ct_eq<1>{}), g(ct_eq<0>{}), g(ct_eq<1>{})) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(list(f, g), list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + list(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{}), + g(ct_eq<0>{}), g(ct_eq<1>{}), g(ct_eq<2>{})) + )); + + ////////////////////////////////////////////////////////////////// + // lift + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(hana::equal( + lift<S>(ct_eq<0>{}), + list(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + lift<S>(ct_eq<1>{}), + list(ct_eq<1>{}) + )); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_APPLICATIVE_HPP diff --git a/src/boost/libs/hana/test/_include/laws/base.hpp b/src/boost/libs/hana/test/_include/laws/base.hpp new file mode 100644 index 000000000..0f421b8ae --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/base.hpp @@ -0,0 +1,369 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_BASE_HPP +#define BOOST_HANA_TEST_LAWS_BASE_HPP + +#include <boost/hana/and.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/detail/wrong.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/eval_if.hpp> +#include <boost/hana/for_each.hpp> +#include <boost/hana/functional/compose.hpp> +#include <boost/hana/functional/infix.hpp> +#include <boost/hana/functional/partial.hpp> +#include <boost/hana/fwd/concept/integral_constant.hpp> +#include <boost/hana/fwd/core/to.hpp> +#include <boost/hana/fwd/less.hpp> +#include <boost/hana/not.hpp> +#include <boost/hana/or.hpp> +#include <boost/hana/tuple.hpp> + +#include <support/tracked.hpp> + +#include <type_traits> +#include <utility> + + +namespace boost { namespace hana { + ////////////////////////////////////////////////////////////////////////// + // Misc + ////////////////////////////////////////////////////////////////////////// + namespace test { + struct laws; + + template <int i> + struct for_each_n_t { + static_assert(i > 0, "can't use for_each_n with i < 0"); + + template <typename Xs, typename F> + constexpr auto operator()(Xs const& xs, F const& f) const { + hana::for_each(xs, + hana::compose( + hana::partial(for_each_n_t<i - 1>{}, xs), + hana::partial(hana::partial, f) + ) + ); + } + }; + + template <> + struct for_each_n_t<1> { + template <typename Xs, typename F> + constexpr auto operator()(Xs const& xs, F const& f) const { + hana::for_each(xs, f); + } + }; + + template <int i> + constexpr for_each_n_t<i> for_each_n{}; + + auto foreach = hana::for_each; + constexpr auto foreach3 = for_each_n<3>; + constexpr auto foreach2 = for_each_n<2>; + + struct implies_t { + template <typename P, typename Q> + constexpr decltype(auto) operator()(P&& p, Q&& q) const { + return hana::or_(hana::not_(static_cast<P&&>(p)), + static_cast<Q&&>(q)); + } + }; + constexpr auto implies = hana::infix(implies_t{}); + + struct iff_t { + template <typename P, typename Q> + constexpr decltype(auto) operator()(P&& p, Q&& q) const { + return hana::and_(implies(p, q), implies(q, p)); + } + }; + constexpr auto iff = hana::infix(iff_t{}); + + template <typename Cond, typename F> + constexpr decltype(auto) only_when_(Cond cond, F f) { + return hana::eval_if(cond, f, [](auto){ }); + } + + // A type with a constructor that must not be instantiated. + // This is to make sure we don't instantiate something else than + // the copy-constructor of the elements inside a container when we + // copy the container. + struct trap_construct { + trap_construct() = default; + trap_construct(trap_construct const&) = default; +#ifndef BOOST_HANA_WORKAROUND_MSVC_MULTIPLECTOR_106654 + trap_construct(trap_construct&) = default; +#endif + trap_construct(trap_construct&&) = default; + + template <typename X> + trap_construct(X&&) { + static_assert(detail::wrong<X>{}, + "this constructor must not be instantiated"); + } + }; + + // A move-only type. Useful for testing containers. + struct move_only { + move_only() = default; + move_only(move_only const&) = delete; + move_only(move_only&&) = default; + }; + + ////////////////////////////////////////////////////////////////////// + // InjectionResult + ////////////////////////////////////////////////////////////////////// + struct InjectionResult { }; + + template <int i, typename ...X> + struct injection_result { + using hana_tag = InjectionResult; + static constexpr int injection_id = i; + hana::tuple<X...> args; + Tracked tracker; + + template <typename ...Y, typename = decltype(tuple<X...>{std::declval<Y>()...})> + constexpr explicit injection_result(Y&& ...y) + : args{static_cast<Y&&>(y)...}, tracker{i} + { } + }; + + //! A monotonic injective function. + //! + //! This is used in the unit tests, where we often just need a function + //! which preserves equality and order, but which also satisfies the + //! following law for all `Injection`s `f` and `g`: + //! @code + //! f(x) == g(x) if and only if f === g + //! @endcode + //! where `===` means _was created by the same call to `injection`_. + //! This allows creating several such functions in the unit tests while + //! conserving precious information such as the fact that + //! `f(g(x)) != g(f(x))`. + template <int i> + struct _injection { + template <typename ...X> + constexpr auto operator()(X&& ...x) const { + return injection_result<i, + typename std::decay<X>::type... + >{static_cast<X&&>(x)...}; + } + }; + } // end namespace test + + template <> + struct equal_impl<test::InjectionResult, test::InjectionResult> { + template <typename X, typename Y> + static constexpr auto apply(X x, Y y) { + return hana::and_( + hana::bool_c<X::injection_id == Y::injection_id>, + hana::equal(x.args, y.args) + ); + } + }; + + template <> + struct less_impl<test::InjectionResult, test::InjectionResult> { + template <typename X, typename Y> + static constexpr auto apply(X x, Y y) { + static_assert(X::injection_id == Y::injection_id, + "can't order the result of two different injections"); + return hana::less(x.args, y.args); + } + }; + + + ////////////////////////////////////////////////////////////////////////// + // Integer + ////////////////////////////////////////////////////////////////////////// + namespace test { + enum class Policy : int { + // One of those is mandatory + Constant = 1 << 0 + , Constexpr = 1 << 1 + , Runtime = 1 << 2 + + // Those are optional + , Tracked = 1 << 3 + , Comparable = 1 << 4 + , Orderable = 1 << 5 + }; + + constexpr bool operator&&(Policy a, Policy b) { + return static_cast<int>(a) && static_cast<int>(b); + } + + constexpr bool operator&&(Policy a, bool b) { + return static_cast<int>(a) && b; + } + + constexpr bool operator&&(bool a, Policy b) { + return a && static_cast<int>(b); + } + + constexpr bool operator||(Policy a, Policy b) { + return static_cast<int>(a) || static_cast<int>(b); + } + + constexpr bool operator||(Policy a, bool b) { + return static_cast<int>(a) || b; + } + + constexpr bool operator||(bool a, Policy b) { + return a || static_cast<int>(b); + } + + constexpr bool operator!(Policy a) { + return !static_cast<int>(a); + } + + constexpr Policy operator|(Policy a, Policy b) { + return static_cast<Policy>(static_cast<int>(a) | static_cast<int>(b)); + } + + constexpr Policy operator&(Policy a, Policy b) { + return static_cast<Policy>(static_cast<int>(a) & static_cast<int>(b)); + } + + template <Policy policy, typename = void> + struct Integer { }; + + template <Policy policy> + struct Integer<policy, std::enable_if_t<!!(policy & Policy::Constant)>> { + using value_type = int; + }; + + template <int i, Policy policy, typename = void> + struct integer { + static_assert( + !!(policy & (Policy::Constant | Policy::Constexpr | Policy::Runtime)) + , "You must choose at least one of Constant, Constexpr and Runtime."); + + static constexpr int value = i; + constexpr operator int() const { return value; } + using hana_tag = Integer<policy>; + Tracked tracker{i}; + }; + + template <int i, Policy policy> + struct integer <i, policy, std::enable_if_t<!!(policy & Policy::Constexpr)>> { + static constexpr int value = i; + constexpr operator int() const { return value; } + using hana_tag = Integer<policy>; + }; + + template <int i> + struct eq : integer<i, Policy::Comparable | Policy::Runtime> { }; + + template <int i> + struct ct_eq : integer<i, Policy::Comparable | Policy::Constant> { }; + + template <int i> + struct cx_eq : integer<i, Policy::Comparable | Policy::Constexpr> { }; + + template <int i> + struct ord : integer<i, Policy::Orderable | Policy::Runtime> { }; + + template <int i> + struct ct_ord : integer<i, Policy::Orderable | Policy::Constant> { }; + + template <int i> + struct cx_ord : integer<i, Policy::Orderable | Policy::Constexpr> { }; + + template <int i> + struct _constant + : integer<i, Policy::Constant | Policy::Comparable | Policy::Orderable> + { }; + } + + ////////////////////////////////////////////////////////////////////////// + // Model of Constant/IntegralConstant + ////////////////////////////////////////////////////////////////////////// + template <test::Policy policy> + struct IntegralConstant<test::Integer<policy>> { + static constexpr bool value = static_cast<bool>(policy & test::Policy::Constant); + }; + + template <test::Policy policy, typename C> + struct to_impl<test::Integer<policy>, C, when< + (policy & test::Policy::Constant) && + hana::IntegralConstant<C>::value + >> + : embedding<is_embedded<typename C::value_type, int>::value> + { + template <typename N> + static constexpr auto apply(N const&) { + return test::integer<N::value, policy>{}; + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Model of Comparable + ////////////////////////////////////////////////////////////////////////// + template <test::Policy p1, test::Policy p2> + struct equal_impl<test::Integer<p1>, test::Integer<p2>, when< + // both Comparable or Orderable + (p1 & (test::Policy::Comparable | test::Policy::Orderable)) && + (p2 & (test::Policy::Comparable | test::Policy::Orderable)) && + + // one Constexpr and the other Constant, or both Constexpr + (((p1 & test::Policy::Constant) && (p2 & test::Policy::Constexpr)) || + ((p1 & test::Policy::Constexpr) && (p2 & test::Policy::Constant)) || + ((p1 & test::Policy::Constexpr) && (p2 & test::Policy::Constexpr))) + >> { + template <typename X, typename Y> + static constexpr bool apply(X const&, Y const&) + { return X::value == Y::value; } + }; + + template <test::Policy p1, test::Policy p2> + struct equal_impl<test::Integer<p1>, test::Integer<p2>, when< + // both Comparable or Orderable + (p1 & (test::Policy::Comparable | test::Policy::Orderable)) && + (p2 & (test::Policy::Comparable | test::Policy::Orderable)) && + + // either one is Runtime + ((p1 & test::Policy::Runtime) || (p2 & test::Policy::Runtime)) + >> { + template <typename X, typename Y> + static bool apply(X const&, Y const&) + { return X::value == Y::value; } + }; + + + ////////////////////////////////////////////////////////////////////////// + // Model of Orderable + ////////////////////////////////////////////////////////////////////////// + template <test::Policy p1, test::Policy p2> + struct less_impl<test::Integer<p1>, test::Integer<p2>, when< + // both Orderable + (p1 & test::Policy::Orderable) && (p2 & test::Policy::Orderable) && + + // one Constexpr and the other Constant, or both Constexpr + (((p1 & test::Policy::Constant) && (p2 & test::Policy::Constexpr)) || + ((p1 & test::Policy::Constexpr) && (p2 & test::Policy::Constant)) || + ((p1 & test::Policy::Constexpr) && (p2 & test::Policy::Constexpr))) + >> { + template <typename X, typename Y> + static constexpr bool apply(X const&, Y const&) + { return X::value < Y::value; } + }; + + template <test::Policy p1, test::Policy p2> + struct less_impl<test::Integer<p1>, test::Integer<p2>, when< + // both Orderable + (p1 & test::Policy::Orderable) && (p2 & test::Policy::Orderable) && + + // either one is Runtime + ((p1 & test::Policy::Runtime) || (p2 & test::Policy::Runtime)) + >> { + template <typename X, typename Y> + static bool apply(X const&, Y const&) + { return X::value < Y::value; } + }; +}} // end namespace boost::hana + +#endif // !BOOST_HANA_TEST_LAWS_BASE_HPP diff --git a/src/boost/libs/hana/test/_include/laws/comonad.hpp b/src/boost/libs/hana/test/_include/laws/comonad.hpp new file mode 100644 index 000000000..82ef7b32d --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/comonad.hpp @@ -0,0 +1,53 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_COMONAD_HPP +#define BOOST_HANA_TEST_LAWS_COMONAD_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/concept/comonad.hpp> +#include <boost/hana/concept/comparable.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/concept/foldable.hpp> +#include <boost/hana/concept/functor.hpp> + +#include <laws/base.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename W, typename = when<true>> + struct TestComonad : TestComonad<W, laws> { + using TestComonad<W, laws>::TestComonad; + }; + + template <typename W> + struct TestComonad<W, laws> { + template <typename Ws> + TestComonad(Ws ws) { + hana::for_each(ws, [](auto w) { + static_assert(Comonad<decltype(w)>{}, ""); + + // extract(duplicate(w)) == w + BOOST_HANA_CHECK(hana::equal( + hana::extract(hana::duplicate(w)), + w + )); + + // transform(duplicate(w), extract) == w + BOOST_HANA_CHECK(hana::equal( + hana::transform(hana::duplicate(w), extract), + w + )); + + // duplicate(duplicate(w)) == transform(duplicate(w), duplicate) + BOOST_HANA_CHECK(hana::equal( + hana::duplicate(hana::duplicate(w)), + hana::transform(hana::duplicate(w), duplicate) + )); + }); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_COMONAD_HPP diff --git a/src/boost/libs/hana/test/_include/laws/comparable.hpp b/src/boost/libs/hana/test/_include/laws/comparable.hpp new file mode 100644 index 000000000..24ce317b8 --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/comparable.hpp @@ -0,0 +1,167 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_COMPARABLE_HPP +#define BOOST_HANA_TEST_LAWS_COMPARABLE_HPP + +#include <boost/hana/and.hpp> +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/comparing.hpp> +#include <boost/hana/concept/comparable.hpp> +#include <boost/hana/concept/constant.hpp> +#include <boost/hana/concept/product.hpp> +#include <boost/hana/concept/sequence.hpp> +#include <boost/hana/core/make.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/first.hpp> +#include <boost/hana/for_each.hpp> +#include <boost/hana/lazy.hpp> +#include <boost/hana/not_equal.hpp> +#include <boost/hana/second.hpp> +#include <boost/hana/value.hpp> + + +#include <laws/base.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename T, typename = hana::when<true>> + struct TestComparable : TestComparable<T, laws> { + using TestComparable<T, laws>::TestComparable; + }; + + template <typename T> + struct TestComparable<T, laws> { + template <typename Xs> + TestComparable(Xs xs) { + hana::for_each(xs, [](auto x) { + static_assert(hana::Comparable<decltype(x)>{}, ""); + }); + + foreach2(xs, [](auto a, auto b) { + + // reflexivity + BOOST_HANA_CHECK( + hana::equal(a, a) + ); + + // symmetry + BOOST_HANA_CHECK( + hana::equal(a, b) ^implies^ hana::equal(b, a) + ); + + // `not_equal` is the negation of `equal` + BOOST_HANA_CHECK( + hana::not_equal(a, b) ^iff^ hana::not_(hana::equal(a, b)) + ); + + // equal.to and not_equal.to + BOOST_HANA_CHECK( + hana::equal.to(a)(b) ^iff^ hana::equal(a, b) + ); + + BOOST_HANA_CHECK( + hana::not_equal.to(a)(b) ^iff^ hana::not_equal(a, b) + ); + + // comparing + _injection<0> f{}; + BOOST_HANA_CHECK( + hana::comparing(f)(a, b) ^iff^ hana::equal(f(a), f(b)) + ); + }); + + // transitivity + foreach3(xs, [](auto a, auto b, auto c) { + BOOST_HANA_CHECK( + hana::and_(hana::equal(a, b), hana::equal(b, c)) + ^implies^ hana::equal(a, c) + ); + }); + } + }; + + template <typename C> + struct TestComparable<C, when<Constant<C>::value>> + : TestComparable<C, laws> + { + template <typename Xs> + TestComparable(Xs xs) : TestComparable<C, laws>{xs} { + foreach2(xs, [](auto a, auto b) { + BOOST_HANA_CHECK( + hana::value(hana::equal(a, b)) ^iff^ + hana::equal(hana::value(a), hana::value(b)) + ); + }); + } + }; + + template <typename P> + struct TestComparable<P, when<Product<P>::value>> + : TestComparable<P, laws> + { + template <typename Products> + TestComparable(Products products) : TestComparable<P, laws>{products} { + foreach2(products, [](auto x, auto y) { + BOOST_HANA_CHECK( + hana::equal(x, y) ^iff^ + hana::and_( + hana::equal(hana::first(x), hana::first(y)), + hana::equal(hana::second(x), hana::second(y)) + ) + ); + }); + } + }; + + template <typename S> + struct TestComparable<S, when<Sequence<S>::value>> + : TestComparable<S, laws> + { + template <int i> + using x = _constant<i>; + + template <typename Xs> + TestComparable(Xs xs) : TestComparable<S, laws>{xs} { + constexpr auto list = make<S>; + + ////////////////////////////////////////////////////////////////// + // equal + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(hana::equal( + list(), + list() + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal( + list(x<0>{}), + list() + ))); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal( + list(), + list(x<0>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + list(x<0>{}), + list(x<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal( + list(x<0>{}, x<1>{}), + list(x<0>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + list(x<0>{}, x<1>{}), + list(x<0>{}, x<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal( + list(x<0>{}, x<1>{}, x<2>{}, x<3>{}), + list(x<0>{}, x<1>{}, x<2>{}, x<4>{}) + ))); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_COMPARABLE_HPP diff --git a/src/boost/libs/hana/test/_include/laws/constant.hpp b/src/boost/libs/hana/test/_include/laws/constant.hpp new file mode 100644 index 000000000..1acd335e4 --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/constant.hpp @@ -0,0 +1,106 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_CONSTANT_HPP +#define BOOST_HANA_TEST_LAWS_CONSTANT_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/concept/comparable.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/functional/capture.hpp> +#include <boost/hana/concept/logical.hpp> + +#include <laws/base.hpp> +#include <laws/comparable.hpp> +#include <laws/euclidean_ring.hpp> +#include <laws/group.hpp> +#include <laws/logical.hpp> +#include <laws/monoid.hpp> +#include <laws/orderable.hpp> +#include <laws/ring.hpp> + +#include <type_traits> + + +namespace boost { namespace hana { namespace test { + template <typename C, typename = when<true>> + struct TestConstant { + using T = typename C::value_type; + + template <typename X> + struct wrap_arbitrary_constant { + static constexpr bool value = boost::hana::value<X>(); + using hana_tag = detail::CanonicalConstant<T>; + }; + + template <typename Xs, typename Convertibles> + TestConstant(Xs xs, Convertibles types) { + hana::for_each(xs, [](auto x) { + static_assert(Constant<decltype(x)>{}, ""); + }); + + hana::for_each(xs, hana::capture(types)([](auto types, auto c) { + + // constexpr-ness of hana::value(c) + constexpr auto must_be_constexpr1 = hana::value(c); + constexpr auto must_be_constexpr2 = hana::value<decltype(c)>(); + (void)must_be_constexpr1; + (void)must_be_constexpr2; + + // consistency of C::value_type + static_assert(std::is_same< + T, + tag_of_t<decltype(hana::value(c))> + >{}, ""); + + // equivalence of value_of(c) and value<decltype(c)> + BOOST_HANA_CHECK(hana::equal( + hana::value_of(c), + hana::value<decltype(c)>() + )); + + // equivalence of value<decltype(c)>() and value(c) + BOOST_HANA_CHECK(hana::equal( + hana::value<decltype(c)>(), + hana::value(c) + )); + + // conversion from an arbitrary Constant + (void)to<C>(wrap_arbitrary_constant<decltype(c)>{}); + static_assert(is_embedded<detail::CanonicalConstant<T>, C>{}, ""); + + hana::for_each(types, hana::capture(c)([](auto c, auto u) { + using U = typename decltype(u)::type; + + // conversion to something to which the underlying data + // type can be converted. + BOOST_HANA_CHECK(equal( + to<U>(c), + make<U>(hana::value(c)) + )); + static_assert(is_embedded<C, U>::value ^iff^ is_embedded<T, U>::value, ""); + + // common data type + static_assert(std::is_same< + common_t<C, detail::CanonicalConstant<U>>, + detail::CanonicalConstant<common_t<T, U>> + >{}, ""); + + static_assert(std::is_same< + common_t<detail::CanonicalConstant<U>, C>, + detail::CanonicalConstant<common_t<T, U>> + >{}, ""); + + static_assert(std::is_same< + common_t<C, U>, + common_t<typename C::value_type, U> + >{}, ""); + })); + })); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_CONSTANT_HPP diff --git a/src/boost/libs/hana/test/_include/laws/euclidean_ring.hpp b/src/boost/libs/hana/test/_include/laws/euclidean_ring.hpp new file mode 100644 index 000000000..96d1fce58 --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/euclidean_ring.hpp @@ -0,0 +1,99 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_EUCLIDEAN_RING_HPP +#define BOOST_HANA_TEST_LAWS_EUCLIDEAN_RING_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/concept/comparable.hpp> +#include <boost/hana/concept/constant.hpp> +#include <boost/hana/concept/euclidean_ring.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/div.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/for_each.hpp> +#include <boost/hana/lazy.hpp> +#include <boost/hana/mod.hpp> +#include <boost/hana/mult.hpp> +#include <boost/hana/not_equal.hpp> +#include <boost/hana/plus.hpp> +#include <boost/hana/value.hpp> +#include <boost/hana/zero.hpp> + +#include <laws/base.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename D, typename = when<true>> + struct TestEuclideanRing : TestEuclideanRing<D, laws> { + using TestEuclideanRing<D, laws>::TestEuclideanRing; + }; + + template <typename D> + struct TestEuclideanRing<D, laws> { + template <typename Xs> + TestEuclideanRing(Xs xs) { + hana::for_each(xs, [](auto x) { + static_assert(EuclideanRing<decltype(x)>{}, ""); + }); + +#ifdef BOOST_HANA_WORKAROUND_MSVC_DECLTYPEAUTO_RETURNTYPE_662735 + zero<D>(); // force adding zero<D>'s member function to pending temploid list +#endif + + foreach2(xs, [](auto a, auto b) { + + // commutativity + BOOST_HANA_CHECK(hana::equal( + hana::mult(a, b), + hana::mult(b, a) + )); + + only_when_(hana::not_equal(b, zero<D>()), + hana::make_lazy([](auto a, auto b) { + BOOST_HANA_CHECK(hana::equal( + hana::plus( + hana::mult(hana::div(a, b), b), + hana::mod(a, b) + ), + a + )); + + BOOST_HANA_CHECK(hana::equal( + hana::mod(zero<D>(), b), + zero<D>() + )); + })(a, b)); + + }); + } + }; + + template <typename C> + struct TestEuclideanRing<C, when<Constant<C>::value>> + : TestEuclideanRing<C, laws> + { + template <typename Xs> + TestEuclideanRing(Xs xs) : TestEuclideanRing<C, laws>{xs} { + foreach2(xs, [](auto x, auto y) { + only_when_(hana::not_equal(zero<C>(), y), + hana::make_lazy([](auto x, auto y) { + BOOST_HANA_CHECK(hana::equal( + hana::div(hana::value(x), hana::value(y)), + hana::value(hana::div(x, y)) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::mod(hana::value(x), hana::value(y)), + hana::value(hana::mod(x, y)) + )); + + })(x, y)); + }); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_EUCLIDEAN_RING_HPP diff --git a/src/boost/libs/hana/test/_include/laws/foldable.hpp b/src/boost/libs/hana/test/_include/laws/foldable.hpp new file mode 100644 index 000000000..57411f416 --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/foldable.hpp @@ -0,0 +1,1104 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_FOLDABLE_HPP +#define BOOST_HANA_TEST_LAWS_FOLDABLE_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/chain.hpp> +#include <boost/hana/concept/comparable.hpp> +#include <boost/hana/concept/foldable.hpp> +#include <boost/hana/concept/product.hpp> +#include <boost/hana/concept/sequence.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/core/make.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/count.hpp> +#include <boost/hana/count_if.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/first.hpp> +#include <boost/hana/fold.hpp> +#include <boost/hana/fold_left.hpp> +#include <boost/hana/fold_right.hpp> +#include <boost/hana/for_each.hpp> +#include <boost/hana/functional/capture.hpp> +#include <boost/hana/functional/curry.hpp> +#include <boost/hana/functional/demux.hpp> +#include <boost/hana/functional/flip.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/lazy.hpp> +#include <boost/hana/length.hpp> +#include <boost/hana/lift.hpp> +#include <boost/hana/maximum.hpp> +#include <boost/hana/minimum.hpp> +#include <boost/hana/monadic_fold_left.hpp> +#include <boost/hana/monadic_fold_right.hpp> +#include <boost/hana/not_equal.hpp> +#include <boost/hana/product.hpp> +#include <boost/hana/reverse_fold.hpp> +#include <boost/hana/second.hpp> +#include <boost/hana/size.hpp> +#include <boost/hana/sum.hpp> +#include <boost/hana/unpack.hpp> +#include <boost/hana/value.hpp> + +#include <laws/base.hpp> +#include <support/identity.hpp> + +#include <vector> + + +namespace boost { namespace hana { namespace test { + template <typename F, typename = when<true>> + struct TestFoldable : TestFoldable<F, laws> { + using TestFoldable<F, laws>::TestFoldable; + }; + + template <typename F> + struct TestFoldable<F, laws> { + template <typename Foldables> + TestFoldable(Foldables foldables) { + hana::for_each(foldables, [](auto xs) { + static_assert(Foldable<decltype(xs)>{}, ""); + + _injection<0> f{}; + ct_eq<999> s{}; + + // equivalence of size(xs) and length(xs) + BOOST_HANA_CHECK(hana::equal( + hana::length(xs), + hana::size(xs) + )); + + // equivalence of fold with fold_left and + // of reverse_fold with fold_right + BOOST_HANA_CHECK(hana::equal( + hana::fold(xs, s, f), + hana::fold_left(xs, s, f) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::reverse_fold(xs, s, f), + hana::fold_right(xs, s, hana::flip(f)) + )); + + only_when_(hana::not_equal(hana::length(xs), hana::size_c<0>), + hana::make_lazy([](auto f, auto xs) { + BOOST_HANA_CHECK(hana::equal( + hana::fold(xs, f), + hana::fold_left(xs, f) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::reverse_fold(xs, f), + hana::fold_right(xs, hana::flip(f)) + )); + })(f, xs)); + + // equivalence of count(xs, val) and count_if(xs, equal.to(val)) + struct not_there { }; + BOOST_HANA_CHECK(hana::equal( + hana::count(xs, not_there{}), + hana::count_if(xs, equal.to(not_there{})) + )); + + hana::for_each(xs, hana::capture(xs)([](auto xs, auto value) { + BOOST_HANA_CHECK(hana::equal( + hana::count(xs, value), + hana::count_if(xs, equal.to(value)) + )); + })); + }); + } + }; + + template <typename P> + struct TestFoldable<P, when<Product<P>::value>> + : TestFoldable<P, laws> + { + template <typename Products> + TestFoldable(Products products) : TestFoldable<P, laws>{products} { + hana::for_each(products, [](auto p) { + _injection<0> f{}; + + BOOST_HANA_CHECK(hana::equal( + hana::unpack(p, f), + f(hana::first(p), hana::second(p)) + )); + }); + } + }; + + template <typename S> + struct TestFoldable<S, when<Sequence<S>::value>> + : TestFoldable<S, laws> + { + template <int i> + using x = _constant<i>; + + template <int i> + using ord = _constant<i>; + + struct undefined { }; + + template <typename Xs> + TestFoldable(Xs xs) : TestFoldable<S, laws>{xs} { + _injection<0> f{}; + auto z = x<999>{}; + constexpr auto list = make<S>; + + ////////////////////////////////////////////////////////////////// + // fold_left (with initial state) + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + fold_left(list(), z, undefined{}), + z + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + fold_left(list(x<1>{}), z, f), + f(z, x<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + fold_left(list(x<1>{}, x<2>{}), z, f), + f(f(z, x<1>{}), x<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + fold_left(list(x<1>{}, x<2>{}, x<3>{}), z, f), + f(f(f(z, x<1>{}), x<2>{}), x<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + fold_left(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}), z, f), + f(f(f(f(z, x<1>{}), x<2>{}), x<3>{}), x<4>{}) + )); + + BOOST_HANA_CONSTEXPR_CHECK(equal( + fold_left(list(1), z, f), + f(z, 1) + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + fold_left(list(1, '2'), z, f), + f(f(z, 1), '2') + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + fold_left(list(1, '2', 3.3), z, f), + f(f(f(z, 1), '2'), 3.3) + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + fold_left(list(1, '2', 3.3, 4.4f), z, f), + f(f(f(f(z, 1), '2'), 3.3), 4.4f) + )); + + ////////////////////////////////////////////////////////////////// + // fold_left (without initial state) + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + fold_left(list(z), undefined{}), + z + )); + BOOST_HANA_CONSTANT_CHECK(equal( + fold_left(list(z, x<2>{}), f), + f(z, x<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + fold_left(list(z, x<2>{}, x<3>{}), f), + f(f(z, x<2>{}), x<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + fold_left(list(z, x<2>{}, x<3>{}, x<4>{}), f), + f(f(f(z, x<2>{}), x<3>{}), x<4>{}) + )); + + ////////////////////////////////////////////////////////////////// + // fold_right (with initial state) + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + fold_right(list(), z, undefined{}), + z + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + fold_right(list(x<0>{}), z, f), + f(x<0>{}, z) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + fold_right(list(x<0>{}, x<1>{}), z, f), + f(x<0>{}, f(x<1>{}, z)) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + fold_right(list(x<0>{}, x<1>{}, x<2>{}), z, f), + f(x<0>{}, f(x<1>{}, f(x<2>{}, z))) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + fold_right(list(x<0>{}, x<1>{}, x<2>{}, x<3>{}), z, f), + f(x<0>{}, f(x<1>{}, f(x<2>{}, f(x<3>{}, z)))) + )); + + + BOOST_HANA_CONSTEXPR_CHECK(equal( + fold_right(list(1), z, f), + f(1, z) + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + fold_right(list(1, '2'), z, f), + f(1, f('2', z)) + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + fold_right(list(1, '2', 3.3), z, f), + f(1, f('2', f(3.3, z))) + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + fold_right(list(1, '2', 3.3, 4.4f), z, f), + f(1, f('2', f(3.3, f(4.4f, z)))) + )); + + ////////////////////////////////////////////////////////////////// + // fold_right (without initial state) + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + fold_right(list(z), undefined{}), + z + )); + BOOST_HANA_CONSTANT_CHECK(equal( + fold_right(list(x<1>{}, z), f), + f(x<1>{}, z) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + fold_right(list(x<1>{}, x<2>{}, z), f), + f(x<1>{}, f(x<2>{}, z)) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + fold_right(list(x<1>{}, x<2>{}, x<3>{}, z), f), + f(x<1>{}, f(x<2>{}, f(x<3>{}, z))) + )); + + ////////////////////////////////////////////////////////////////// + // monadic_fold_left (with initial state) + ////////////////////////////////////////////////////////////////// + { + using M = ::Identity; + auto f = hana::demux(::identity)(test::_injection<0>{}); + auto s = x<999>{}; + auto fp = hana::curry<2>(hana::flip(f)); + constexpr auto mfold = monadic_fold_left<M>; + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(), s, undefined{}), + lift<M>(s) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}), s, f), + f(s, x<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}), s, f), + chain(f(s, x<1>{}), fp(x<2>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}, x<3>{}), s, f), + chain(chain(f(s, x<1>{}), fp(x<2>{})), fp(x<3>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}), s, f), + chain(chain(chain(f(s, x<1>{}), fp(x<2>{})), fp(x<3>{})), fp(x<4>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}), s, f), + chain(chain(chain(chain(f(s, x<1>{}), fp(x<2>{})), fp(x<3>{})), fp(x<4>{})), fp(x<5>{})) + )); + } + + ////////////////////////////////////////////////////////////////// + // monadic_fold_left (without initial state) + ////////////////////////////////////////////////////////////////// + { + using M = ::Identity; + auto f = hana::demux(::identity)(test::_injection<0>{}); + auto fp = hana::curry<2>(hana::flip(f)); + constexpr auto mfold = monadic_fold_left<M>; + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}), undefined{}), + lift<M>(x<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}), f), + f(x<1>{}, x<2>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}, x<3>{}), f), + chain(f(x<1>{}, x<2>{}), fp(x<3>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}), f), + chain(chain(f(x<1>{}, x<2>{}), fp(x<3>{})), fp(x<4>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}), f), + chain(chain(chain(f(x<1>{}, x<2>{}), fp(x<3>{})), fp(x<4>{})), fp(x<5>{})) + )); + } + + ////////////////////////////////////////////////////////////////// + // monadic_fold_right (with initial state) + ////////////////////////////////////////////////////////////////// + { + using M = ::Identity; + auto f = hana::demux(::identity)(test::_injection<0>{}); + auto s = x<999>{}; + auto fp = hana::curry<2>(f); + // flipping `chain` makes the right associativity easier to see + auto chain = hana::flip(hana::chain); + constexpr auto mfold = monadic_fold_right<M>; + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(), s, undefined{}), + lift<M>(s) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}), s, f), + f(x<1>{}, s) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}), s, f), + chain(fp(x<1>{}), f(x<2>{}, s)) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}, x<3>{}), s, f), + chain(fp(x<1>{}), chain(fp(x<2>{}), f(x<3>{}, s))) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}), s, f), + chain(fp(x<1>{}), chain(fp(x<2>{}), chain(fp(x<3>{}), f(x<4>{}, s)))) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}), s, f), + chain(fp(x<1>{}), chain(fp(x<2>{}), chain(fp(x<3>{}), chain(fp(x<4>{}), f(x<5>{}, s))))) + )); + } + + ////////////////////////////////////////////////////////////////// + // monadic_fold_right (without initial state) + ////////////////////////////////////////////////////////////////// + { + using M = ::Identity; + auto f = hana::demux(::identity)(test::_injection<0>{}); + auto fp = hana::curry<2>(f); + // flipping `chain` makes the right associativity easier to see + auto chain = hana::flip(hana::chain); + constexpr auto mfold = monadic_fold_right<M>; + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}), undefined{}), + lift<M>(x<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}), f), + f(x<1>{}, x<2>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}, x<3>{}), f), + chain(fp(x<1>{}), f(x<2>{}, x<3>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}), f), + chain(fp(x<1>{}), chain(fp(x<2>{}), f(x<3>{}, x<4>{}))) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}), f), + chain(fp(x<1>{}), chain(fp(x<2>{}), chain(fp(x<3>{}), f(x<4>{}, x<5>{})))) + )); + } + + ////////////////////////////////////////////////////////////////// + // length + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + length(list()), size_c<0> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + length(list(undefined{})), size_c<1> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + length(list(undefined{}, undefined{})), size_c<2> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + length(list(undefined{}, undefined{}, undefined{})), size_c<3> + )); + + int i = 0; // non-constexpr + BOOST_HANA_CONSTANT_CHECK(equal( + length(list(i, i)), + size_c<2> + )); + + ////////////////////////////////////////////////////////////////// + // maximum (without a custom predicate) + ////////////////////////////////////////////////////////////////// + { + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<0>{})), + ord<0>{} + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<0>{}, ord<1>{})), + ord<1>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<1>{}, ord<0>{})), + ord<1>{} + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<0>{}, ord<1>{}, ord<2>{})), + ord<2>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<1>{}, ord<0>{}, ord<2>{})), + ord<2>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<1>{}, ord<2>{}, ord<0>{})), + ord<2>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<2>{}, ord<1>{}, ord<0>{})), + ord<2>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<2>{}, ord<0>{}, ord<1>{})), + ord<2>{} + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<0>{}, ord<1>{}, ord<2>{}, ord<3>{})), + ord<3>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<1>{}, ord<0>{}, ord<2>{}, ord<3>{})), + ord<3>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<1>{}, ord<2>{}, ord<0>{}, ord<3>{})), + ord<3>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<1>{}, ord<2>{}, ord<3>{}, ord<0>{})), + ord<3>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<2>{}, ord<1>{}, ord<3>{}, ord<0>{})), + ord<3>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<2>{}, ord<3>{}, ord<1>{}, ord<0>{})), + ord<3>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<2>{}, ord<3>{}, ord<0>{}, ord<1>{})), + ord<3>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<3>{}, ord<2>{}, ord<0>{}, ord<1>{})), + ord<3>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<3>{}, ord<0>{}, ord<2>{}, ord<1>{})), + ord<3>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<3>{}, ord<0>{}, ord<1>{}, ord<2>{})), + ord<3>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<0>{}, ord<2>{}, ord<3>{}, ord<1>{})), + ord<3>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + maximum(list(ord<0>{}, ord<3>{}, ord<1>{}, ord<2>{})), + ord<3>{} + )); + + + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{0})), + int{0} + )); + + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{0}, long{1})), + long{1} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{1}, long{0})), + int{1} + )); + + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{0}, 1ll, long{2})), + long{2} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{1}, 0ll, long{2})), + long{2} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{1}, 2ll, long{0})), + 2ll + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{2}, 1ll, long{0})), + int{2} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{2}, 0ll, long{1})), + int{2} + )); + + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{0}, 1ll, long{2}, short{3})), + short{3} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{1}, 0ll, long{2}, short{3})), + short{3} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{1}, 2ll, long{0}, short{3})), + short{3} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{1}, 2ll, long{3}, short{0})), + long{3} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{2}, 1ll, long{3}, short{0})), + long{3} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{2}, 3ll, long{1}, short{0})), + 3ll + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{2}, 3ll, long{0}, short{1})), + 3ll + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{3}, 2ll, long{0}, short{1})), + int{3} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{3}, 0ll, long{2}, short{1})), + int{3} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{3}, 0ll, long{1}, short{2})), + int{3} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{0}, 2ll, long{3}, short{1})), + long{3} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{0}, 3ll, long{1}, short{2})), + 3ll + )); + + + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{0}, 1ll, long_c<2>)), + long{2} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + maximum(list(int{0}, long_c<1>, 2ll)), + 2ll + )); + } + + ////////////////////////////////////////////////////////////////// + // minimum (without a custom predicate) + ////////////////////////////////////////////////////////////////// + { + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<6>{})), + ord<6>{} + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<6>{}, ord<7>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<7>{}, ord<6>{})), + ord<6>{} + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<6>{}, ord<7>{}, ord<8>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<7>{}, ord<6>{}, ord<8>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<7>{}, ord<8>{}, ord<6>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<8>{}, ord<7>{}, ord<6>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<8>{}, ord<6>{}, ord<7>{})), + ord<6>{} + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<6>{}, ord<7>{}, ord<8>{}, ord<9>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<7>{}, ord<6>{}, ord<8>{}, ord<9>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<7>{}, ord<8>{}, ord<6>{}, ord<9>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<7>{}, ord<8>{}, ord<9>{}, ord<6>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<8>{}, ord<7>{}, ord<9>{}, ord<6>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<8>{}, ord<9>{}, ord<7>{}, ord<6>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<8>{}, ord<9>{}, ord<6>{}, ord<7>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<9>{}, ord<8>{}, ord<6>{}, ord<7>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<9>{}, ord<6>{}, ord<8>{}, ord<7>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<9>{}, ord<6>{}, ord<7>{}, ord<8>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<6>{}, ord<8>{}, ord<9>{}, ord<7>{})), + ord<6>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + minimum(list(ord<6>{}, ord<9>{}, ord<7>{}, ord<8>{})), + ord<6>{} + )); + + + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{4})), + int{4} + )); + + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{4}, short{5})), + int{4} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{5}, short{4})), + short{4} + )); + + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{4}, short{5}, long{6})), + int{4} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{7}, short{6}, long{8})), + short{6} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{7}, short{8}, long{6})), + long{6} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{8}, short{7}, long{6})), + long{6} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{8}, short{6}, long{7})), + short{6} + )); + + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{6}, short{7}, long{8}, 9ll)), + int{6} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{7}, short{6}, long{8}, 9ll)), + short{6} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{7}, short{8}, long{6}, 9ll)), + long{6} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{7}, short{8}, long{9}, 6ll)), + 6ll + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{8}, short{7}, long{9}, 6ll)), + 6ll + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{8}, short{9}, long{7}, 6ll)), + 6ll + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{8}, short{9}, long{6}, 7ll)), + long{6} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{9}, short{8}, long{6}, 7ll)), + long{6} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{9}, short{6}, long{8}, 7ll)), + short{6} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{9}, short{6}, long{7}, 8ll)), + short{6} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{6}, short{8}, long{9}, 7ll)), + int{6} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{6}, short{9}, long{7}, 8ll)), + int{6} + )); + + + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(int{3}, short{4}, long_c<5>)), + int{3} + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + minimum(list(ord<33>{}, short{45}, long{46})), + ord<33>{} + )); + } + + + ////////////////////////////////////////////////////////////////// + // count_if + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + count_if(list(), id), size_c<0> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + count_if(list(int_c<1>), id), size_c<1> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + count_if(list(int_c<0>), id), size_c<0> + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + count_if(list(int_c<1>, char_c<1>), id), size_c<2> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + count_if(list(int_c<1>, char_c<0>), id), size_c<1> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + count_if(list(int_c<0>, char_c<1>), id), size_c<1> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + count_if(list(int_c<0>, char_c<0>), id), size_c<0> + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + count_if(list(int_c<1>, char_c<1>, long_c<1>), id), size_c<3> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + count_if(list(int_c<1>, char_c<1>, long_c<0>), id), size_c<2> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + count_if(list(int_c<1>, char_c<0>, long_c<1>), id), size_c<2> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + count_if(list(int_c<1>, char_c<0>, long_c<0>), id), size_c<1> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + count_if(list(int_c<0>, char_c<1>, long_c<1>), id), size_c<2> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + count_if(list(int_c<0>, char_c<1>, long_c<0>), id), size_c<1> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + count_if(list(int_c<0>, char_c<0>, long_c<1>), id), size_c<1> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + count_if(list(int_c<0>, char_c<0>, long_c<0>), id), size_c<0> + )); + + + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(int{1}), id), 1u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(int{0}), id), 0u + )); + + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(int{1}, char{1}), id), 2u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(int{1}, char{0}), id), 1u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(int{0}, char{1}), id), 1u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(int{0}, char{0}), id), 0u + )); + + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(int{1}, char{1}, double{1}), id), 3u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(int{1}, char{1}, double{0}), id), 2u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(int{1}, char{0}, double{1}), id), 2u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(int{1}, char{0}, double{0}), id), 1u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(int{0}, char{1}, double{1}), id), 2u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(int{0}, char{1}, double{0}), id), 1u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(int{0}, char{0}, double{1}), id), 1u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(int{0}, char{0}, double{0}), id), 0u + )); + + + BOOST_HANA_CONSTEXPR_LAMBDA auto is_even = [](auto x) { + return x % 2 == 0; + }; + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(), is_even), 0u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(1), is_even), 0u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(2), is_even), 1u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(1, 2), is_even), 1u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(1, 2, 3), is_even), 1u + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + count_if(list(1, 2, 3, 4), is_even), 2u + )); + + ////////////////////////////////////////////////////////////////// + // count + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::count(list(), undefined{}), + size_c<0> + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::count(list(ct_eq<0>{}), undefined{}), + size_c<0> + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::count(list(ct_eq<0>{}), ct_eq<0>{}), + size_c<1> + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::count(list(ct_eq<0>{}, ct_eq<1>{}), undefined{}), + size_c<0> + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::count(list(ct_eq<0>{}, ct_eq<1>{}), ct_eq<0>{}), + size_c<1> + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::count(list(ct_eq<0>{}, ct_eq<1>{}), ct_eq<1>{}), + size_c<1> + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::count(list(ct_eq<0>{}, ct_eq<0>{}), ct_eq<0>{}), + size_c<2> + )); + + ////////////////////////////////////////////////////////////////// + // product + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + product<integral_constant_tag<int>>(list()), + int_c<1> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + product<integral_constant_tag<int>>(list(int_c<2>)), + int_c<2> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + product<integral_constant_tag<int>>(list(int_c<2>, int_c<3>)), + int_c<2 * 3> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + product<integral_constant_tag<int>>(list(int_c<2>, int_c<3>, int_c<4>)), + int_c<2 * 3 * 4> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + product<integral_constant_tag<int>>(list(int_c<2>, int_c<3>, int_c<4>, int_c<5>)), + int_c<2 * 3 * 4 * 5> + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + product<integral_constant_tag<unsigned long>>(list()), + ulong_c<1> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + product<integral_constant_tag<unsigned long>>(list(ulong_c<2>, ulong_c<3>, ulong_c<4>)), + ulong_c<2 * 3 * 4> + )); + + BOOST_HANA_CONSTEXPR_CHECK(equal( + product<int>(list(2)), + 2 + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + product<int>(list(2, 3)), + 2 * 3 + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + product<int>(list(2, 3, 4)), + 2 * 3 * 4 + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + product<int>(list(2, 3, 4, 5)), + 2 * 3 * 4 * 5 + )); + + + ////////////////////////////////////////////////////////////////// + // sum + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + sum<integral_constant_tag<int>>(list()), + int_c<0> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + sum<integral_constant_tag<int>>(list(int_c<1>)), + int_c<1> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + sum<integral_constant_tag<int>>(list(int_c<1>, int_c<2>)), + int_c<1 + 2> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + sum<integral_constant_tag<int>>(list(int_c<1>, int_c<2>, int_c<3>)), + int_c<1 + 2 + 3> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + sum<integral_constant_tag<int>>(list(int_c<1>, int_c<2>, int_c<3>, int_c<4>)), + int_c<1 + 2 + 3 + 4> + )); + + + BOOST_HANA_CONSTANT_CHECK(equal( + sum<integral_constant_tag<unsigned long>>(list()), + ulong_c<0> + )); + BOOST_HANA_CONSTANT_CHECK(equal( + sum<integral_constant_tag<unsigned long>>(list(ulong_c<1>, ulong_c<2>, ulong_c<3>)), + ulong_c<1 + 2 + 3> + )); + + + BOOST_HANA_CONSTEXPR_CHECK(equal( + sum<int>(list(1)), 1 + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + sum<int>(list(1, 2)), 1 + 2 + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + sum<int>(list(1, 2, 3)), 1 + 2 + 3 + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + sum<int>(list(1, 2, 3, 4)), 1 + 2 + 3 + 4 + )); + + + ////////////////////////////////////////////////////////////////// + // unpack + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + unpack(list(), f), + f() + )); + BOOST_HANA_CONSTANT_CHECK(equal( + unpack(list(x<0>{}), f), + f(x<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + unpack(list(x<0>{}, x<1>{}), f), + f(x<0>{}, x<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + unpack(list(x<0>{}, x<1>{}, x<2>{}), f), + f(x<0>{}, x<1>{}, x<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + unpack(list(x<0>{}, x<1>{}, x<2>{}, x<3>{}), f), + f(x<0>{}, x<1>{}, x<2>{}, x<3>{}) + )); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_FOLDABLE_HPP diff --git a/src/boost/libs/hana/test/_include/laws/functor.hpp b/src/boost/libs/hana/test/_include/laws/functor.hpp new file mode 100644 index 000000000..d1ddbb4de --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/functor.hpp @@ -0,0 +1,250 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_FUNCTOR_HPP +#define BOOST_HANA_TEST_LAWS_FUNCTOR_HPP + +#include <boost/hana/adjust.hpp> +#include <boost/hana/adjust_if.hpp> +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/concept/comparable.hpp> +#include <boost/hana/concept/functor.hpp> +#include <boost/hana/concept/sequence.hpp> +#include <boost/hana/core/make.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/eval_if.hpp> +#include <boost/hana/fill.hpp> +#include <boost/hana/for_each.hpp> +#include <boost/hana/functional/always.hpp> +#include <boost/hana/functional/capture.hpp> +#include <boost/hana/functional/compose.hpp> +#include <boost/hana/lazy.hpp> +#include <boost/hana/replace.hpp> +#include <boost/hana/replace_if.hpp> +#include <boost/hana/transform.hpp> + +#include <laws/base.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename F, typename = when<true>> + struct TestFunctor : TestFunctor<F, laws> { + using TestFunctor<F, laws>::TestFunctor; + }; + + template <typename F> + struct TestFunctor<F, laws> { + template <typename Xs, typename Elements> + TestFunctor(Xs xs, Elements elements) { + hana::for_each(xs, hana::capture(elements)([](auto elements, auto x) { + static_assert(Functor<decltype(x)>{}, ""); + + test::_injection<0> f{}; + test::_injection<1> g{}; + + // identity + BOOST_HANA_CHECK(hana::equal( + hana::transform(x, id), + x + )); + + // composition + BOOST_HANA_CHECK(hana::equal( + hana::transform(x, hana::compose(f, g)), + hana::transform(hana::transform(x, g), f) + )); + + // method definitions in terms of transform/adjust_if + hana::for_each(elements, hana::capture(x, f, elements)( + [](auto x, auto f, auto elements, auto value) { + BOOST_HANA_CHECK(hana::equal( + hana::adjust(x, value, f), + hana::adjust_if(x, hana::equal.to(value), f) + )); + + hana::for_each(elements, hana::capture(x, value)( + [](auto x, auto oldval, auto newval) { + BOOST_HANA_CHECK(hana::equal( + hana::replace(x, oldval, newval), + hana::replace_if(x, hana::equal.to(oldval), newval) + )); + })); + })); + + auto pred = hana::always(true_c); + BOOST_HANA_CHECK(hana::equal( + hana::adjust_if(x, pred, f), + hana::transform(x, [=](auto z) { + return hana::eval_if(pred(z), + hana::make_lazy(f)(z), + hana::make_lazy(z) + ); + }) + )); + + test::_constant<0> v{}; + BOOST_HANA_CHECK(hana::equal( + hana::replace_if(x, pred, v), + hana::adjust_if(x, pred, hana::always(v)) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::fill(x, v), + hana::replace_if(x, hana::always(true_c), v) + )); + + })); + } + }; + + template <typename S> + struct TestFunctor<S, when<Sequence<S>::value>> + : TestFunctor<S, laws> + { + struct undefined { }; + + template <typename Xs, typename Elements> + TestFunctor(Xs xs, Elements elements) + : TestFunctor<S, laws>{xs, elements} + { + using test::ct_eq; + using test::cx_eq; + constexpr auto list = make<S>; + + ////////////////////////////////////////////////////////////////// + // replace_if + ////////////////////////////////////////////////////////////////// + { + auto a = ct_eq<888>{}; + auto b = ct_eq<999>{}; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace_if(list(), undefined{}, undefined{}), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace_if(list(ct_eq<0>{}), equal.to(a), undefined{}), + list(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace_if(list(a), equal.to(a), b), + list(b) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace_if(list(ct_eq<0>{}, ct_eq<1>{}), equal.to(a), undefined{}), + list(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace_if(list(a, ct_eq<1>{}), equal.to(a), b), + list(b, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace_if(list(ct_eq<0>{}, a), equal.to(a), b), + list(ct_eq<0>{}, b) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace_if(list(a, a), equal.to(a), b), + list(b, b) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace_if(list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), equal.to(a), undefined{}), + list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace_if(list(a, ct_eq<1>{}, ct_eq<2>{}), equal.to(a), b), + list(b, ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace_if(list(ct_eq<0>{}, a, ct_eq<2>{}), equal.to(a), b), + list(ct_eq<0>{}, b, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace_if(list(ct_eq<0>{}, ct_eq<1>{}, a), equal.to(a), b), + list(ct_eq<0>{}, ct_eq<1>{}, b) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace_if(list(a, ct_eq<1>{}, a), equal.to(a), b), + list(b, ct_eq<1>{}, b) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace_if(list(a, ct_eq<1>{}, a, ct_eq<3>{}, a), equal.to(a), b), + list(b, ct_eq<1>{}, b, ct_eq<3>{}, b) + )); + } + + ////////////////////////////////////////////////////////////////// + // replace + ////////////////////////////////////////////////////////////////// + { + auto a = ct_eq<888>{}; + auto b = ct_eq<999>{}; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace(list(), undefined{}, undefined{}), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace(list(ct_eq<0>{}), a, undefined{}), + list(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace(list(a), a, b), + list(b) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace(list(ct_eq<0>{}, ct_eq<1>{}), a, undefined{}), + list(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace(list(a, ct_eq<1>{}), a, b), + list(b, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace(list(ct_eq<0>{}, a), a, b), + list(ct_eq<0>{}, b) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace(list(a, a), a, b), + list(b, b) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace(list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), a, undefined{}), + list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace(list(a, ct_eq<1>{}, ct_eq<2>{}), a, b), + list(b, ct_eq<1>{}, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace(list(ct_eq<0>{}, a, ct_eq<2>{}), a, b), + list(ct_eq<0>{}, b, ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace(list(ct_eq<0>{}, ct_eq<1>{}, a), a, b), + list(ct_eq<0>{}, ct_eq<1>{}, b) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace(list(a, ct_eq<1>{}, a), a, b), + list(b, ct_eq<1>{}, b) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::replace(list(a, ct_eq<1>{}, a, ct_eq<3>{}, a), a, b), + list(b, ct_eq<1>{}, b, ct_eq<3>{}, b) + )); + } + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_FUNCTOR_HPP diff --git a/src/boost/libs/hana/test/_include/laws/group.hpp b/src/boost/libs/hana/test/_include/laws/group.hpp new file mode 100644 index 000000000..b9eeab776 --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/group.hpp @@ -0,0 +1,93 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_GROUP_HPP +#define BOOST_HANA_TEST_LAWS_GROUP_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/concept/comparable.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/concept/group.hpp> +#include <boost/hana/lazy.hpp> + +#include <laws/base.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename G, typename = when<true>> + struct TestGroup : TestGroup<G, laws> { + using TestGroup<G, laws>::TestGroup; + }; + + template <typename G> + struct TestGroup<G, laws> { + template <typename Xs> + TestGroup(Xs xs) { + hana::for_each(xs, [](auto x) { + static_assert(Group<decltype(x)>{}, ""); + }); + +#ifdef BOOST_HANA_WORKAROUND_MSVC_DECLTYPEAUTO_RETURNTYPE_662735 + zero<G>(); // force adding zero<G>'s member function to pending temploid list +#endif + + foreach2(xs, [](auto x, auto y) { + + // left inverse + BOOST_HANA_CHECK(hana::equal( + hana::plus(x, hana::negate(x)), + zero<G>() + )); + + // right inverse + BOOST_HANA_CHECK(hana::equal( + hana::plus(hana::negate(x), x), + zero<G>() + )); + + // default definition of minus + BOOST_HANA_CHECK(hana::equal( + hana::minus(x, y), + hana::plus(x, hana::negate(y)) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::minus(y, x), + hana::plus(y, hana::negate(x)) + )); + + // default definition of negate + BOOST_HANA_CHECK(hana::equal( + hana::negate(hana::negate(x)), + x + )); + }); + } + }; + + template <typename C> + struct TestGroup<C, when<Constant<C>::value>> + : TestGroup<C, laws> + { + template <typename Xs> + TestGroup(Xs xs) : TestGroup<C, laws>{xs} { + foreach2(xs, [](auto x, auto y) { + + BOOST_HANA_CHECK(hana::equal( + hana::negate(hana::value(x)), + hana::value(hana::negate(x)) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::minus(hana::value(x), hana::value(y)), + hana::value(hana::minus(x, y)) + )); + + }); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_GROUP_HPP diff --git a/src/boost/libs/hana/test/_include/laws/hashable.hpp b/src/boost/libs/hana/test/_include/laws/hashable.hpp new file mode 100644 index 000000000..0fbd8f333 --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/hashable.hpp @@ -0,0 +1,60 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_HASHABLE_HPP +#define BOOST_HANA_TEST_LAWS_HASHABLE_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/concept/hashable.hpp> +#include <boost/hana/core/default.hpp> +#include <boost/hana/core/tag_of.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/for_each.hpp> +#include <boost/hana/hash.hpp> +#include <boost/hana/if.hpp> + +#include <laws/base.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename G, typename = when<true>> + struct TestHashable : TestHashable<G, laws> { + using TestHashable<G, laws>::TestHashable; + }; + + template <typename H> + struct TestHashable<H, laws> { + template <typename Xs> + TestHashable(Xs xs) { + hana::for_each(xs, [](auto x) { + static_assert(Hashable<decltype(x)>{}, ""); + }); + + hana::for_each(xs, [&](auto const& x) { + hana::for_each(xs, [&](auto const& y) { + using X = hana::tag_of_t<decltype(x)>; + using Y = hana::tag_of_t<decltype(y)>; + constexpr bool comparable = !hana::is_default< + hana::equal_impl<X, Y> + >::value; + + hana::if_(hana::bool_c<comparable>, + [](auto const& x, auto const& y) { + BOOST_HANA_CHECK( + hana::equal(x, y) + ^implies^ + hana::equal(hana::hash(x), hana::hash(y)) + ); + }, + [](auto...) { } + )(x, y); + }); + }); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_HASHABLE_HPP diff --git a/src/boost/libs/hana/test/_include/laws/iterable.hpp b/src/boost/libs/hana/test/_include/laws/iterable.hpp new file mode 100644 index 000000000..d6d84c5ec --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/iterable.hpp @@ -0,0 +1,195 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_ITERABLE_HPP +#define BOOST_HANA_TEST_LAWS_ITERABLE_HPP + +#include <boost/hana/any_of.hpp> +#include <boost/hana/assert.hpp> +#include <boost/hana/at.hpp> +#include <boost/hana/back.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/concept/comparable.hpp> +#include <boost/hana/concept/foldable.hpp> +#include <boost/hana/concept/sequence.hpp> +#include <boost/hana/core/make.hpp> +#include <boost/hana/core/to.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/drop_front.hpp> +#include <boost/hana/drop_front_exactly.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/eval_if.hpp> +#include <boost/hana/find_if.hpp> +#include <boost/hana/for_each.hpp> +#include <boost/hana/front.hpp> +#include <boost/hana/functional/always.hpp> +#include <boost/hana/functional/capture.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/is_empty.hpp> +#include <boost/hana/lazy.hpp> +#include <boost/hana/length.hpp> +#include <boost/hana/minus.hpp> +#include <boost/hana/not.hpp> +#include <boost/hana/optional.hpp> +#include <boost/hana/range.hpp> +#include <boost/hana/tuple.hpp> + +#include <laws/base.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename It, typename = hana::when<true>> + struct TestIterable : TestIterable<It, laws> { + using TestIterable<It, laws>::TestIterable; + }; + + template <typename It> + struct TestIterable<It, laws> { + template <typename Xs> + TestIterable(Xs xs) { + hana::for_each(xs, [](auto xs) { + static_assert(Iterable<decltype(xs)>{}, ""); + + BOOST_HANA_CONSTANT_CHECK( + hana::is_empty(xs) ^iff^ hana::is_empty(hana::to<tuple_tag>(xs)) + ); + + only_when_(hana::not_(hana::is_empty(xs)), hana::make_lazy([](auto xs) { + BOOST_HANA_CHECK(hana::equal( + hana::front(xs), + hana::front(hana::to<tuple_tag>(xs)) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::to<tuple_tag>(hana::drop_front_exactly(xs)), + hana::drop_front_exactly(hana::to<tuple_tag>(xs)) + )); + + // methods + // back(xs) == at(xs, length(xs)-1) + BOOST_HANA_CHECK(hana::equal( + hana::back(xs), + hana::at(xs, hana::minus(hana::length(xs), hana::size_c<1>)) + )); + + })(xs)); + + // drop_front(xs, 0) == xs + BOOST_HANA_CHECK(hana::equal( + hana::drop_front(xs, size_c<0>), + xs + )); + + // at(xs, n) == front(drop_front(xs, n)) + hana::for_each(hana::make_range(size_c<0>, hana::length(xs)), + hana::capture(xs)([](auto xs, auto n) { + BOOST_HANA_CHECK(hana::equal( + hana::at(xs, n), + hana::front(hana::drop_front(xs, n)) + )); + })); + + // Searchable + hana::eval_if(hana::is_empty(xs), + hana::make_lazy([](auto xs) { + BOOST_HANA_CONSTANT_CHECK( + hana::not_(hana::any_of(xs, hana::always(true_c))) + ); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::find_if(xs, hana::always(true_c)), + nothing + )); + })(xs), + hana::make_lazy([](auto xs) { + BOOST_HANA_CHECK( + hana::any_of(xs, hana::always(true_c)) + ); + BOOST_HANA_CHECK( + hana::not_(hana::any_of(xs, hana::always(false_c))) + ); + + BOOST_HANA_CHECK(hana::equal( + hana::find_if(xs, hana::always(true_c)), + hana::just(hana::front(xs)) + )); + })(xs) + ); + + }); + } + }; + + template <typename S> + struct TestIterable<S, when<Sequence<S>::value>> + : TestIterable<S, laws> + { + template <int i> + using x = ct_eq<i>; + + template <int i = 0> + struct invalid { }; + + struct undefined { }; + + template <typename Xs> + TestIterable(Xs xs) : TestIterable<S, laws>{xs} { + constexpr auto list = make<S>; + + ////////////////////////////////////////////////////////////////// + // front + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + front(list(x<0>{})), + x<0>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + front(list(x<0>{}, invalid<>{})), + x<0>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + front(list(x<0>{}, invalid<1>{}, invalid<2>{})), + x<0>{} + )); + + BOOST_HANA_CONSTEXPR_CHECK(equal( + front(list(1)), 1 + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + front(list(1, '2')), 1 + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + front(list(1, '2', 3.3)), 1 + )); + + ////////////////////////////////////////////////////////////////// + // back + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + back(list(x<0>{})), + x<0>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + back(list(invalid<0>{}, x<1>{})), + x<1>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + back(list(invalid<0>{}, invalid<1>{}, x<2>{})), + x<2>{} + )); + + BOOST_HANA_CONSTEXPR_CHECK(equal( + back(list(1)), 1 + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + back(list(1, '2')), '2' + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + back(list(1, '2', 3.3)), 3.3 + )); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_ITERABLE_HPP diff --git a/src/boost/libs/hana/test/_include/laws/logical.hpp b/src/boost/libs/hana/test/_include/laws/logical.hpp new file mode 100644 index 000000000..df9932766 --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/logical.hpp @@ -0,0 +1,137 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_LOGICAL_HPP +#define BOOST_HANA_TEST_LAWS_LOGICAL_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/concept/comparable.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/functional/capture.hpp> +#include <boost/hana/lazy.hpp> +#include <boost/hana/concept/logical.hpp> + +#include <laws/base.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename L, typename = when<true>> + struct TestLogical : TestLogical<L, laws> { + using TestLogical<L, laws>::TestLogical; + }; + + template <typename L> + struct TestLogical<L, laws> { + template <typename Xs, typename Pred, typename F> + static void for_each_such_that(Xs xs, Pred pred, F f) { + hana::for_each(xs, [&pred, &f](auto x) { + hana::eval_if(pred(x), + hana::make_lazy(f)(x), + [](auto) { } + ); + }); + } + + template <typename Xs> + TestLogical(Xs xs) { + hana::for_each(xs, [](auto x) { + static_assert(Logical<decltype(x)>{}, ""); + }); + + foreach3(xs, hana::capture(xs)([](auto xs, auto a, auto b, auto c) { + auto true_valued = [](auto x) { + return hana::if_(x, true_c, false_c); + }; + auto false_valued = [](auto x) { + return hana::if_(x, false_c, true_c); + }; + + // associativity + BOOST_HANA_CHECK(hana::equal( + hana::or_(a, hana::or_(b, c)), + hana::or_(hana::or_(a, b), c) + )); + BOOST_HANA_CHECK(hana::equal( + hana::and_(a, hana::and_(b, c)), + hana::and_(hana::and_(a, b), c) + )); + + // equivalence through commutativity + BOOST_HANA_CHECK( + hana::or_(a, b) ^iff^ hana::or_(b, a) + ); + BOOST_HANA_CHECK( + hana::and_(a, b) ^iff^ hana::and_(b, a) + ); + + // absorption + BOOST_HANA_CHECK(hana::equal( + hana::or_(a, hana::and_(a, b)), a + )); + BOOST_HANA_CHECK(hana::equal( + hana::and_(a, hana::or_(a, b)), a + )); + + // left identity + TestLogical::for_each_such_that(xs, true_valued, + hana::capture(a)([](auto a, auto t) { + BOOST_HANA_CHECK(hana::equal( + hana::and_(t, a), a + )); + })); + TestLogical::for_each_such_that(xs, false_valued, + hana::capture(a)([](auto a, auto f) { + BOOST_HANA_CHECK(hana::equal( + hana::or_(f, a), a + )); + })); + + // distributivity + BOOST_HANA_CHECK(hana::equal( + hana::or_(a, hana::and_(b, c)), + hana::and_(hana::or_(a, b), hana::or_(a, c)) + )); + BOOST_HANA_CHECK(hana::equal( + hana::and_(a, hana::or_(b, c)), + hana::or_(hana::and_(a, b), hana::and_(a, c)) + )); + + // complements + BOOST_HANA_CHECK(true_valued(hana::or_(a, hana::not_(a)))); + BOOST_HANA_CHECK(false_valued(hana::and_(a, hana::not_(a)))); + + })); + } + }; + + template <typename C> + struct TestLogical<C, when<Constant<C>::value>> + : TestLogical<C, laws> + { + template <typename Xs> + TestLogical(Xs xs) : TestLogical<C, laws>{xs} { + foreach2(xs, [](auto x, auto y) { + + BOOST_HANA_CHECK(hana::equal( + hana::value(hana::not_(x)), + hana::not_(hana::value(x)) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::value(hana::and_(x, y)), + hana::and_(hana::value(x), hana::value(y)) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::value(hana::or_(x, y)), + hana::or_(hana::value(x), hana::value(y)) + )); + + }); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_LOGICAL_HPP diff --git a/src/boost/libs/hana/test/_include/laws/monad.hpp b/src/boost/libs/hana/test/_include/laws/monad.hpp new file mode 100644 index 000000000..25a23d417 --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/monad.hpp @@ -0,0 +1,222 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_MONAD_HPP +#define BOOST_HANA_TEST_LAWS_MONAD_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/chain.hpp> +#include <boost/hana/concept/comparable.hpp> +#include <boost/hana/concept/monad.hpp> +#include <boost/hana/concept/sequence.hpp> +#include <boost/hana/core/make.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/flatten.hpp> +#include <boost/hana/for_each.hpp> +#include <boost/hana/functional/compose.hpp> +#include <boost/hana/functional/id.hpp> +#include <boost/hana/lift.hpp> +#include <boost/hana/monadic_compose.hpp> +#include <boost/hana/transform.hpp> + +#include <laws/base.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename M, typename = when<true>> + struct TestMonad : TestMonad<M, laws> { + using TestMonad<M, laws>::TestMonad; + }; + + template <typename M> + struct TestMonad<M, laws> { + // Xs are Monads over something + // XXs are Monads over Monads over something + template <typename Xs, typename XXs> + TestMonad(Xs xs, XXs xxs) { + hana::for_each(xs, [](auto m) { + static_assert(Monad<decltype(m)>{}, ""); + + auto f = hana::compose(lift<M>, test::_injection<0>{}); + auto g = hana::compose(lift<M>, test::_injection<1>{}); + auto h = hana::compose(lift<M>, test::_injection<2>{}); + auto x = test::ct_eq<0>{}; + + ////////////////////////////////////////////////////////////// + // Laws formulated with `monadic_compose` + ////////////////////////////////////////////////////////////// + // associativity + BOOST_HANA_CHECK(hana::equal( + hana::monadic_compose(h, hana::monadic_compose(g, f))(x), + hana::monadic_compose(hana::monadic_compose(h, g), f)(x) + )); + + // left identity + BOOST_HANA_CHECK(hana::equal( + hana::monadic_compose(lift<M>, f)(x), + f(x) + )); + + // right identity + BOOST_HANA_CHECK(hana::equal( + hana::monadic_compose(f, lift<M>)(x), + f(x) + )); + + ////////////////////////////////////////////////////////////// + // Laws formulated with `chain` + // + // This just provides us with some additional cross-checking, + // but the documentation does not mention those. + ////////////////////////////////////////////////////////////// + BOOST_HANA_CHECK(hana::equal( + hana::chain(hana::lift<M>(x), f), + f(x) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::chain(m, lift<M>), + m + )); + + BOOST_HANA_CHECK(hana::equal( + hana::chain(m, [f, g](auto x) { + return hana::chain(f(x), g); + }), + hana::chain(hana::chain(m, f), g) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::transform(m, f), + hana::chain(m, hana::compose(lift<M>, f)) + )); + + ////////////////////////////////////////////////////////////// + // Consistency of method definitions + ////////////////////////////////////////////////////////////// + // consistency of `chain` + BOOST_HANA_CHECK(hana::equal( + hana::chain(m, f), + hana::flatten(hana::transform(m, f)) + )); + + // consistency of `monadic_compose` + BOOST_HANA_CHECK(hana::equal( + hana::monadic_compose(f, g)(x), + hana::chain(g(x), f) + )); + }); + + // consistency of `flatten` + hana::for_each(xxs, [](auto mm) { + BOOST_HANA_CHECK(hana::equal( + hana::flatten(mm), + hana::chain(mm, hana::id) + )); + }); + } + }; + + template <typename S> + struct TestMonad<S, when<Sequence<S>::value>> + : TestMonad<S, laws> + { + template <typename Xs, typename XXs> + TestMonad(Xs xs, XXs xxs) + : TestMonad<S, laws>{xs, xxs} + { + constexpr auto list = make<S>; + + ////////////////////////////////////////////////////////////////// + // flatten + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::flatten(list(list(), list())), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::flatten(list(list(ct_eq<0>{}), list())), + list(ct_eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::flatten(list(list(), list(ct_eq<0>{}))), + list(ct_eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::flatten(list(list(ct_eq<0>{}), list(ct_eq<1>{}))), + list(ct_eq<0>{}, ct_eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::flatten(list( + list(ct_eq<0>{}, ct_eq<1>{}), + list(), + list(ct_eq<2>{}, ct_eq<3>{}), + list(ct_eq<4>{}) + )), + list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}) + )); + + // just make sure we don't double move; this happened in hana::tuple + hana::flatten(list(list(Tracked{1}, Tracked{2}))); + + ////////////////////////////////////////////////////////////////// + // chain + ////////////////////////////////////////////////////////////////// + { + test::_injection<0> f{}; + auto g = hana::compose(list, f); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::chain(list(), g), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::chain(list(ct_eq<1>{}), g), + list(f(ct_eq<1>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::chain(list(ct_eq<1>{}, ct_eq<2>{}), g), + list(f(ct_eq<1>{}), f(ct_eq<2>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::chain(list(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}), g), + list(f(ct_eq<1>{}), f(ct_eq<2>{}), f(ct_eq<3>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::chain(list(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}), g), + list(f(ct_eq<1>{}), f(ct_eq<2>{}), f(ct_eq<3>{}), f(ct_eq<4>{})) + )); + } + + ////////////////////////////////////////////////////////////////// + // monadic_compose + ////////////////////////////////////////////////////////////////// + { + test::_injection<0> f{}; + test::_injection<1> g{}; + + auto mf = [=](auto x) { return list(f(x), f(f(x))); }; + auto mg = [=](auto x) { return list(g(x), g(g(x))); }; + + auto x = test::ct_eq<0>{}; + BOOST_HANA_CHECK(hana::equal( + hana::monadic_compose(mf, mg)(x), + list(f(g(x)), f(f(g(x))), f(g(g(x))), f(f(g(g(x))))) + )); + } + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_MONAD_HPP diff --git a/src/boost/libs/hana/test/_include/laws/monad_plus.hpp b/src/boost/libs/hana/test/_include/laws/monad_plus.hpp new file mode 100644 index 000000000..406320c91 --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/monad_plus.hpp @@ -0,0 +1,616 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_MONAD_PLUS_HPP +#define BOOST_HANA_TEST_LAWS_MONAD_PLUS_HPP + +#include <boost/hana/append.hpp> +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/chain.hpp> +#include <boost/hana/concat.hpp> +#include <boost/hana/concept/comparable.hpp> +#include <boost/hana/concept/monad_plus.hpp> +#include <boost/hana/concept/sequence.hpp> +#include <boost/hana/core/make.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/cycle.hpp> +#include <boost/hana/empty.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/filter.hpp> +#include <boost/hana/for_each.hpp> +#include <boost/hana/functional/capture.hpp> +#include <boost/hana/functional/compose.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/lift.hpp> +#include <boost/hana/not.hpp> +#include <boost/hana/not_equal.hpp> +#include <boost/hana/prefix.hpp> +#include <boost/hana/prepend.hpp> +#include <boost/hana/remove.hpp> +#include <boost/hana/remove_if.hpp> +#include <boost/hana/replicate.hpp> +#include <boost/hana/suffix.hpp> + +#include <laws/base.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename M, typename = when<true>> + struct TestMonadPlus : TestMonadPlus<M, laws> { + using TestMonadPlus<M, laws>::TestMonadPlus; + }; + + template <typename M> + struct TestMonadPlus<M, laws> { + template <typename Xs, typename Predicates, typename Values> + TestMonadPlus(Xs xs, Predicates predicates, Values values) { +#ifdef BOOST_HANA_WORKAROUND_MSVC_DECLTYPEAUTO_RETURNTYPE_662735 + empty<M>(); // force adding empty<M>'s member function to pending temploid list +#endif + + hana::for_each(xs, [](auto a) { + static_assert(MonadPlus<decltype(a)>{}, ""); + + // left identity + BOOST_HANA_CHECK(hana::equal( + hana::concat(hana::empty<M>(), a), + a + )); + + // right identity + BOOST_HANA_CHECK(hana::equal( + hana::concat(a, hana::empty<M>()), + a + )); + + // absorption + auto f = hana::compose(lift<M>, test::_injection<0>{}); + BOOST_HANA_CHECK(hana::equal( + hana::chain(hana::empty<M>(), f), + hana::empty<M>() + )); + + BOOST_HANA_CHECK(hana::equal( + hana::chain(a, hana::always(hana::empty<M>())), + hana::empty<M>() + )); + + }); + + // associativity + foreach3(xs, [](auto a, auto b, auto c) { + BOOST_HANA_CHECK(hana::equal( + hana::concat(a, hana::concat(b, c)), + hana::concat(hana::concat(a, b), c) + )); + }); + + // Default method definitions + hana::for_each(xs, hana::capture(predicates, values)( + [](auto predicates, auto values, auto x) { + + // remove_if(x, pred) == filter(x, negated pred) + hana::for_each(predicates, hana::capture(x)([](auto x, auto pred) { + BOOST_HANA_CHECK(hana::equal( + hana::remove_if(x, pred), + hana::filter(x, hana::compose(hana::not_, pred)) + )); + })); + + // remove(x, value) == remove_if(x, equal.to(value)) + hana::for_each(values, hana::capture(x)([](auto x, auto value) { + BOOST_HANA_CHECK(hana::equal( + hana::remove(x, value), + hana::remove_if(x, hana::equal.to(value)) + )); + })); + })); + } + }; + + template <typename S> + struct TestMonadPlus<S, when<Sequence<S>::value>> + : TestMonadPlus<S, laws> + { + template <int i> + using eq = test::ct_eq<i>; + + struct undefined { }; + + template <typename Xs, typename Predicates, typename Values> + TestMonadPlus(Xs xs, Predicates predicates, Values values) + : TestMonadPlus<S, laws>{xs, predicates, values} + { + auto z = eq<999>{}; + constexpr auto list = make<S>; + + ////////////////////////////////////////////////////////////////// + // empty + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + hana::empty<S>(), list() + )); + + ////////////////////////////////////////////////////////////////// + // concat + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + concat(list(), list()), + list() + )); + BOOST_HANA_CONSTANT_CHECK(equal( + concat(list(), list(eq<0>{})), + list(eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + concat(list(), list(eq<0>{}, eq<1>{})), + list(eq<0>{}, eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + concat(list(eq<0>{}), list()), + list(eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + concat(list(eq<0>{}), list(eq<1>{})), + list(eq<0>{}, eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + concat(list(eq<0>{}), list(eq<1>{}, eq<2>{})), + list(eq<0>{}, eq<1>{}, eq<2>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + concat(list(eq<0>{}, eq<1>{}), list()), + list(eq<0>{}, eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + concat(list(eq<0>{}, eq<1>{}), list(eq<2>{})), + list(eq<0>{}, eq<1>{}, eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + concat(list(eq<0>{}, eq<1>{}), list(eq<2>{}, eq<3>{})), + list(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{}) + )); + + + BOOST_HANA_CONSTANT_CHECK(equal( + concat(list(), list()), + list() + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + concat(list(1), list()), + list(1) + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + concat(list(), list(1)), + list(1) + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + concat(list(1), list('2')), + list(1, '2') + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + concat(list(1, '2'), list(3.3)), + list(1, '2', 3.3) + )); + + + ////////////////////////////////////////////////////////////////// + // filter + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + filter(list(), undefined{}), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + filter(list(z), not_equal.to(z)), + list() + )); + BOOST_HANA_CONSTANT_CHECK(equal( + filter(list(eq<1>{}), not_equal.to(z)), + list(eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + filter(list(eq<1>{}, eq<2>{}), not_equal.to(z)), + list(eq<1>{}, eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + filter(list(z, eq<2>{}), not_equal.to(z)), + list(eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + filter(list(eq<1>{}, z), not_equal.to(z)), + list(eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + filter(list(z, eq<2>{}, eq<3>{}), not_equal.to(z)), + list(eq<2>{}, eq<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + filter(list(eq<1>{}, z, eq<3>{}), not_equal.to(z)), + list(eq<1>{}, eq<3>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + filter(list(eq<1>{}, eq<2>{}, z), not_equal.to(z)), + list(eq<1>{}, eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + filter(list(eq<1>{}, z, z), not_equal.to(z)), + list(eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + filter(list(z, eq<2>{}, z), not_equal.to(z)), + list(eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + filter(list(z, z, eq<3>{}), not_equal.to(z)), + list(eq<3>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + filter(list(eq<1>{}, eq<2>{}, eq<3>{}, eq<4>{}, z), not_equal.to(z)), + list(eq<1>{}, eq<2>{}, eq<3>{}, eq<4>{}) + )); + + ////////////////////////////////////////////////////////////////// + // prepend + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + prepend(list(), eq<0>{}), + list(eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + prepend(list(eq<1>{}), eq<0>{}), + list(eq<0>{}, eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + prepend(list(eq<1>{}, eq<2>{}), eq<0>{}), + list(eq<0>{}, eq<1>{}, eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + prepend(list(eq<1>{}, eq<2>{}, eq<3>{}), eq<0>{}), + list(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{}) + )); + + + BOOST_HANA_CONSTEXPR_CHECK(equal( + prepend(list(), 1), + list(1) + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + prepend(list('2'), 1), + list(1, '2') + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + prepend(list('2', 3.3), 1), + list(1, '2', 3.3) + )); + + ////////////////////////////////////////////////////////////////// + // append + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + append(list(), eq<0>{}), + list(eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + append(list(eq<0>{}), eq<1>{}), + list(eq<0>{}, eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + append(list(eq<0>{}, eq<1>{}), eq<2>{}), + list(eq<0>{}, eq<1>{}, eq<2>{}) + )); + + BOOST_HANA_CONSTEXPR_CHECK(equal( + append(list(), 1), list(1) + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + append(list(1), '2'), list(1, '2') + )); + BOOST_HANA_CONSTEXPR_CHECK(equal( + append(list(1, '2'), 3.3), list(1, '2', 3.3) + )); + + + ////////////////////////////////////////////////////////////////// + // cycle + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(), size_c<0>), + list() + )); + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(), size_c<1>), + list() + )); + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(), size_c<2>), + list() + )); + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(), size_c<3>), + list() + )); + + + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(eq<0>{}), size_c<0>), + list() + )); + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(eq<0>{}), size_c<1>), + list(eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(eq<0>{}), size_c<2>), + list(eq<0>{}, eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(eq<0>{}), size_c<3>), + list(eq<0>{}, eq<0>{}, eq<0>{}) + )); + + + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(eq<0>{}, eq<1>{}), size_c<0>), + list() + )); + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(eq<0>{}, eq<1>{}), size_c<1>), + list(eq<0>{}, eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(eq<0>{}, eq<1>{}), size_c<2>), + list(eq<0>{}, eq<1>{}, eq<0>{}, eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(eq<0>{}, eq<1>{}), size_c<3>), + list(eq<0>{}, eq<1>{}, eq<0>{}, eq<1>{}, eq<0>{}, eq<1>{}) + )); + + + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(eq<0>{}, eq<1>{}, eq<2>{}), size_c<0>), + list() + )); + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(eq<0>{}, eq<1>{}, eq<2>{}), size_c<1>), + list(eq<0>{}, eq<1>{}, eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(eq<0>{}, eq<1>{}, eq<2>{}), size_c<2>), + list(eq<0>{}, eq<1>{}, eq<2>{}, eq<0>{}, eq<1>{}, eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + cycle(list(eq<0>{}, eq<1>{}, eq<2>{}), size_c<3>), + list(eq<0>{}, eq<1>{}, eq<2>{}, eq<0>{}, eq<1>{}, eq<2>{}, eq<0>{}, eq<1>{}, eq<2>{}) + )); + + ////////////////////////////////////////////////////////////////// + // remove_if + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + remove_if(list(), undefined{}), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + remove_if(list(eq<0>{}), equal.to(z)), + list(eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + remove_if(list(z), equal.to(z)), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + remove_if(list(eq<0>{}, eq<1>{}), equal.to(z)), + list(eq<0>{}, eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + remove_if(list(z, eq<1>{}), equal.to(z)), + list(eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + remove_if(list(eq<0>{}, z), equal.to(z)), + list(eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + remove_if(list(z, z), equal.to(z)), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + remove_if(list(eq<0>{}, eq<1>{}, eq<2>{}), equal.to(z)), + list(eq<0>{}, eq<1>{}, eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + remove_if(list(eq<0>{}, eq<1>{}, z), equal.to(z)), + list(eq<0>{}, eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + remove_if(list(eq<0>{}, z, eq<2>{}), equal.to(z)), + list(eq<0>{}, eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + remove_if(list(z, eq<1>{}, eq<2>{}), equal.to(z)), + list(eq<1>{}, eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + remove_if(list(z, z, eq<2>{}), equal.to(z)), + list(eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + remove_if(list(eq<0>{}, z, z), equal.to(z)), + list(eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + remove_if(list(z, z, z), equal.to(z)), + list() + )); + + ////////////////////////////////////////////////////////////////// + // remove + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + hana::remove(list(), undefined{}), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + hana::remove(list(eq<0>{}), z), + list(eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + hana::remove(list(z), z), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + hana::remove(list(eq<0>{}, eq<1>{}), z), + list(eq<0>{}, eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + hana::remove(list(z, eq<1>{}), z), + list(eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + hana::remove(list(eq<0>{}, z), z), + list(eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + hana::remove(list(z, z), z), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + hana::remove(list(eq<0>{}, eq<1>{}, eq<2>{}), z), + list(eq<0>{}, eq<1>{}, eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + hana::remove(list(eq<0>{}, eq<1>{}, z), z), + list(eq<0>{}, eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + hana::remove(list(eq<0>{}, z, eq<2>{}), z), + list(eq<0>{}, eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + hana::remove(list(z, eq<1>{}, eq<2>{}), z), + list(eq<1>{}, eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + hana::remove(list(z, z, eq<2>{}), z), + list(eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + hana::remove(list(eq<0>{}, z, z), z), + list(eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + hana::remove(list(z, z, z), z), + list() + )); + + ////////////////////////////////////////////////////////////////// + // replicate + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + replicate<S>(eq<0>{}, size_c<0>), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + replicate<S>(eq<0>{}, size_c<1>), + list(eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + replicate<S>(eq<0>{}, size_c<2>), + list(eq<0>{}, eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + replicate<S>(eq<0>{}, size_c<3>), + list(eq<0>{}, eq<0>{}, eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + replicate<S>(eq<0>{}, size_c<4>), + list(eq<0>{}, eq<0>{}, eq<0>{}, eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + replicate<S>(eq<0>{}, size_c<5>), + list(eq<0>{}, eq<0>{}, eq<0>{}, eq<0>{}, eq<0>{}) + )); + + + ////////////////////////////////////////////////////////////////// + // prefix + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + prefix(list(), z), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + prefix(list(eq<0>{}), z), + list(z, eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + prefix(list(eq<0>{}, eq<1>{}), z), + list(z, eq<0>{}, z, eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + prefix(list(eq<0>{}, eq<1>{}, eq<2>{}), z), + list(z, eq<0>{}, z, eq<1>{}, z, eq<2>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + prefix(list(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{}), z), + list(z, eq<0>{}, z, eq<1>{}, z, eq<2>{}, z, eq<3>{}) + )); + + + ////////////////////////////////////////////////////////////////// + // suffix + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + suffix(list(), z), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + suffix(list(eq<0>{}), z), + list(eq<0>{}, z) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + suffix(list(eq<0>{}, eq<1>{}), z), + list(eq<0>{}, z, eq<1>{}, z) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + suffix(list(eq<0>{}, eq<1>{}, eq<2>{}), z), + list(eq<0>{}, z, eq<1>{}, z, eq<2>{}, z) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + suffix(list(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{}), z), + list(eq<0>{}, z, eq<1>{}, z, eq<2>{}, z, eq<3>{}, z) + )); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_MONAD_PLUS_HPP diff --git a/src/boost/libs/hana/test/_include/laws/monoid.hpp b/src/boost/libs/hana/test/_include/laws/monoid.hpp new file mode 100644 index 000000000..d500992a0 --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/monoid.hpp @@ -0,0 +1,86 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_MONOID_HPP +#define BOOST_HANA_TEST_LAWS_MONOID_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/concept/comparable.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/functional/capture.hpp> +#include <boost/hana/lazy.hpp> +#include <boost/hana/concept/monoid.hpp> + +#include <laws/base.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename M, typename = when<true>> + struct TestMonoid : TestMonoid<M, laws> { + using TestMonoid<M, laws>::TestMonoid; + }; + + template <typename M> + struct TestMonoid<M, laws> { + template <typename Xs> + TestMonoid(Xs xs) { +#ifdef BOOST_HANA_WORKAROUND_MSVC_DECLTYPEAUTO_RETURNTYPE_662735 + zero<M>(); // force adding zero<M>'s member function to pending temploid list +#endif + + hana::for_each(xs, hana::capture(xs)([](auto xs, auto a) { + static_assert(Monoid<decltype(a)>{}, ""); + + // left identity + BOOST_HANA_CHECK(hana::equal( + hana::plus(zero<M>(), a), + a + )); + + // right identity + BOOST_HANA_CHECK(hana::equal( + hana::plus(a, zero<M>()), + a + )); + + hana::for_each(xs, + hana::capture(xs, a)([](auto xs, auto a, auto b) { + hana::for_each(xs, + hana::capture(a, b)([](auto a, auto b, auto c) { + // associativity + BOOST_HANA_CHECK(equal( + hana::plus(a, hana::plus(b, c)), + hana::plus(hana::plus(a, b), c) + )); + })); + })); + + })); + } + }; + + template <typename C> + struct TestMonoid<C, when<Constant<C>::value>> + : TestMonoid<C, laws> + { + template <typename Xs> + TestMonoid(Xs xs) : TestMonoid<C, laws>{xs} { + + BOOST_HANA_CHECK(hana::equal( + hana::value(zero<C>()), + zero<typename C::value_type>() + )); + + foreach2(xs, [](auto x, auto y) { + BOOST_HANA_CHECK(hana::equal( + hana::plus(hana::value(x), hana::value(y)), + hana::value(hana::plus(x, y)) + )); + }); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_MONOID_HPP diff --git a/src/boost/libs/hana/test/_include/laws/orderable.hpp b/src/boost/libs/hana/test/_include/laws/orderable.hpp new file mode 100644 index 000000000..f49ea7f8a --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/orderable.hpp @@ -0,0 +1,182 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_ORDERABLE_HPP +#define BOOST_HANA_TEST_LAWS_ORDERABLE_HPP + +#include <boost/hana/and.hpp> +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/concept/constant.hpp> +#include <boost/hana/concept/orderable.hpp> +#include <boost/hana/concept/product.hpp> +#include <boost/hana/concept/sequence.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/first.hpp> +#include <boost/hana/greater.hpp> +#include <boost/hana/greater_equal.hpp> +#include <boost/hana/lazy.hpp> +#include <boost/hana/less.hpp> +#include <boost/hana/less_equal.hpp> +#include <boost/hana/not.hpp> +#include <boost/hana/or.hpp> +#include <boost/hana/ordering.hpp> +#include <boost/hana/second.hpp> +#include <boost/hana/value.hpp> + +#include <laws/base.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename T, typename = when<true>> + struct TestOrderable : TestOrderable<T, laws> { + using TestOrderable<T, laws>::TestOrderable; + }; + + template <typename T> + struct TestOrderable<T, laws> { + template <typename Xs> + TestOrderable(Xs xs) { + hana::for_each(xs, [](auto x) { + static_assert(Orderable<decltype(x)>{}, ""); + }); + + foreach2(xs, [](auto a, auto b) { + + // antisymmetry + BOOST_HANA_CHECK( + hana::and_(hana::less_equal(a, b), hana::less_equal(b, a)) + ^implies^ hana::equal(a, b) + ); + + // totality + BOOST_HANA_CHECK( + hana::or_(hana::less_equal(a, b), hana::less_equal(b, a)) + ); + + // other methods in terms of `less_equal` + BOOST_HANA_CHECK( + hana::less(a, b) ^iff^ hana::not_(hana::less_equal(b, a)) + ); + + BOOST_HANA_CHECK( + hana::greater(a, b) ^iff^ hana::less(b, a) + ); + + BOOST_HANA_CHECK( + hana::greater_equal(a, b) ^iff^ hana::not_(hana::less(a, b)) + ); + + // less.than & al. + BOOST_HANA_CHECK(hana::less.than(a)(b) ^iff^ hana::less(b, a)); + BOOST_HANA_CHECK(hana::greater.than(a)(b) ^iff^ hana::greater(b, a)); + BOOST_HANA_CHECK(hana::less_equal.than(a)(b) ^iff^ hana::less_equal(b, a)); + BOOST_HANA_CHECK(hana::greater_equal.than(a)(b) ^iff^ hana::greater_equal(b, a)); + + // ordering + _injection<0> f{}; // test::_injection is also monotonic + BOOST_HANA_CHECK( + hana::ordering(f)(a, b) ^iff^ hana::less(f(a), f(b)) + ); + }); + + // transitivity + foreach3(xs, [](auto a, auto b, auto c) { + BOOST_HANA_CHECK( + hana::and_(hana::less_equal(a, b), hana::less_equal(b, c)) + ^implies^ hana::less_equal(a, c) + ); + }); + } + }; + + template <typename C> + struct TestOrderable<C, when<Constant<C>::value>> + : TestOrderable<C, laws> + { + template <typename Xs> + TestOrderable(Xs xs) : TestOrderable<C, laws>{xs} { + foreach2(xs, [](auto a, auto b) { + + BOOST_HANA_CHECK( + hana::value(hana::less(a, b)) ^iff^ + hana::less(hana::value(a), hana::value(b)) + ); + + }); + } + }; + + template <typename P> + struct TestOrderable<P, when<Product<P>::value>> + : TestOrderable<P, laws> + { + template <typename Products> + TestOrderable(Products products) + : TestOrderable<P, laws>{products} + { + foreach2(products, [](auto x, auto y) { + BOOST_HANA_CHECK( + hana::less(x, y) ^iff^ + hana::or_( + hana::less(hana::first(x), hana::first(y)), + hana::and_( + hana::equal(hana::first(x), hana::first(y)), + hana::less(hana::second(x), hana::second(y)) + ) + ) + ); + }); + } + }; + + template <typename S> + struct TestOrderable<S, when<Sequence<S>::value>> + : TestOrderable<S, laws> + { + struct invalid { }; + + template <typename Xs> + TestOrderable(Xs xs) : TestOrderable<S, laws>{xs} { + constexpr auto list = make<S>; + + ////////////////////////////////////////////////////////////////// + // less + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less( + list(), + list() + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::less( + list(), + list(invalid{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less( + list(invalid{}), + list() + ))); + BOOST_HANA_CONSTANT_CHECK(hana::less( + list(ct_ord<0>{}), + list(ct_ord<7>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less( + list(ct_ord<1>{}), + list(ct_ord<0>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less( + list(ct_ord<0>{}, ct_ord<1>{}, ct_ord<8>{}), + list(ct_ord<0>{}, ct_ord<1>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::less( + list(ct_ord<0>{}, ct_ord<0>{}, ct_ord<8>{}), + list(ct_ord<0>{}, ct_ord<1>{}) + )); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_ORDERABLE_HPP diff --git a/src/boost/libs/hana/test/_include/laws/product.hpp b/src/boost/libs/hana/test/_include/laws/product.hpp new file mode 100644 index 000000000..18e5a15d2 --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/product.hpp @@ -0,0 +1,46 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_PRODUCT_HPP +#define BOOST_HANA_TEST_LAWS_PRODUCT_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/concept/product.hpp> +#include <boost/hana/core/make.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/first.hpp> +#include <boost/hana/second.hpp> + +#include <laws/base.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename P, typename = when<true>> + struct TestProduct : TestProduct<P, laws> { + using TestProduct<P, laws>::TestProduct; + }; + + template <typename P> + struct TestProduct<P, laws> { + template <typename Elements> + TestProduct(Elements elements) { + foreach2(elements, [](auto x, auto y) { + static_assert(Product<decltype(hana::make<P>(x, y))>{}, ""); + + BOOST_HANA_CHECK(hana::equal( + hana::first(hana::make<P>(x, y)), + x + )); + + BOOST_HANA_CHECK(hana::equal( + hana::second(hana::make<P>(x, y)), + y + )); + }); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_PRODUCT_HPP diff --git a/src/boost/libs/hana/test/_include/laws/ring.hpp b/src/boost/libs/hana/test/_include/laws/ring.hpp new file mode 100644 index 000000000..4afbca05c --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/ring.hpp @@ -0,0 +1,125 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_RING_HPP +#define BOOST_HANA_TEST_LAWS_RING_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/concept/comparable.hpp> +#include <boost/hana/concept/constant.hpp> +#include <boost/hana/concept/monoid.hpp> +#include <boost/hana/concept/ring.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/functional/capture.hpp> +#include <boost/hana/lazy.hpp> +#include <boost/hana/mult.hpp> +#include <boost/hana/not_equal.hpp> +#include <boost/hana/one.hpp> +#include <boost/hana/plus.hpp> +#include <boost/hana/power.hpp> +#include <boost/hana/value.hpp> + +#include <laws/base.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename R, typename = when<true>> + struct TestRing : TestRing<R, laws> { + using TestRing<R, laws>::TestRing; + }; + + template <typename R> + struct TestRing<R, laws> { + template <typename Xs> + TestRing(Xs xs) { +#ifdef BOOST_HANA_WORKAROUND_MSVC_DECLTYPEAUTO_RETURNTYPE_662735 + one<R>(); // force adding one<R>'s member function to pending temploid list +#endif + + hana::for_each(xs, hana::capture(xs)([](auto xs, auto x) { + static_assert(Ring<decltype(x)>{}, ""); + + foreach2(xs, hana::capture(x)([](auto x, auto y, auto z) { + // associativity + BOOST_HANA_CHECK(hana::equal( + hana::mult(x, hana::mult(y, z)), + hana::mult(hana::mult(x, y), z) + )); + + // distributivity + BOOST_HANA_CHECK(hana::equal( + hana::mult(x, hana::plus(y, z)), + hana::plus(hana::mult(x, y), hana::mult(x, z)) + )); + })); + + // right identity + BOOST_HANA_CHECK(hana::equal( + hana::mult(x, one<R>()), x + )); + + // left identity + BOOST_HANA_CHECK(hana::equal( + hana::mult(one<R>(), x), x + )); + + // power + BOOST_HANA_CHECK(hana::equal( + hana::power(x, int_c<0>), + one<R>() + )); + + BOOST_HANA_CHECK(hana::equal( + hana::power(x, int_c<1>), + x + )); + + BOOST_HANA_CHECK(hana::equal( + hana::power(x, int_c<2>), + hana::mult(x, x) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::power(x, int_c<3>), + hana::mult(hana::mult(x, x), x) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::power(x, int_c<4>), + hana::mult(hana::mult(hana::mult(x, x), x), x) + )); + + BOOST_HANA_CHECK(hana::equal( + hana::power(x, int_c<5>), + hana::mult(hana::mult(hana::mult(hana::mult(x, x), x), x), x) + )); + + })); + } + }; + + template <typename C> + struct TestRing<C, when<Constant<C>::value>> + : TestRing<C, laws> + { + template <typename Xs> + TestRing(Xs xs) : TestRing<C, laws>{xs} { + BOOST_HANA_CHECK(hana::equal( + hana::value(one<C>()), + one<typename C::value_type>() + )); + + foreach2(xs, [](auto x, auto y) { + BOOST_HANA_CHECK(hana::equal( + hana::mult(hana::value(x), hana::value(y)), + hana::value(hana::mult(x, y)) + )); + }); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_RING_HPP diff --git a/src/boost/libs/hana/test/_include/laws/searchable.hpp b/src/boost/libs/hana/test/_include/laws/searchable.hpp new file mode 100644 index 000000000..ae55b06eb --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/searchable.hpp @@ -0,0 +1,611 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_SEARCHABLE_HPP +#define BOOST_HANA_TEST_LAWS_SEARCHABLE_HPP + +#include <boost/hana/all.hpp> +#include <boost/hana/all_of.hpp> +#include <boost/hana/any.hpp> +#include <boost/hana/any_of.hpp> +#include <boost/hana/assert.hpp> +#include <boost/hana/at_key.hpp> +#include <boost/hana/bool.hpp> +#include <boost/hana/concat.hpp> +#include <boost/hana/concept/comparable.hpp> +#include <boost/hana/concept/searchable.hpp> +#include <boost/hana/concept/sequence.hpp> +#include <boost/hana/contains.hpp> +#include <boost/hana/core/is_a.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/find.hpp> +#include <boost/hana/find_if.hpp> +#include <boost/hana/for_each.hpp> +#include <boost/hana/functional/always.hpp> +#include <boost/hana/functional/capture.hpp> +#include <boost/hana/functional/compose.hpp> +#include <boost/hana/functional/partial.hpp> +#include <boost/hana/is_disjoint.hpp> +#include <boost/hana/is_subset.hpp> +#include <boost/hana/lazy.hpp> +#include <boost/hana/none.hpp> +#include <boost/hana/none_of.hpp> +#include <boost/hana/not.hpp> +#include <boost/hana/optional.hpp> +#include <boost/hana/transform.hpp> +#include <boost/hana/tuple.hpp> + +#include <laws/base.hpp> +#include <support/numeric.hpp> + + +namespace boost { namespace hana { namespace test { + template <typename S, typename = when<true>> + struct TestSearchable : TestSearchable<S, laws> { + using TestSearchable<S, laws>::TestSearchable; + }; + + template <typename S> + struct TestSearchable<S, laws> { + template <typename Searchables, typename Keys> + TestSearchable(Searchables searchables, Keys keys) { + hana::for_each(searchables, [](auto xs) { + static_assert(Searchable<decltype(xs)>{}, ""); + }); + + auto predicates = hana::concat( + hana::to_tuple(hana::transform(keys, equal.to)), + hana::make_tuple( + hana::always(false_c), + hana::always(true_c) + ) + ); + + hana::for_each(searchables, hana::capture(searchables, keys, predicates)( + [](auto searchables, auto keys, auto predicates, auto xs) { + hana::for_each(predicates, hana::capture(xs)( + [](auto xs, auto p) { + // any_of(xs, p) <=> !all_of(xs, negated p) + // <=> !none_of(xs, p) + BOOST_HANA_CHECK( + hana::any_of(xs, p) ^iff^ + hana::not_(hana::all_of(xs, hana::compose(not_, p))) + ); + + BOOST_HANA_CHECK( + hana::any_of(xs, p) ^iff^ + hana::not_(hana::none_of(xs, p)) + ); + })); + + // any(xs) <=> any_of(xs, id) + // all(xs) <=> all_of(xs, id) + // none(xs) <=> none_of(xs, id) + auto all_logicals = hana::all_of(xs, [](auto x) { + return hana::bool_c<hana::Logical<decltype(x)>::value>; + }); + only_when_(all_logicals, hana::make_lazy([](auto xs) { + BOOST_HANA_CHECK( + hana::any(xs) ^iff^ hana::any_of(xs, id) + ); + + BOOST_HANA_CHECK( + hana::all(xs) ^iff^ hana::all_of(xs, hana::id) + ); + + BOOST_HANA_CHECK( + hana::none(xs) ^iff^ hana::none_of(xs, hana::id) + ); + })(xs)); + + // find_if(xs, always(false_c)) == nothing + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::find_if(xs, hana::always(hana::false_c)), + hana::nothing + )); + + hana::for_each(searchables, hana::capture(xs)([](auto xs, auto ys) { + // is_subset(xs, ys) <=> all_of(xs, [](auto x) { return contains(ys, x); }) + BOOST_HANA_CHECK( + hana::is_subset(xs, ys) ^iff^ + hana::all_of(xs, hana::partial(hana::contains, ys)) + ); + + // is_disjoint(xs, ys) <=> none_of(xs, [](auto x) { return contains(ys, x); }) + BOOST_HANA_CHECK( + hana::is_disjoint(xs, ys) ^iff^ + hana::none_of(xs, hana::partial(hana::contains, ys)) + ); + })); + + hana::for_each(keys, hana::capture(xs)([](auto xs, auto key) { + // find(xs, x) == find_if(xs, [](auto y) { return y == x; }) + BOOST_HANA_CHECK(hana::equal( + hana::find(xs, key), + hana::find_if(xs, hana::equal.to(key)) + )); + + // contains(xs, x) <=> any_of(xs, [](auto y) { return y == x; }) + BOOST_HANA_CHECK( + hana::contains(xs, key) ^iff^ + hana::any_of(xs, hana::equal.to(key)) + ); + + only_when_(hana::contains(xs, key), + hana::make_lazy([](auto xs, auto key) { + // at_key(xs, key) == find(xs, key).value() + BOOST_HANA_CHECK(hana::equal( + hana::at_key(xs, key), + hana::find(xs, key).value() + )); + })(xs, key) + ); + })); + })); + } + }; + + template <typename S> + struct TestSearchable<S, when<Sequence<S>::value>> + : TestSearchable<S, laws> + { + template <int i> + using x = _constant<i>; + + template <int = 0> + struct invalid { }; + + struct undefined { }; + + template <typename Xs, typename Keys> + TestSearchable(Xs xs, Keys keys) + : TestSearchable<S, laws>{xs, keys} + { + constexpr auto list = make<S>; + + BOOST_HANA_CONSTEXPR_LAMBDA auto is_even = [](auto x) { + return x % 2 == 0; + }; + + auto c = numeric; // a minimal comparable + auto logical = numeric; + + ////////////////////////////////////////////////////////////////// + // any_of + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK( + hana::not_(hana::any_of(list(), equal.to(x<9>{}))) + ); + + BOOST_HANA_CONSTANT_CHECK( + hana::not_(hana::any_of(list(x<0>{}), equal.to(x<9>{}))) + ); + BOOST_HANA_CONSTANT_CHECK( + hana::any_of(list(x<0>{}), equal.to(x<0>{})) + ); + BOOST_HANA_CONSTANT_CHECK( + hana::any_of(list(x<0>{}, invalid<1>{}), equal.to(x<0>{})) + ); + BOOST_HANA_CONSTANT_CHECK( + hana::any_of(list(x<0>{}, invalid<1>{}, invalid<2>{}), equal.to(x<0>{})) + ); + + BOOST_HANA_CONSTANT_CHECK( + hana::not_(hana::any_of(list(x<0>{}, x<1>{}), equal.to(x<9>{}))) + ); + BOOST_HANA_CONSTANT_CHECK( + hana::any_of(list(x<0>{}, x<1>{}), equal.to(x<1>{})) + ); + BOOST_HANA_CONSTANT_CHECK( + hana::any_of(list(x<0>{}, x<1>{}, invalid<2>{}), equal.to(x<1>{})) + ); + BOOST_HANA_CONSTANT_CHECK( + hana::any_of(list(x<0>{}, x<1>{}, invalid<2>{}, invalid<3>{}), equal.to(x<1>{})) + ); + + BOOST_HANA_CONSTANT_CHECK( + hana::not_(hana::any_of(list(x<0>{}, x<1>{}, x<2>{}), equal.to(x<9>{}))) + ); + BOOST_HANA_CONSTANT_CHECK( + hana::any_of(list(x<0>{}, x<1>{}, x<2>{}), equal.to(x<2>{})) + ); + BOOST_HANA_CONSTANT_CHECK( + hana::any_of(list(x<0>{}, x<1>{}, x<2>{}, nothing), equal.to(x<2>{})) + ); + BOOST_HANA_CONSTANT_CHECK( + hana::any_of(list(x<0>{}, x<1>{}, x<2>{}, nothing, nothing), equal.to(x<2>{})) + ); + + BOOST_HANA_CONSTANT_CHECK( + hana::not_(hana::any_of(list(), invalid<>{})) + ); + + + BOOST_HANA_CONSTEXPR_CHECK( + hana::any_of(list(c(0)), equal.to(c(0))) + ); + BOOST_HANA_CONSTEXPR_CHECK( + hana::not_(hana::any_of(list(c(0)), equal.to(c(1)))) + ); + BOOST_HANA_CONSTEXPR_CHECK( + hana::not_(hana::any_of(list(1), is_even)) + ); + BOOST_HANA_CONSTEXPR_CHECK( + hana::any_of(list(2), is_even) + ); + BOOST_HANA_CONSTEXPR_CHECK( + hana::any_of(list(1, 2), is_even) + ); + BOOST_HANA_CONSTEXPR_CHECK( + hana::not_(hana::any_of(list(1, 3), is_even)) + ); + BOOST_HANA_CONSTEXPR_CHECK( + hana::any_of(list(1, 3, 4), is_even) + ); + + ////////////////////////////////////////////////////////////////// + // any + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any(list()))); + BOOST_HANA_CONSTEXPR_CHECK(hana::any(list(logical(true)))); + BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::any(list(logical(false))))); + + + ////////////////////////////////////////////////////////////////// + // all_of + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK( + all_of(list(), invalid<>{}) + ); + BOOST_HANA_CONSTEXPR_CHECK( + all_of(list(c(0)), equal.to(c(0))) + ); + BOOST_HANA_CONSTEXPR_CHECK( + not_(all_of(list(c(0)), equal.to(c(1)))) + ); + BOOST_HANA_CONSTEXPR_CHECK(not_( + all_of(list(c(0), c(1)), equal.to(c(0))) + )); + BOOST_HANA_CONSTEXPR_CHECK( + all_of(list(c(0), c(0)), equal.to(c(0))) + ); + + BOOST_HANA_CONSTEXPR_CHECK(not_(all_of(list(1), is_even))); + BOOST_HANA_CONSTEXPR_CHECK(all_of(list(2), is_even)); + BOOST_HANA_CONSTEXPR_CHECK(all_of(list(2, 4), is_even)); + BOOST_HANA_CONSTEXPR_CHECK(not_(all_of(list(1, 2), is_even))); + BOOST_HANA_CONSTEXPR_CHECK(not_(all_of(list(1, 3), is_even))); + BOOST_HANA_CONSTEXPR_CHECK(not_(all_of(list(1, 3, 4), is_even))); + + + ////////////////////////////////////////////////////////////////// + // all + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(all(list())); + BOOST_HANA_CONSTEXPR_CHECK(all(list(logical(true)))); + BOOST_HANA_CONSTEXPR_CHECK(not_(all(list(logical(false))))); + BOOST_HANA_CONSTEXPR_CHECK(all(list(logical(true), logical(true)))); + BOOST_HANA_CONSTEXPR_CHECK(not_(all(list(logical(true), logical(false))))); + + ////////////////////////////////////////////////////////////////// + // none_of + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(none_of(list(), invalid<>{})); + BOOST_HANA_CONSTEXPR_CHECK(none_of(list(c(0)), equal.to(c(1)))); + BOOST_HANA_CONSTEXPR_CHECK(not_(none_of(list(c(0)), equal.to(c(0))))); + + BOOST_HANA_CONSTEXPR_CHECK(none_of(list(1), is_even)); + BOOST_HANA_CONSTEXPR_CHECK(not_(none_of(list(2), is_even))); + BOOST_HANA_CONSTEXPR_CHECK(not_(none_of(list(1, 2), is_even))); + BOOST_HANA_CONSTEXPR_CHECK(none_of(list(1, 3), is_even)); + BOOST_HANA_CONSTEXPR_CHECK(not_(none_of(list(1, 3, 4), is_even))); + + + ////////////////////////////////////////////////////////////////// + // none + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(none(list())); + BOOST_HANA_CONSTEXPR_CHECK(none(list(logical(false)))); + BOOST_HANA_CONSTEXPR_CHECK(not_(none(list(logical(true))))); + + ////////////////////////////////////////////////////////////////// + // find_if + ////////////////////////////////////////////////////////////////// + { + BOOST_HANA_CONSTANT_CHECK(equal( + find_if(list(), equal.to(x<9>{})), + nothing + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + find_if(list(x<0>{}), equal.to(x<9>{})), + nothing + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find_if(list(x<0>{}), equal.to(x<0>{})), + just(x<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find_if(list(x<0>{}, invalid<1>{}), equal.to(x<0>{})), + just(x<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find_if(list(x<0>{}, invalid<1>{}, invalid<2>{}), equal.to(x<0>{})), + just(x<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + find_if(list(x<0>{}, x<1>{}), equal.to(x<9>{})), + nothing + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find_if(list(x<0>{}, x<1>{}), equal.to(x<1>{})), + just(x<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find_if(list(x<0>{}, x<1>{}, invalid<2>{}), equal.to(x<1>{})), + just(x<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find_if(list(x<0>{}, x<1>{}, invalid<2>{}, invalid<3>{}), equal.to(x<1>{})), + just(x<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + find_if(list(x<0>{}, x<1>{}, x<2>{}), equal.to(x<9>{})), + nothing + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find_if(list(x<0>{}, x<1>{}, x<2>{}), equal.to(x<2>{})), + just(x<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find_if(list(x<0>{}, x<1>{}, x<2>{}, nothing), equal.to(x<2>{})), + just(x<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find_if(list(x<0>{}, x<1>{}, x<2>{}, nothing, nothing), equal.to(x<2>{})), + just(x<2>{}) + )); + + // Make sure find_if works with an lvalue sequence. hana::tuple + // used to have a bug that broke this. + auto const const_lvalue = list(x<0>{}, x<1>{}, x<2>{}); + BOOST_HANA_CONSTANT_CHECK(equal( + find_if(const_lvalue, equal.to(x<1>{})), + just(x<1>{}) + )); + + auto lvalue = list(x<0>{}, x<1>{}, x<2>{}); + BOOST_HANA_CONSTANT_CHECK(equal( + find_if(lvalue, equal.to(x<1>{})), + just(x<1>{}) + )); + } + + ////////////////////////////////////////////////////////////////// + // find + ////////////////////////////////////////////////////////////////// + { + BOOST_HANA_CONSTANT_CHECK(equal( + find(list(), invalid<>{}), + nothing + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + find(list(x<0>{}), x<9>{}), + nothing + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find(list(x<0>{}), x<0>{}), + just(x<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find(list(x<0>{}, invalid<1>{}), x<0>{}), + just(x<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find(list(x<0>{}, invalid<1>{}, invalid<2>{}), x<0>{}), + just(x<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + find(list(x<0>{}, x<1>{}), x<9>{}), + nothing + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find(list(x<0>{}, x<1>{}), x<1>{}), + just(x<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find(list(x<0>{}, x<1>{}, invalid<2>{}), x<1>{}), + just(x<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find(list(x<0>{}, x<1>{}, invalid<2>{}, invalid<3>{}), x<1>{}), + just(x<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + find(list(x<0>{}, x<1>{}, x<2>{}), x<9>{}), + nothing + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find(list(x<0>{}, x<1>{}, x<2>{}), x<2>{}), + just(x<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find(list(x<0>{}, x<1>{}, x<2>{}, nothing), x<2>{}), + just(x<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + find(list(x<0>{}, x<1>{}, x<2>{}, nothing, nothing), x<2>{}), + just(x<2>{}) + )); + } + + ////////////////////////////////////////////////////////////////// + // at_key + ////////////////////////////////////////////////////////////////// + { + BOOST_HANA_CONSTANT_CHECK(equal( + at_key(list(x<0>{}), x<0>{}), + x<0>{} + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + at_key(list(x<0>{}, x<1>{}), x<0>{}), + x<0>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + at_key(list(x<0>{}, x<1>{}), x<1>{}), + x<1>{} + )); + + BOOST_HANA_CONSTANT_CHECK(equal( + at_key(list(x<0>{}, x<1>{}, x<2>{}), x<0>{}), + x<0>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + at_key(list(x<0>{}, x<1>{}, x<2>{}), x<1>{}), + x<1>{} + )); + BOOST_HANA_CONSTANT_CHECK(equal( + at_key(list(x<0>{}, x<1>{}, x<2>{}), x<2>{}), + x<2>{} + )); + } + + ////////////////////////////////////////////////////////////////// + // contains + ////////////////////////////////////////////////////////////////// + { + BOOST_HANA_CONSTANT_CHECK(not_( + contains(list(), undefined{}) + )); + + BOOST_HANA_CONSTANT_CHECK(not_( + contains(list(x<0>{}), x<999>{}) + )); + + BOOST_HANA_CONSTANT_CHECK( + contains(list(x<0>{}), x<0>{}) + ); + + BOOST_HANA_CONSTANT_CHECK( + contains(list(x<0>{}, x<1>{}), x<1>{}) + ); + + BOOST_HANA_CONSTANT_CHECK( + contains(list(x<0>{}, x<1>{}, x<3>{}), x<3>{}) + ); + + BOOST_HANA_CONSTEXPR_CHECK(contains(list(c(0)), c(0))); + BOOST_HANA_CONSTEXPR_CHECK(not_(contains(list(c(0)), c(1)))); + + // infix application + BOOST_HANA_CONSTANT_CHECK( + list(x<0>{}, x<1>{}) ^contains^ x<1>{} + ); + } + + ////////////////////////////////////////////////////////////////// + // in + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTEXPR_CHECK(c(0) ^in^ list(c(0))); + BOOST_HANA_CONSTEXPR_CHECK(not_(c(1) ^in^ list(c(0)))); + + ////////////////////////////////////////////////////////////////// + // is_subset + ////////////////////////////////////////////////////////////////// + { + BOOST_HANA_CONSTANT_CHECK(is_subset( + list(), list(undefined{}) + )); + + BOOST_HANA_CONSTANT_CHECK(not_(is_subset( + list(undefined{}), list() + ))); + + BOOST_HANA_CONSTEXPR_CHECK(is_subset( + list(c(0)), list(c(0)) + )); + + BOOST_HANA_CONSTEXPR_CHECK(is_subset( + list(c(0)), list(c(0), c(1)) + )); + + BOOST_HANA_CONSTEXPR_CHECK(not_(is_subset( + list(c(0)), list(c(1)) + ))); + + // infix application + BOOST_HANA_CONSTANT_CHECK( + list(x<0>{}) ^is_subset^ list(x<1>{}, x<0>{}) + ); + + BOOST_HANA_CONSTANT_CHECK( + list(x<0>{}, x<1>{}) ^is_subset^ list(x<1>{}, x<0>{}) + ); + } + + ////////////////////////////////////////////////////////////////// + // is_disjoint + ////////////////////////////////////////////////////////////////// + { + BOOST_HANA_CONSTANT_CHECK(is_disjoint( + list(), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(is_disjoint( + list(), + list(undefined{}) + )); + BOOST_HANA_CONSTANT_CHECK(is_disjoint( + list(undefined{}), + list() + )); + + BOOST_HANA_CONSTANT_CHECK(is_disjoint( + list(x<0>{}), + list(x<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(is_disjoint( + list(x<1>{}), + list(x<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(not_(is_disjoint( + list(x<0>{}), + list(x<0>{}) + ))); + + + BOOST_HANA_CONSTANT_CHECK(not_(is_disjoint( + list(x<0>{}, x<1>{}), + list(x<0>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(not_(is_disjoint( + list(x<0>{}), + list(x<0>{}, x<1>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(not_(is_disjoint( + list(x<1>{}, x<0>{}), + list(x<0>{}, x<1>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(not_(is_disjoint( + list(x<0>{}, x<1>{}), + list(x<1>{}, x<2>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(is_disjoint( + list(x<0>{}, x<1>{}), + list(x<2>{}, x<3>{}) + )); + } + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_SEARCHABLE_HPP diff --git a/src/boost/libs/hana/test/_include/laws/sequence.hpp b/src/boost/libs/hana/test/_include/laws/sequence.hpp new file mode 100644 index 000000000..cc04590ea --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/sequence.hpp @@ -0,0 +1,133 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_HANA_TEST_LAWS_SEQUENCE_HPP +#define BOOST_HANA_TEST_LAWS_SEQUENCE_HPP + +#include <boost/hana/assert.hpp> +#include <boost/hana/concept/sequence.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/core/tag_of.hpp> +#include <boost/hana/functional/capture.hpp> +#include <boost/hana/functional/compose.hpp> +#include <boost/hana/functional/id.hpp> +#include <boost/hana/functional/partial.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/optional.hpp> +#include <boost/hana/plus.hpp> +#include <boost/hana/range.hpp> +#include <boost/hana/tuple.hpp> + +#include <laws/base.hpp> +#include <support/minimal_product.hpp> +#include <support/seq.hpp> + +#include <type_traits> +#include <vector> + + +namespace boost { namespace hana { namespace test { + template <typename S, typename = when<true>> + struct TestSequence : TestSequence<S, laws> { + using TestSequence<S, laws>::TestSequence; + }; + + template <typename S> + struct TestSequence<S, laws> { + template <int i> + using eq = integer<i, + Policy::Comparable + | Policy::Constant + >; + + template <int i> + using cx_eq = integer<i, + Policy::Comparable + | Policy::Constexpr + >; + + template <int i> + using ord = integer<i, + Policy::Orderable + | Policy::Constant + >; + + struct undefined { }; + + TestSequence() { + constexpr auto list = make<S>; (void)list; + constexpr auto foldable = ::seq; (void)foldable; + + ////////////////////////////////////////////////////////////////// + // Check for Sequence<...> + ////////////////////////////////////////////////////////////////// + static_assert(Sequence<decltype(list())>{}, ""); + static_assert(Sequence<decltype(list(1))>{}, ""); + static_assert(Sequence<decltype(list(1, '2'))>{}, ""); + static_assert(Sequence<decltype(list(1, '2', 3.4))>{}, ""); + + ////////////////////////////////////////////////////////////////// + // Check for basic tag consistency + ////////////////////////////////////////////////////////////////// + struct Random; + static_assert(std::is_same<tag_of_t<decltype(list())>, S>{}, ""); + static_assert(std::is_same<tag_of_t<decltype(list(1))>, S>{}, ""); + static_assert(std::is_same<tag_of_t<decltype(list(1, '2'))>, S>{}, ""); + static_assert(std::is_same<tag_of_t<decltype(list(1, '2', 3.3))>, S>{}, ""); + static_assert(!std::is_same<tag_of_t<Random>, S>{}, ""); + + ////////////////////////////////////////////////////////////////// + // Foldable -> Sequence conversion + ////////////////////////////////////////////////////////////////// + { + BOOST_HANA_CONSTANT_CHECK(equal( + to<S>(foldable()), + list() + )); + BOOST_HANA_CONSTANT_CHECK(equal( + to<S>(foldable(eq<0>{})), + list(eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + to<S>(foldable(eq<0>{}, eq<1>{})), + list(eq<0>{}, eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + to<S>(foldable(eq<0>{}, eq<1>{}, eq<2>{})), + list(eq<0>{}, eq<1>{}, eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + to<S>(foldable(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{})), + list(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{}) + )); + } + + ////////////////////////////////////////////////////////////////// + // make (tautological given our definition of `list`) + ////////////////////////////////////////////////////////////////// + BOOST_HANA_CONSTANT_CHECK(equal( + make<S>(), + list() + )); + BOOST_HANA_CONSTANT_CHECK(equal( + make<S>(eq<0>{}), + list(eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + make<S>(eq<0>{}, eq<1>{}), + list(eq<0>{}, eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + make<S>(eq<0>{}, eq<1>{}, eq<2>{}), + list(eq<0>{}, eq<1>{}, eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(equal( + make<S>(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{}), + list(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{}) + )); + } + }; +}}} // end namespace boost::hana::test + +#endif // !BOOST_HANA_TEST_LAWS_SEQUENCE_HPP diff --git a/src/boost/libs/hana/test/_include/laws/templates/seq.hpp b/src/boost/libs/hana/test/_include/laws/templates/seq.hpp new file mode 100644 index 000000000..72438fc50 --- /dev/null +++ b/src/boost/libs/hana/test/_include/laws/templates/seq.hpp @@ -0,0 +1,132 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#include <boost/hana/bool.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/functional/always.hpp> +#include <boost/hana/tuple.hpp> + +#include <laws/applicative.hpp> +#include <laws/base.hpp> +#include <laws/comparable.hpp> +#include <laws/foldable.hpp> +#include <laws/functor.hpp> +#include <laws/iterable.hpp> +#include <laws/monad.hpp> +#include <laws/monad_plus.hpp> +#include <laws/orderable.hpp> +#include <laws/searchable.hpp> +#include <laws/sequence.hpp> +#include <support/seq.hpp> +namespace hana = boost::hana; +using hana::test::ct_eq; +using hana::test::ct_ord; + + +int main() { + auto eqs = hana::make_tuple( + ::seq() + , ::seq(ct_eq<0>{}) + , ::seq(ct_eq<0>{}, ct_eq<1>{}) + , ::seq(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}) + , ::seq(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}) + ); + (void)eqs; + + auto nested_eqs = hana::make_tuple( + ::seq() + , ::seq( + ::seq(ct_eq<0>{})) + , ::seq( + ::seq(ct_eq<0>{}), + ::seq(ct_eq<1>{}, ct_eq<2>{})) + , ::seq( + ::seq(ct_eq<0>{}), + ::seq(ct_eq<1>{}, ct_eq<2>{}), + ::seq(ct_eq<3>{}, ct_eq<4>{})) + ); + (void)nested_eqs; + + auto eq_keys = hana::make_tuple(ct_eq<0>{}, ct_eq<3>{}, ct_eq<10>{}); + (void)eq_keys; + + auto predicates = hana::make_tuple( + hana::equal.to(ct_eq<0>{}), hana::equal.to(ct_eq<3>{}), hana::equal.to(ct_eq<10>{}), + hana::always(hana::true_c), hana::always(hana::false_c) + ); + (void)predicates; + + auto ords = hana::make_tuple( + ::seq() + , ::seq(ct_ord<0>{}) + , ::seq(ct_ord<0>{}, ct_ord<1>{}) + , ::seq(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}) + , ::seq(ct_ord<0>{}, ct_ord<1>{}, ct_ord<2>{}, ct_ord<3>{}) + ); + (void)ords; + + ////////////////////////////////////////////////////////////////////////// + // Comparable, Orderable + ////////////////////////////////////////////////////////////////////////// +#ifdef BOOST_HANA_TEST_ORDERABLE + hana::test::TestComparable<::Seq>{eqs}; + hana::test::TestOrderable<::Seq>{ords}; +#endif + +#ifdef BOOST_HANA_TEST_ITERABLE + ////////////////////////////////////////////////////////////////////////// + // Foldable + ////////////////////////////////////////////////////////////////////////// + hana::test::TestFoldable<::Seq>{eqs}; + + ////////////////////////////////////////////////////////////////////////// + // Iterable + ////////////////////////////////////////////////////////////////////////// + { + hana::test::TestIterable<::Seq>{eqs}; + } +#endif + + ////////////////////////////////////////////////////////////////////////// + // Searchable + ////////////////////////////////////////////////////////////////////////// +#ifdef BOOST_HANA_TEST_SEARCHABLE + { + hana::test::TestSearchable<::Seq>{eqs, eq_keys}; + + auto bools = hana::make_tuple( + ::seq(hana::true_c) + , ::seq(hana::false_c) + , ::seq(hana::true_c, hana::true_c) + , ::seq(hana::true_c, hana::false_c) + , ::seq(hana::false_c, hana::true_c) + , ::seq(hana::false_c, hana::false_c) + ); + hana::test::TestSearchable<::Seq>{bools, hana::make_tuple(hana::true_c, hana::false_c)}; + } +#endif + + ////////////////////////////////////////////////////////////////////////// + // Functor, Applicative, Monad + ////////////////////////////////////////////////////////////////////////// +#ifdef BOOST_HANA_TEST_MONAD + hana::test::TestFunctor<::Seq>{eqs, eq_keys}; + hana::test::TestApplicative<::Seq>{eqs}; + hana::test::TestMonad<::Seq>{eqs, nested_eqs}; +#endif + + ////////////////////////////////////////////////////////////////////////// + // MonadPlus + ////////////////////////////////////////////////////////////////////////// +#ifdef BOOST_HANA_TEST_MONAD_PLUS + hana::test::TestMonadPlus<::Seq>{eqs, predicates, eq_keys}; +#endif + + ////////////////////////////////////////////////////////////////////////// + // Sequence + ////////////////////////////////////////////////////////////////////////// +#ifdef BOOST_HANA_TEST_SEQUENCE + hana::test::TestSequence<::Seq>{}; +#endif +} diff --git a/src/boost/libs/hana/test/_include/support/cnumeric.hpp b/src/boost/libs/hana/test/_include/support/cnumeric.hpp new file mode 100644 index 000000000..51575a40f --- /dev/null +++ b/src/boost/libs/hana/test/_include/support/cnumeric.hpp @@ -0,0 +1,66 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef TEST_SUPPORT_CNUMERIC_HPP +#define TEST_SUPPORT_CNUMERIC_HPP + +#include <boost/hana/concept/integral_constant.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/fwd/core/to.hpp> +#include <boost/hana/fwd/equal.hpp> +#include <boost/hana/fwd/less.hpp> + + +template <typename T> +struct CNumeric { using value_type = T; }; + +template <typename T, T v> +struct cnumeric_t { + static constexpr T value = v; + using hana_tag = CNumeric<T>; + constexpr operator T() const { return value; } +}; + +template <typename T, T v> +constexpr cnumeric_t<T, v> cnumeric{}; + +template <typename T, T v> +constexpr cnumeric_t<T, v> make_cnumeric() { return {}; } + +namespace boost { namespace hana { + // Constant and IntegralConstant + template <typename T> + struct IntegralConstant<CNumeric<T>> { + static constexpr bool value = true; + }; + + template <typename T, typename C> + struct to_impl<CNumeric<T>, C, when< + hana::IntegralConstant<C>::value + >> + : embedding<is_embedded<typename C::value_type, T>::value> + { + template <typename N> + static constexpr auto apply(N const&) + { return cnumeric<T, N::value>; } + }; + + // Comparable + template <typename T, typename U> + struct equal_impl<CNumeric<T>, CNumeric<U>> { + template <typename X, typename Y> + static constexpr auto apply(X const&, Y const&) + { return cnumeric<bool, X::value == Y::value>; } + }; + + // Orderable + template <typename T, typename U> + struct less_impl<CNumeric<T>, CNumeric<U>> { + template <typename X, typename Y> + static constexpr auto apply(X const&, Y const&) + { return cnumeric<bool, (X::value < Y::value)>; } + }; +}} // end namespace boost::hana + +#endif // !TEST_SUPPORT_CNUMERIC_HPP diff --git a/src/boost/libs/hana/test/_include/support/constexpr_move_only.hpp b/src/boost/libs/hana/test/_include/support/constexpr_move_only.hpp new file mode 100644 index 000000000..bdc234afe --- /dev/null +++ b/src/boost/libs/hana/test/_include/support/constexpr_move_only.hpp @@ -0,0 +1,41 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef TEST_SUPPORT_CONSTEXPR_MOVE_ONLY_HPP +#define TEST_SUPPORT_CONSTEXPR_MOVE_ONLY_HPP + +#include <boost/hana/bool.hpp> +#include <boost/hana/fwd/hash.hpp> +#include <boost/hana/type.hpp> + +#include <utility> + + +// A move-only type that's also a literal type. It is also Comparable and +// Hashable so it can be used in associative containers. +template <int i> +struct ConstexprMoveOnly { + constexpr ConstexprMoveOnly() { } + constexpr ConstexprMoveOnly(ConstexprMoveOnly const&) = delete; + constexpr ConstexprMoveOnly& operator=(ConstexprMoveOnly const&) = delete; + constexpr ConstexprMoveOnly(ConstexprMoveOnly&&) { } +}; + +template <int i, int j> +constexpr auto operator==(ConstexprMoveOnly<i> const&, ConstexprMoveOnly<j> const&) +{ return boost::hana::bool_c<i == j>; } + +template <int i, int j> +constexpr auto operator!=(ConstexprMoveOnly<i> const&, ConstexprMoveOnly<j> const&) +{ return boost::hana::bool_c<i != j>; } + +namespace boost { namespace hana { + template <int i> + struct hash_impl<ConstexprMoveOnly<i>> { + static constexpr auto apply(ConstexprMoveOnly<i> const&) + { return hana::type_c<ConstexprMoveOnly<i>>; }; + }; +}} + +#endif // !TEST_SUPPORT_CONSTEXPR_MOVE_ONLY_HPP diff --git a/src/boost/libs/hana/test/_include/support/counter.hpp b/src/boost/libs/hana/test/_include/support/counter.hpp new file mode 100644 index 000000000..4640363d7 --- /dev/null +++ b/src/boost/libs/hana/test/_include/support/counter.hpp @@ -0,0 +1,56 @@ +// Copyright Louis Dionne 2013-2017 +// Copyright Jason Rice 2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef TEST_SUPPORT_COUNTER_HPP +#define TEST_SUPPORT_COUNTER_HPP + +#include <boost/hana/fwd/at.hpp> +#include <boost/hana/fwd/concept/iterable.hpp> +#include <boost/hana/fwd/drop_front.hpp> +#include <boost/hana/fwd/is_empty.hpp> +#include <boost/hana/integral_constant.hpp> + + +// Counter - an infinite iterable for the masses + +struct Counter_tag { }; + +template <std::size_t N = 0> +struct Counter { + using hana_tag = Counter_tag; + static constexpr std::size_t value = N; +}; + + +namespace boost { namespace hana { + ////////////////////////////////////////////////////////////////////////// + // Iterable + ////////////////////////////////////////////////////////////////////////// + template <> + struct at_impl<Counter_tag> { + template <typename T, typename N> + static constexpr decltype(auto) apply(T, N) { + return hana::size_c<T::value + N::value>; + } + }; + + template <> + struct drop_front_impl<Counter_tag> { + template <typename T, typename N> + static constexpr auto apply(T, N) { + return Counter<T::value + N::value>{}; + } + }; + + template <> + struct is_empty_impl<Counter_tag> { + template <typename Xs> + static constexpr auto apply(Xs) + -> hana::false_ + { return {}; } + }; +}} // end namespace boost::hana + +#endif // !TEST_SUPPORT_COUNTER_HPP diff --git a/src/boost/libs/hana/test/_include/support/equivalence_class.hpp b/src/boost/libs/hana/test/_include/support/equivalence_class.hpp new file mode 100644 index 000000000..c5e8d72e6 --- /dev/null +++ b/src/boost/libs/hana/test/_include/support/equivalence_class.hpp @@ -0,0 +1,34 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef TEST_SUPPORT_EQUIVALENCE_CLASS_HPP +#define TEST_SUPPORT_EQUIVALENCE_CLASS_HPP + +#include <boost/hana/fwd/equal.hpp> + + +struct EquivalenceClass { }; + +template <typename Token, typename T> +struct equivalence_class_impl { + Token equivalence_class; + T unwrap; + using hana_tag = EquivalenceClass; +}; + +template <typename Token, typename X> +constexpr equivalence_class_impl<Token, X> equivalence_class(Token token, X x) { + return {token, x}; +} + +namespace boost { namespace hana { + template <> + struct equal_impl<EquivalenceClass, EquivalenceClass> { + template <typename X, typename Y> + static constexpr auto apply(X x, Y y) + { return hana::equal(x.equivalence_class, y.equivalence_class); } + }; +}} // end namespace boost::hana + +#endif // !TEST_SUPPORT_EQUIVALENCE_CLASS_HPP diff --git a/src/boost/libs/hana/test/_include/support/identity.hpp b/src/boost/libs/hana/test/_include/support/identity.hpp new file mode 100644 index 000000000..c6799cbe8 --- /dev/null +++ b/src/boost/libs/hana/test/_include/support/identity.hpp @@ -0,0 +1,159 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef TEST_SUPPORT_IDENTITY_HPP +#define TEST_SUPPORT_IDENTITY_HPP + +#include <boost/hana/chain.hpp> +#include <boost/hana/eval_if.hpp> +#include <boost/hana/functional/compose.hpp> +#include <boost/hana/functional/partial.hpp> +#include <boost/hana/fwd/adjust_if.hpp> +#include <boost/hana/fwd/ap.hpp> +#include <boost/hana/fwd/equal.hpp> +#include <boost/hana/fwd/flatten.hpp> +#include <boost/hana/fwd/less.hpp> +#include <boost/hana/fwd/lift.hpp> +#include <boost/hana/lazy.hpp> +#include <boost/hana/transform.hpp> + +#include <type_traits> + + +struct Identity; + +template <typename T> +struct identity_t { + T value; + using hana_tag = Identity; +}; + +struct make_identity { + template <typename T> + constexpr identity_t<typename std::decay<T>::type> operator()(T&& t) const { + return {static_cast<T&&>(t)}; + } +}; + +constexpr make_identity identity{}; + + +namespace boost { namespace hana { + ////////////////////////////////////////////////////////////////////////// + // Comparable + ////////////////////////////////////////////////////////////////////////// + template <> + struct equal_impl<Identity, Identity> { + template <typename Id1, typename Id2> + static constexpr auto apply(Id1 x, Id2 y) + { return hana::equal(x.value, y.value); } + }; + + ////////////////////////////////////////////////////////////////////////// + // Orderable + ////////////////////////////////////////////////////////////////////////// + template <> + struct less_impl<Identity, Identity> { + template <typename Id1, typename Id2> + static constexpr auto apply(Id1 x, Id2 y) + { return hana::less(x.value, y.value); } + }; + + ////////////////////////////////////////////////////////////////////////// + // Functor + // + // Define either one to select which MCD is used: + // BOOST_HANA_TEST_FUNCTOR_TRANSFORM_MCD + // BOOST_HANA_TEST_FUNCTOR_ADJUST_MCD_MCD + // + // If neither is defined, the MCD used is unspecified. + ////////////////////////////////////////////////////////////////////////// +#ifdef BOOST_HANA_TEST_FUNCTOR_TRANSFORM_MCD + template <> + struct transform_impl<Identity> { + template <typename Id, typename F> + static constexpr auto apply(Id self, F f) + { return ::identity(f(self.value)); } + }; +#else + template <> + struct adjust_if_impl<Identity> { + struct get_value { + template <typename T> + constexpr auto operator()(T t) const { return t.value; } + }; + + template <typename Id, typename P, typename F> + static constexpr auto apply(Id self, P p, F f) { + auto x = hana::eval_if(p(self.value), + hana::make_lazy(hana::compose(f, get_value{}))(self), + hana::make_lazy(get_value{})(self) + ); + return ::identity(x); + } + }; +#endif + + ////////////////////////////////////////////////////////////////////////// + // Applicative + // + // Define either one to select which MCD is used: + // BOOST_HANA_TEST_APPLICATIVE_FULL_MCD + // BOOST_HANA_TEST_APPLICATIVE_MONAD_MCD + // + // If neither is defined, the MCD used is unspecified. + ////////////////////////////////////////////////////////////////////////// + template <> + struct lift_impl<Identity> { + template <typename X> + static constexpr auto apply(X x) + { return ::identity(x); } + }; +#ifdef BOOST_HANA_TEST_APPLICATIVE_FULL_MCD + template <> + struct ap_impl<Identity> { + template <typename F, typename X> + static constexpr auto apply(F f, X x) + { return ::identity(f.value(x.value)); } + }; +#else + template <> + struct ap_impl<Identity> { + template <typename F, typename X> + static constexpr decltype(auto) apply(F&& f, X&& x) { + return hana::chain( + static_cast<F&&>(f), + hana::partial(hana::transform, static_cast<X&&>(x)) + ); + } + }; +#endif + + ////////////////////////////////////////////////////////////////////////// + // Monad + // + // Define either one to select which MCD is used: + // BOOST_HANA_TEST_MONAD_FLATTEN_MCD + // BOOST_HANA_TEST_MONAD_CHAIN_MCD + // + // If neither is defined, the MCD used is unspecified. + ////////////////////////////////////////////////////////////////////////// +#ifdef BOOST_HANA_TEST_MONAD_FLATTEN_MCD + template <> + struct flatten_impl<Identity> { + template <typename Id> + static constexpr auto apply(Id self) + { return self.value; } + }; +#else + template <> + struct chain_impl<Identity> { + template <typename X, typename F> + static constexpr auto apply(X x, F f) + { return f(x.value); } + }; +#endif +}} // end namespace boost::hana + +#endif // !TEST_SUPPORT_IDENTITY_HPP diff --git a/src/boost/libs/hana/test/_include/support/minimal_product.hpp b/src/boost/libs/hana/test/_include/support/minimal_product.hpp new file mode 100644 index 000000000..1fe39f786 --- /dev/null +++ b/src/boost/libs/hana/test/_include/support/minimal_product.hpp @@ -0,0 +1,61 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef TEST_SUPPORT_MINIMAL_PRODUCT_HPP +#define TEST_SUPPORT_MINIMAL_PRODUCT_HPP + +#include <boost/hana/fwd/core/make.hpp> +#include <boost/hana/fwd/first.hpp> +#include <boost/hana/fwd/second.hpp> + +#include <type_traits> + + +struct MinimalProduct; + +template <typename X, typename Y> +struct product_t { + X fst; + Y snd; + using hana_tag = MinimalProduct; +}; + +struct make_minimal_product { + template <typename T, typename U> + constexpr product_t<typename std::decay<T>::type, + typename std::decay<U>::type> + operator()(T&& t, U&& u) const { + return {static_cast<T&&>(t), static_cast<U&&>(u)}; + } +}; + +constexpr make_minimal_product minimal_product{}; + +namespace boost { namespace hana { + ////////////////////////////////////////////////////////////////////////// + // Product + ////////////////////////////////////////////////////////////////////////// + template <> + struct make_impl<MinimalProduct> { + template <typename X, typename Y> + static constexpr auto apply(X x, Y y) + { return ::minimal_product(x, y); } + }; + + template <> + struct first_impl<MinimalProduct> { + template <typename P> + static constexpr decltype(auto) apply(P&& p) + { return p.fst; } + }; + + template <> + struct second_impl<MinimalProduct> { + template <typename P> + static constexpr decltype(auto) apply(P&& p) + { return p.snd; } + }; +}} // end namespace boost::hana + +#endif // !TEST_SUPPORT_MINIMAL_PRODUCT_HPP diff --git a/src/boost/libs/hana/test/_include/support/numeric.hpp b/src/boost/libs/hana/test/_include/support/numeric.hpp new file mode 100644 index 000000000..2aebe7664 --- /dev/null +++ b/src/boost/libs/hana/test/_include/support/numeric.hpp @@ -0,0 +1,175 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef TEST_SUPPORT_NUMERIC_HPP +#define TEST_SUPPORT_NUMERIC_HPP + +#include <boost/hana/core/tag_of.hpp> +#include <boost/hana/eval.hpp> +#include <boost/hana/fwd/div.hpp> +#include <boost/hana/fwd/equal.hpp> +#include <boost/hana/fwd/eval_if.hpp> +#include <boost/hana/fwd/less.hpp> +#include <boost/hana/fwd/minus.hpp> +#include <boost/hana/fwd/mod.hpp> +#include <boost/hana/fwd/mult.hpp> +#include <boost/hana/fwd/negate.hpp> +#include <boost/hana/fwd/not.hpp> +#include <boost/hana/fwd/one.hpp> +#include <boost/hana/fwd/plus.hpp> +#include <boost/hana/fwd/while.hpp> +#include <boost/hana/fwd/zero.hpp> + + +struct numeric_type { + constexpr explicit numeric_type(int v) : value(v) { } + int value; + constexpr operator int() const { return value; } +}; + +using Numeric = boost::hana::tag_of_t<numeric_type>; + +struct numeric_t { + constexpr numeric_type operator()(int x) const { + return numeric_type{x}; + } +}; +constexpr numeric_t numeric{}; + + +namespace boost { namespace hana { + ////////////////////////////////////////////////////////////////////////// + // Comparable + ////////////////////////////////////////////////////////////////////////// + template <> + struct equal_impl<Numeric, Numeric> { + template <typename X, typename Y> + static constexpr auto apply(X x, Y y) + { return numeric(x.value == y.value); } + }; + + ////////////////////////////////////////////////////////////////////////// + // Orderable + ////////////////////////////////////////////////////////////////////////// + template <> + struct less_impl<Numeric, Numeric> { + template <typename X, typename Y> + static constexpr auto apply(X x, Y y) { + // Workaround a _weird_ GCC bug: + // error: parse error in template argument list + // bool cmp = (x.value < y.value); + // ^ + int xv = x.value, yv = y.value; + return numeric(xv < yv); + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Logical + ////////////////////////////////////////////////////////////////////////// + template <> + struct eval_if_impl<Numeric> { + template <typename C, typename T, typename E> + static constexpr auto apply(C const& c, T&& t, E&& e) { + return c.value ? hana::eval(static_cast<T&&>(t)) + : hana::eval(static_cast<E&&>(e)); + } + }; + + template <> + struct not_impl<Numeric> { + template <typename X> + static constexpr auto apply(X x) + { return numeric(!x.value); } + }; + + template <> + struct while_impl<Numeric> { + template <typename Pred, typename State, typename F> + static constexpr auto apply(Pred pred, State state, F f) + -> decltype(true ? f(state) : state) + { + if (pred(state)) + return hana::while_(pred, f(state), f); + else + return state; + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Monoid + ////////////////////////////////////////////////////////////////////////// + template <> + struct plus_impl<Numeric, Numeric> { + template <typename X, typename Y> + static constexpr auto apply(X x, Y y) + { return numeric(x.value + y.value); } + }; + + template <> + struct zero_impl<Numeric> { + static constexpr auto apply() + { return numeric(0); } + }; + + ////////////////////////////////////////////////////////////////////////// + // Group + // + // Define either one to select which MCD is used: + // BOOST_HANA_TEST_GROUP_NEGATE_MCD + // BOOST_HANA_TEST_GROUP_MINUS_MCD + // + // If neither is defined, the MCD used is unspecified. + ////////////////////////////////////////////////////////////////////////// +#if defined(BOOST_HANA_TEST_GROUP_NEGATE_MCD) + template <> + struct negate_impl<Numeric> { + template <typename X> + static constexpr auto apply(X x) + { return numeric(-x.value); } + }; +#else + template <> + struct minus_impl<Numeric, Numeric> { + template <typename X, typename Y> + static constexpr auto apply(X x, Y y) + { return numeric(x.value - y.value); } + }; +#endif + + ////////////////////////////////////////////////////////////////////////// + // Ring + ////////////////////////////////////////////////////////////////////////// + template <> + struct mult_impl<Numeric, Numeric> { + template <typename X, typename Y> + static constexpr auto apply(X x, Y y) + { return numeric(x.value * y.value); } + }; + + template <> + struct one_impl<Numeric> { + static constexpr auto apply() + { return numeric(1); } + }; + + ////////////////////////////////////////////////////////////////////////// + // EuclideanRing + ////////////////////////////////////////////////////////////////////////// + template <> + struct div_impl<Numeric, Numeric> { + template <typename X, typename Y> + static constexpr auto apply(X x, Y y) + { return numeric(x.value / y.value); } + }; + + template <> + struct mod_impl<Numeric, Numeric> { + template <typename X, typename Y> + static constexpr auto apply(X x, Y y) + { return numeric(x.value % y.value); } + }; +}} // end namespace boost::hana + +#endif //! TEST_SUPPORT_NUMERIC_HPP diff --git a/src/boost/libs/hana/test/_include/support/seq.hpp b/src/boost/libs/hana/test/_include/support/seq.hpp new file mode 100644 index 000000000..ee222dc01 --- /dev/null +++ b/src/boost/libs/hana/test/_include/support/seq.hpp @@ -0,0 +1,122 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef TEST_SUPPORT_SEQ_HPP +#define TEST_SUPPORT_SEQ_HPP + +#include <boost/hana/fwd/at.hpp> +#include <boost/hana/fwd/concept/sequence.hpp> +#include <boost/hana/fwd/core/make.hpp> +#include <boost/hana/fwd/drop_front.hpp> +#include <boost/hana/fwd/fold_left.hpp> +#include <boost/hana/fwd/is_empty.hpp> +#include <boost/hana/fwd/length.hpp> +#include <boost/hana/tuple.hpp> +#include <boost/hana/unpack.hpp> + + +struct Seq; + +template <typename Storage> +struct seq_type { + explicit constexpr seq_type(Storage s) : storage(s) { } + Storage storage; + using hana_tag = Seq; +}; + +struct seq_t { + template <typename ...Xs> + constexpr auto operator()(Xs&& ...xs) const { + auto storage = boost::hana::make_tuple(xs...); + return seq_type<decltype(storage)>(storage); + } +}; +constexpr seq_t seq{}; + +namespace boost { namespace hana { + ////////////////////////////////////////////////////////////////////////// + // Foldable + // + // Define either one to select which MCD is used: + // BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD + // BOOST_HANA_TEST_FOLDABLE_UNPACK_MCD + // BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD + // + // If neither is defined, the MCD used is unspecified. + ////////////////////////////////////////////////////////////////////////// +#ifdef BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD + template <> + struct fold_left_impl<Seq> { + template <typename Xs, typename S, typename F> + static constexpr auto apply(Xs xs, S s, F f) { + return hana::fold_left(xs.storage, s, f); + } + + template <typename Xs, typename F> + static constexpr auto apply(Xs xs, F f) { + return hana::fold_left(xs.storage, f); + } + }; +#elif defined(BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD) + template <> + struct length_impl<Seq> { + template <typename Xs> + static constexpr auto apply(Xs const& xs) { + return hana::length(xs.storage); + } + }; +#else + template <> + struct unpack_impl<Seq> { + template <typename Xs, typename F> + static constexpr auto apply(Xs xs, F f) + { return hana::unpack(xs.storage, f); } + }; +#endif + + ////////////////////////////////////////////////////////////////////////// + // Iterable + ////////////////////////////////////////////////////////////////////////// + template <> + struct at_impl<Seq> { + template <typename Xs, typename N> + static constexpr decltype(auto) apply(Xs&& xs, N&& n) { + return hana::at(static_cast<Xs&&>(xs).storage, n); + } + }; + + template <> + struct drop_front_impl<Seq> { + template <typename Xs, typename N> + static constexpr auto apply(Xs xs, N n) { + return hana::unpack(hana::drop_front(xs.storage, n), ::seq); + } + }; + + template <> + struct is_empty_impl<Seq> { + template <typename Xs> + static constexpr auto apply(Xs xs) { + return hana::is_empty(xs.storage); + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Sequence + ////////////////////////////////////////////////////////////////////////// + template <> + struct Sequence<Seq> { + static constexpr bool value = true; + }; + + template <> + struct make_impl<Seq> { + template <typename ...Xs> + static constexpr auto apply(Xs&& ...xs) { + return ::seq(static_cast<Xs&&>(xs)...); + } + }; +}} // end namespace boost::hana + +#endif // !TEST_SUPPORT_SEQ_HPP diff --git a/src/boost/libs/hana/test/_include/support/tracked.hpp b/src/boost/libs/hana/test/_include/support/tracked.hpp new file mode 100644 index 000000000..215ffba4d --- /dev/null +++ b/src/boost/libs/hana/test/_include/support/tracked.hpp @@ -0,0 +1,120 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef TEST_SUPPORT_TRACKED_HPP +#define TEST_SUPPORT_TRACKED_HPP + +// Define this if you want Tracked objects to print information to stderr. +// #define TRACKED_PRINT_STUFF + +#include <boost/hana/assert.hpp> + +#ifdef TRACKED_PRINT_STUFF +# include <iostream> +#endif + +#include <iosfwd> + + +struct Tracked { + enum class State { CONSTRUCTED, MOVED_FROM, DESTROYED }; + + int value; + State state; + + explicit Tracked(int k) : value{k}, state{State::CONSTRUCTED} { +#ifdef TRACKED_PRINT_STUFF + std::cerr << "constructing " << *this << '\n'; +#endif + } + + Tracked(Tracked const& t) : value{t.value}, state{State::CONSTRUCTED} { + BOOST_HANA_RUNTIME_CHECK(t.state != State::MOVED_FROM && + "copying a moved-from object"); + + BOOST_HANA_RUNTIME_CHECK(t.state != State::DESTROYED && + "copying a destroyed object"); + +#ifdef TRACKED_PRINT_STUFF + std::cerr << "copying " << *this << '\n'; +#endif + } + + Tracked(Tracked&& t) : value{t.value}, state{State::CONSTRUCTED} { + BOOST_HANA_RUNTIME_CHECK(t.state != State::MOVED_FROM && + "double moving from an object"); + + BOOST_HANA_RUNTIME_CHECK(t.state != State::DESTROYED && + "moving from a destroyed object"); + +#ifdef TRACKED_PRINT_STUFF + std::cerr << "moving " << t << '\n'; +#endif + t.state = State::MOVED_FROM; + } + + Tracked& operator=(Tracked const& other) { + BOOST_HANA_RUNTIME_CHECK(this->state != State::DESTROYED && + "assigning to a destroyed object"); + + BOOST_HANA_RUNTIME_CHECK(other.state != State::MOVED_FROM && + "assigning a moved-from object"); + + BOOST_HANA_RUNTIME_CHECK(other.state != State::DESTROYED && + "assigning a destroyed object"); + +#ifdef TRACKED_PRINT_STUFF + std::cerr << "assigning " << other << " to " << *this << '\n'; +#endif + this->value = other.value; + return *this; + } + + Tracked& operator=(Tracked&& other) { + BOOST_HANA_RUNTIME_CHECK(this->state != State::DESTROYED && + "assigning to a destroyed object"); + + BOOST_HANA_RUNTIME_CHECK(other.state != State::MOVED_FROM && + "double-moving from an object"); + + BOOST_HANA_RUNTIME_CHECK(other.state != State::DESTROYED && + "assigning a destroyed object"); + +#ifdef TRACKED_PRINT_STUFF + std::cerr << "assigning " << other << " to " << *this << '\n'; +#endif + this->value = other.value; + other.state = State::MOVED_FROM; + return *this; + } + + ~Tracked() { + BOOST_HANA_RUNTIME_CHECK(state != State::DESTROYED && + "double-destroying an object"); + +#ifdef TRACKED_PRINT_STUFF + std::cerr << "destructing " << *this << '\n'; +#endif + state = State::DESTROYED; + } + + template <typename CharT, typename Traits> + friend std::basic_ostream<CharT, Traits>& + operator<<(std::basic_ostream<CharT, Traits>& os, Tracked const& t) { + os << "Tracked{" << t.value << "}"; + switch (t.state) { + case State::CONSTRUCTED: + os << "[ok]"; break; + case State::MOVED_FROM: + os << "[moved from]"; break; + case State::DESTROYED: + os << "[destroyed]"; break; + default: + BOOST_HANA_RUNTIME_CHECK(false && "never reached"); + } + return os; + } +}; + +#endif // !TEST_SUPPORT_TRACKED_HPP diff --git a/src/boost/libs/hana/test/_include/support/tracked_move_only.hpp b/src/boost/libs/hana/test/_include/support/tracked_move_only.hpp new file mode 100644 index 000000000..03e9d5da6 --- /dev/null +++ b/src/boost/libs/hana/test/_include/support/tracked_move_only.hpp @@ -0,0 +1,45 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#ifndef TEST_SUPPORT_TRACKED_MOVE_ONLY_HPP +#define TEST_SUPPORT_TRACKED_MOVE_ONLY_HPP + +#include <boost/hana/bool.hpp> +#include <boost/hana/fwd/hash.hpp> +#include <boost/hana/type.hpp> + +#include <support/tracked.hpp> + +#include <utility> + + +// A move-only type that's Tracked. It is also Comparable and Hashable so it +// can be used in associative containers. +template <int i> +struct TrackedMoveOnly : Tracked { + TrackedMoveOnly() : Tracked(i) { } + TrackedMoveOnly(TrackedMoveOnly const&) = delete; + TrackedMoveOnly& operator=(TrackedMoveOnly const&) = delete; + TrackedMoveOnly(TrackedMoveOnly&& x) + : Tracked(std::move(x)) + { } +}; + +template <int i, int j> +constexpr auto operator==(TrackedMoveOnly<i> const&, TrackedMoveOnly<j> const&) +{ return boost::hana::bool_c<i == j>; } + +template <int i, int j> +constexpr auto operator!=(TrackedMoveOnly<i> const&, TrackedMoveOnly<j> const&) +{ return boost::hana::bool_c<i != j>; } + +namespace boost { namespace hana { + template <int i> + struct hash_impl<TrackedMoveOnly<i>> { + static constexpr auto apply(TrackedMoveOnly<i> const&) + { return hana::type_c<TrackedMoveOnly<i>>; }; + }; +}} + +#endif // !TEST_SUPPORT_TRACKED_MOVE_ONLY_HPP |