// 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace hana { namespace test { template > struct TestIterable : TestIterable { using TestIterable::TestIterable; }; template struct TestIterable { template TestIterable(Xs xs) { hana::for_each(xs, [](auto xs) { static_assert(Iterable{}, ""); BOOST_HANA_CONSTANT_CHECK( hana::is_empty(xs) ^iff^ hana::is_empty(hana::to(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(xs)) )); BOOST_HANA_CHECK(hana::equal( hana::to(hana::drop_front_exactly(xs)), hana::drop_front_exactly(hana::to(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 struct TestIterable::value>> : TestIterable { template using x = ct_eq; template struct invalid { }; struct undefined { }; template TestIterable(Xs xs) : TestIterable{xs} { constexpr auto list = make; ////////////////////////////////////////////////////////////////// // 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