12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- #include <util/generic/overloaded.h>
- #include <library/cpp/testing/unittest/registar.h>
- #include <util/generic/variant.h>
- #include <util/generic/algorithm.h>
- #include <tuple>
- 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<F, TType1>);
- static_assert(std::is_invocable_v<F, TType2>);
- static_assert(std::is_invocable_v<F, TType3>);
- static_assert(!std::is_invocable_v<F, int>);
- static_assert(!std::is_invocable_v<F, double>);
- }
- Y_UNIT_TEST(VariantTest) {
- std::variant<int, double, TType1> 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<int, double, bool, int> 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<int, double, char>;
- // 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);
- }
- }
|