#include #include #include #include "test.hpp" #include static constexpr fit::static_ > unary_unpack = {}; static constexpr fit::static_ > binary_unpack = {}; FIT_STATIC_AUTO unary_unpack_constexpr = fit::unpack_adaptor(); FIT_STATIC_AUTO binary_unpack_constexpr = fit::unpack_adaptor(); FIT_STATIC_AUTO unary_unpack_reveal = fit::reveal_adaptor>(); FIT_STATIC_AUTO binary_unpack_reveal = fit::reveal_adaptor>(); #if FIT_HAS_NOEXCEPT_DEDUCTION FIT_TEST_CASE() { static_assert(noexcept(fit::unpack(unary_class())(fit::pack(3))), "noexcept unpack"); static_assert(noexcept(unary_unpack(fit::pack(3))), "noexcept unpack"); static_assert(noexcept(binary_unpack(fit::pack(3), fit::pack(2))), "noexcept unpack"); } #endif FIT_TEST_CASE() { FIT_TEST_CHECK(3 == fit::unpack(unary_class())(std::make_tuple(3))); FIT_TEST_CHECK(3 == unary_unpack(std::make_tuple(3))); FIT_TEST_CHECK(3 == unary_unpack_reveal(std::make_tuple(3))); int ifu = 3; FIT_TEST_CHECK(3 == unary_unpack(std::tuple(ifu))); FIT_STATIC_TEST_CHECK(3 == fit::unpack(unary_class())(std::make_tuple(3))); FIT_STATIC_TEST_CHECK(3 == unary_unpack_constexpr(std::make_tuple(3))); FIT_STATIC_TEST_CHECK(3 == unary_unpack_reveal(std::make_tuple(3))); } FIT_TEST_CASE() { FIT_TEST_CHECK(3 == fit::unpack(unary_class())(fit::pack(3))); FIT_TEST_CHECK(3 == unary_unpack(fit::pack(3))); FIT_TEST_CHECK(3 == unary_unpack_reveal(fit::pack(3))); int ifu = 3; FIT_TEST_CHECK(3 == unary_unpack(fit::pack_forward(ifu))); FIT_STATIC_TEST_CHECK(3 == fit::unpack(unary_class())(fit::pack(3))); FIT_STATIC_TEST_CHECK(3 == unary_unpack_constexpr(fit::pack(3))); FIT_STATIC_TEST_CHECK(3 == unary_unpack_reveal(fit::pack(3))); } FIT_TEST_CASE() { FIT_TEST_CHECK(3 == fit::unpack(binary_class())(std::make_tuple(1, 2))); FIT_TEST_CHECK(3 == binary_unpack(std::make_tuple(1, 2))); FIT_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1, 2))); FIT_TEST_CHECK(3 == fit::unpack(binary_class())(std::make_tuple(1), std::make_tuple(2))); FIT_TEST_CHECK(3 == binary_unpack(std::make_tuple(1), std::make_tuple(2))); FIT_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(2))); FIT_TEST_CHECK(3 == fit::unpack(binary_class())(std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); FIT_TEST_CHECK(3 == binary_unpack(std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); FIT_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); FIT_TEST_CHECK(3 == fit::unpack(binary_class())(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); FIT_TEST_CHECK(3 == binary_unpack(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); FIT_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); FIT_TEST_CHECK(3 == fit::unpack(binary_class())(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple())); FIT_TEST_CHECK(3 == binary_unpack(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple())); FIT_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple())); FIT_STATIC_TEST_CHECK(3 == fit::unpack(binary_class())(std::make_tuple(1, 2))); FIT_STATIC_TEST_CHECK(3 == binary_unpack_constexpr(std::make_tuple(1, 2))); FIT_STATIC_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1, 2))); FIT_STATIC_TEST_CHECK(3 == fit::unpack(binary_class())(std::make_tuple(1), std::make_tuple(2))); FIT_STATIC_TEST_CHECK(3 == binary_unpack_constexpr(std::make_tuple(1), std::make_tuple(2))); FIT_STATIC_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(2))); FIT_STATIC_TEST_CHECK(3 == fit::unpack(binary_class())(std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); FIT_STATIC_TEST_CHECK(3 == binary_unpack_constexpr(std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); FIT_STATIC_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); FIT_STATIC_TEST_CHECK(3 == fit::unpack(binary_class())(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); FIT_STATIC_TEST_CHECK(3 == binary_unpack_constexpr(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); FIT_STATIC_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(), std::make_tuple(1), std::make_tuple(), std::make_tuple(2))); FIT_STATIC_TEST_CHECK(3 == fit::unpack(binary_class())(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple())); FIT_STATIC_TEST_CHECK(3 == binary_unpack_constexpr(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple())); FIT_STATIC_TEST_CHECK(3 == binary_unpack_reveal(std::make_tuple(1), std::make_tuple(), std::make_tuple(2), std::make_tuple())); } FIT_TEST_CASE() { auto p1 = fit::pack_basic(1, 2); static_assert(fit::is_unpackable::value, "Not unpackable"); static_assert(fit::is_unpackable::value, "Not unpackable"); auto p2 = fit::pack_forward(1, 2); static_assert(fit::is_unpackable::value, "Not unpackable"); static_assert(fit::is_unpackable::value, "Not unpackable"); auto p3 = fit::pack(1, 2); static_assert(fit::is_unpackable::value, "Not unpackable"); static_assert(fit::is_unpackable::value, "Not unpackable"); static_assert(fit::is_unpackable>::value, "Not unpackable"); static_assert(!fit::is_unpackable::value, "Unpackable"); static_assert(!fit::is_unpackable::value, "Unpackable"); } FIT_TEST_CASE() { typedef std::tuple tuple_type; static_assert(fit::is_unpackable::value, "Not unpackable"); static_assert(fit::is_unpackable::value, "Not unpackable"); static_assert(fit::is_unpackable::value, "Not unpackable"); static_assert(fit::is_unpackable::value, "Not unpackable"); } FIT_STATIC_AUTO lambda_unary_unpack = fit::unpack(FIT_STATIC_LAMBDA(int x) { return x; }); FIT_TEST_CASE() { FIT_TEST_CHECK(3 == lambda_unary_unpack(std::make_tuple(3))); } FIT_TEST_CASE() { FIT_TEST_CHECK(3 == lambda_unary_unpack(fit::pack(3))); } struct unary_move { std::unique_ptr i; unary_move() : i(new int(2)) {} template T operator()(T x) const { return x + *i; } }; static constexpr fit::static_ > unary_move_unpack = {}; FIT_TEST_CASE() { FIT_TEST_CHECK(3 == fit::unpack(unary_move())(std::make_tuple(1))); FIT_TEST_CHECK(3 == unary_move_unpack(std::make_tuple(1))); } FIT_TEST_CASE() { FIT_TEST_CHECK(3 == fit::unpack(unary_move())(fit::pack(1))); FIT_TEST_CHECK(3 == unary_move_unpack(fit::pack(1))); } struct indirect_sum_f { template auto operator()(T x, U y) const FIT_RETURNS(*x + *y); }; #define MAKE_UNIQUE_PTR(x) std::unique_ptr(new int(x)) FIT_TEST_CASE() { FIT_TEST_CHECK(3 == fit::unpack(indirect_sum_f())(fit::pack_basic(MAKE_UNIQUE_PTR(1), MAKE_UNIQUE_PTR(2)))); FIT_TEST_CHECK(3 == fit::unpack(indirect_sum_f())(fit::pack_forward(MAKE_UNIQUE_PTR(1), MAKE_UNIQUE_PTR(2)))); FIT_TEST_CHECK(3 == fit::unpack(indirect_sum_f())(fit::pack(MAKE_UNIQUE_PTR(1), MAKE_UNIQUE_PTR(2)))); FIT_TEST_CHECK(3 == fit::unpack(indirect_sum_f())(std::make_tuple(MAKE_UNIQUE_PTR(1), MAKE_UNIQUE_PTR(2)))); } template struct deduce_types {}; struct deducer { template deduce_types operator()(Ts&&...) const; }; static constexpr fit::unpack_adaptor deduce = {}; FIT_TEST_CASE() { STATIC_ASSERT_SAME(deduce_types, decltype(deduce(std::make_tuple(1, 2)))); STATIC_ASSERT_SAME(deduce_types, decltype(deduce(std::make_tuple(1), std::make_tuple(2)))); STATIC_ASSERT_SAME(deduce_types, decltype(deduce(std::make_tuple(1), std::make_tuple(2), std::make_tuple(3)))); STATIC_ASSERT_SAME(std::tuple, decltype(std::forward_as_tuple(1, 2))); // Disable this test, it seems that rvalue references get swalllowed by type deduction // STATIC_ASSERT_SAME(deduce_types, decltype(deduce(std::forward_as_tuple(1, 2)))); STATIC_ASSERT_SAME(deduce_types, decltype(deduce(fit::pack_basic(1, 2)))); STATIC_ASSERT_SAME(deduce_types, decltype(deduce(fit::pack_basic(1), fit::pack_basic(2)))); STATIC_ASSERT_SAME(deduce_types, decltype(deduce(fit::pack_basic(1), fit::pack_basic(2), fit::pack_basic(3)))); // STATIC_ASSERT_SAME(deduce_types, decltype(deduce(fit::pack_forward(1, 2)))); } struct not_unpackable {}; FIT_TEST_CASE() { auto f = fit::unpack(fit::always(1)); static_assert(!fit::is_callable::value, "SFINAE for unpack failed"); } struct simple_unpackable {}; namespace fit { template<> struct unpack_sequence { template constexpr static auto apply(F&& f, S&&) FIT_RETURNS ( f(1) ); }; } // namespace fit FIT_TEST_CASE() { FIT_TEST_CHECK(fit::unpack(fit::identity)(simple_unpackable{}) == 1); FIT_STATIC_TEST_CHECK(fit::unpack(fit::identity)(simple_unpackable{}) == 1); }