/* @copyright Louis Dionne 2015 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 #include #include #include #include #include #include #include #include #include #include using namespace boost::hana; template using eq = test::ct_eq; template using ord = test::ct_ord; struct x0; struct x1; struct x2; struct x3; int main() { ////////////////////////////////////////////////////////////////////////// // Move-only friendliness and reference semantics ////////////////////////////////////////////////////////////////////////// { struct movable { movable() = default; movable(movable const&) = delete; movable(movable&&) = default; }; { auto xs = make(movable{}); auto by_val = [](auto) { }; by_val(std::move(xs)); by_val(head(std::move(xs))); by_val(at_c<0>(std::move(xs))); by_val(last(std::move(xs))); } { auto const& xs = make(movable{}); auto by_const_ref = [](auto const&) { }; by_const_ref(xs); by_const_ref(head(xs)); by_const_ref(at_c<0>(xs)); by_const_ref(last(xs)); } { auto xs = make(movable{}); auto by_ref = [](auto&) { }; by_ref(xs); by_ref(head(xs)); by_ref(at_c<0>(xs)); by_ref(last(xs)); } } ////////////////////////////////////////////////////////////////////////// // default-constructibility ////////////////////////////////////////////////////////////////////////// { _tuple<> z1{}; (void)z1; _tuple z2{}; (void)z2; _tuple z3{}; (void)z3; _tuple z4{}; (void)z4; using Types = decltype(tuple_t); Types default_{}; (void)default_; } ////////////////////////////////////////////////////////////////////////// // `decltype(tuple_t)` should inherit `_tuple_t` ////////////////////////////////////////////////////////////////////////// { static_assert(std::is_base_of< _tuple_t, decltype(tuple_t) >{}, ""); } ////////////////////////////////////////////////////////////////////////// // Setup for the laws below ////////////////////////////////////////////////////////////////////////// auto eq_tuples = make( make() , make(eq<0>{}) , make(eq<0>{}, eq<1>{}) , make(eq<0>{}, eq<1>{}, eq<2>{}) , make(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{}) , make(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{}, eq<4>{}) , make(eq<0>{}, eq<1>{}, eq<2>{}, eq<3>{}, eq<4>{}, eq<5>{}) ); ////////////////////////////////////////////////////////////////////////// // Foldable ////////////////////////////////////////////////////////////////////////// { // unpack { test::_injection<0> f{}; // tuple BOOST_HANA_CONSTANT_CHECK(equal( unpack(make(), f), f() )); BOOST_HANA_CONSTANT_CHECK(equal( unpack(make(eq<0>{}), f), f(eq<0>{}) )); BOOST_HANA_CONSTANT_CHECK(equal( unpack(make(eq<0>{}, eq<1>{}), f), f(eq<0>{}, eq<1>{}) )); BOOST_HANA_CONSTANT_CHECK(equal( unpack(make(eq<0>{}, eq<1>{}, eq<2>{}), f), f(eq<0>{}, eq<1>{}, eq<2>{}) )); // tuple_t BOOST_HANA_CONSTANT_CHECK(equal( unpack(tuple_t<>, f), f() )); BOOST_HANA_CONSTANT_CHECK(equal( unpack(tuple_t, f), f(type) )); BOOST_HANA_CONSTANT_CHECK(equal( unpack(tuple_t, f), f(type, type) )); BOOST_HANA_CONSTANT_CHECK(equal( unpack(tuple_t, f), f(type, type, type) )); BOOST_HANA_CONSTANT_CHECK(equal( unpack(tuple_t, f), f(type, type, type, type) )); } test::TestFoldable{eq_tuples}; } ////////////////////////////////////////////////////////////////////////// // Iterable ////////////////////////////////////////////////////////////////////////// { // head { // tuple_t BOOST_HANA_CONSTANT_CHECK(equal(head(tuple_t), type)); BOOST_HANA_CONSTANT_CHECK(equal(head(tuple_t), type)); BOOST_HANA_CONSTANT_CHECK(equal(head(tuple_t), type)); // tuple_c BOOST_HANA_CONSTANT_CHECK(equal(head(tuple_c), int_<0>)); BOOST_HANA_CONSTANT_CHECK(equal(head(tuple_c), int_<0>)); BOOST_HANA_CONSTANT_CHECK(equal(head(tuple_c), int_<0>)); } // is_empty { // tuple_t BOOST_HANA_CONSTANT_CHECK(is_empty(tuple_t<>)); BOOST_HANA_CONSTANT_CHECK(not_(is_empty(tuple_t))); BOOST_HANA_CONSTANT_CHECK(not_(is_empty(tuple_t))); // tuple_c BOOST_HANA_CONSTANT_CHECK(is_empty(tuple_c)); BOOST_HANA_CONSTANT_CHECK(not_(is_empty(tuple_c))); BOOST_HANA_CONSTANT_CHECK(not_(is_empty(tuple_c))); BOOST_HANA_CONSTANT_CHECK(not_(is_empty(tuple_c))); } // tail { // tuple_t BOOST_HANA_CONSTANT_CHECK(equal(tail(tuple_t), tuple_t<>)); BOOST_HANA_CONSTANT_CHECK(equal(tail(tuple_t), tuple_t)); BOOST_HANA_CONSTANT_CHECK(equal(tail(tuple_t), tuple_t)); // tuple_c BOOST_HANA_CONSTANT_CHECK(equal( tail(tuple_c), tuple_c )); BOOST_HANA_CONSTANT_CHECK(equal( tail(tuple_c), tuple_c )); BOOST_HANA_CONSTANT_CHECK(equal( tail(tuple_c), tuple_c )); } test::TestIterable{eq_tuples}; } ////////////////////////////////////////////////////////////////////////// // Traversable ////////////////////////////////////////////////////////////////////////// { test::TestTraversable{}; } ////////////////////////////////////////////////////////////////////////// // Sequence ////////////////////////////////////////////////////////////////////////// { test::TestSequence{}; } }