#include #include #include #include #include namespace { struct TType1 {}; struct TType2 {}; struct TType3 {}; } Y_UNIT_TEST_SUITE(TOverloadedTest) { Y_UNIT_TEST(StaticTest) { auto f = TOverloaded{ [](const TType1&) {}, [](const TType2&) {}, [](const TType3&) {}}; using F = decltype(f); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(std::is_invocable_v); static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); } Y_UNIT_TEST(VariantTest) { std::variant v = 5; int res = 0; std::visit(TOverloaded{ [&](int val) { res = val; }, [&](double) { res = -1; }, [&](TType1) { res = -1; }}, v); UNIT_ASSERT_VALUES_EQUAL(res, 5); } Y_UNIT_TEST(TupleTest) { std::tuple t{5, 3.14, true, 20}; TString res; ForEach(t, TOverloaded{ [&](int val) { res += "(int) " + ToString(val) + ' '; }, [&](double val) { res += "(double) " + ToString(val) + ' '; }, [&](bool val) { res += "(bool) " + ToString(val) + ' '; }, }); UNIT_ASSERT_VALUES_EQUAL(res, "(int) 5 (double) 3.14 (bool) 1 (int) 20 "); } Y_UNIT_TEST(ImplicitConversionsTest) { using TTestVariant = std::variant; // Purposefully exhibit inexact overload matched with implicit type // conversions // All cases implicitly cast to int auto matchAsInt = [](TTestVariant var) { return std::visit(TOverloaded{ [](int val) { return val; }, }, var); }; UNIT_ASSERT_VALUES_EQUAL(matchAsInt(TTestVariant{17.77}), 17); UNIT_ASSERT_VALUES_EQUAL(matchAsInt(TTestVariant{12345}), 12345); UNIT_ASSERT_VALUES_EQUAL(matchAsInt(TTestVariant{'X'}), 88); // All cases implicitly cast to double auto matchAsDouble = [](TTestVariant var) { return std::visit(TOverloaded{ [](double val) { return val; }, }, var); }; UNIT_ASSERT_VALUES_EQUAL(matchAsDouble(TTestVariant{17.77}), 17.77); UNIT_ASSERT_VALUES_EQUAL(matchAsDouble(TTestVariant{12345}), 12345.0); UNIT_ASSERT_VALUES_EQUAL(matchAsDouble(TTestVariant{'X'}), 88.0); } }