overloaded_ut.cpp 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #include <util/generic/overloaded.h>
  2. #include <library/cpp/testing/unittest/registar.h>
  3. #include <util/generic/variant.h>
  4. #include <util/generic/algorithm.h>
  5. #include <tuple>
  6. namespace {
  7. struct TType1 {};
  8. struct TType2 {};
  9. struct TType3 {};
  10. }
  11. Y_UNIT_TEST_SUITE(TOverloadedTest) {
  12. Y_UNIT_TEST(StaticTest) {
  13. auto f = TOverloaded{
  14. [](const TType1&) {},
  15. [](const TType2&) {},
  16. [](const TType3&) {}};
  17. using F = decltype(f);
  18. static_assert(std::is_invocable_v<F, TType1>);
  19. static_assert(std::is_invocable_v<F, TType2>);
  20. static_assert(std::is_invocable_v<F, TType3>);
  21. static_assert(!std::is_invocable_v<F, int>);
  22. static_assert(!std::is_invocable_v<F, double>);
  23. }
  24. Y_UNIT_TEST(VariantTest) {
  25. std::variant<int, double, TType1> v = 5;
  26. int res = 0;
  27. std::visit(TOverloaded{
  28. [&](int val) { res = val; },
  29. [&](double) { res = -1; },
  30. [&](TType1) { res = -1; }},
  31. v);
  32. UNIT_ASSERT_VALUES_EQUAL(res, 5);
  33. }
  34. Y_UNIT_TEST(TupleTest) {
  35. std::tuple<int, double, bool, int> t{5, 3.14, true, 20};
  36. TString res;
  37. ForEach(t, TOverloaded{
  38. [&](int val) { res += "(int) " + ToString(val) + ' '; },
  39. [&](double val) { res += "(double) " + ToString(val) + ' '; },
  40. [&](bool val) { res += "(bool) " + ToString(val) + ' '; },
  41. });
  42. UNIT_ASSERT_VALUES_EQUAL(res, "(int) 5 (double) 3.14 (bool) 1 (int) 20 ");
  43. }
  44. Y_UNIT_TEST(ImplicitConversionsTest) {
  45. using TTestVariant = std::variant<int, double, char>;
  46. // Purposefully exhibit inexact overload matched with implicit type
  47. // conversions
  48. // All cases implicitly cast to int
  49. auto matchAsInt = [](TTestVariant var) {
  50. return std::visit(TOverloaded{
  51. [](int val) { return val; },
  52. }, var);
  53. };
  54. UNIT_ASSERT_VALUES_EQUAL(matchAsInt(TTestVariant{17.77}), 17);
  55. UNIT_ASSERT_VALUES_EQUAL(matchAsInt(TTestVariant{12345}), 12345);
  56. UNIT_ASSERT_VALUES_EQUAL(matchAsInt(TTestVariant{'X'}), 88);
  57. // All cases implicitly cast to double
  58. auto matchAsDouble = [](TTestVariant var) {
  59. return std::visit(TOverloaded{
  60. [](double val) { return val; },
  61. }, var);
  62. };
  63. UNIT_ASSERT_VALUES_EQUAL(matchAsDouble(TTestVariant{17.77}), 17.77);
  64. UNIT_ASSERT_VALUES_EQUAL(matchAsDouble(TTestVariant{12345}), 12345.0);
  65. UNIT_ASSERT_VALUES_EQUAL(matchAsDouble(TTestVariant{'X'}), 88.0);
  66. }
  67. }