diff options
author | Vitaly Goldshteyn <goldvitaly@google.com> | 2024-03-06 02:38:50 -0800 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-03-06 02:39:47 -0800 |
commit | 6bf3c73fdfeb62733d2a0f81b9846ff77f3a3b9f (patch) | |
tree | 674d88886bca7c1407310a8d6691c07c6902413e /absl | |
parent | 8dc90ff07402cd027daec520bb77f46e51855889 (diff) |
Document and test ability to use absl::Overload with generic lambdas.
PiperOrigin-RevId: 613141617
Change-Id: Ife68495d4a5951b734db7407fb99686cf45a5133
Diffstat (limited to 'absl')
-rw-r--r-- | absl/functional/overload.h | 9 | ||||
-rw-r--r-- | absl/functional/overload_test.cc | 44 |
2 files changed, 51 insertions, 2 deletions
diff --git a/absl/functional/overload.h b/absl/functional/overload.h index 4651f14b..732795fc 100644 --- a/absl/functional/overload.h +++ b/absl/functional/overload.h @@ -35,7 +35,14 @@ // [](double) -> absl::string_view { return "double"; }), // v) == "int"); // -// Note: This requires C++17. +// One of the lambda may specify overload for several types via generic lambda. +// +// absl::variant<std::string, int32_t, int64_t> v(int32_t{1}); +// assert(std::visit(absl::Overload( +// [](const std::string& s) { return s.size(); }, +// [](const auto& s) { return sizeof(s); }), v) == 4); +// +// Note: absl::Overload requires C++17. #ifndef ABSL_FUNCTIONAL_OVERLOAD_H_ #define ABSL_FUNCTIONAL_OVERLOAD_H_ diff --git a/absl/functional/overload_test.cc b/absl/functional/overload_test.cc index 739c4c4c..040bf83f 100644 --- a/absl/functional/overload_test.cc +++ b/absl/functional/overload_test.cc @@ -30,7 +30,7 @@ namespace { -TEST(OverloadTest, DispatchConsidersType) { +TEST(OverloadTest, DispatchConsidersTypeWithAutoFallback) { auto overloaded = absl::Overload( [](int v) -> std::string { return absl::StrCat("int ", v); }, // [](double v) -> std::string { return absl::StrCat("double ", v); }, // @@ -103,6 +103,35 @@ TEST(OverloadTest, AmbiguousConversionNotInvocable) { static_assert(!std::is_invocable_v<decltype(overloaded), int>); } +TEST(OverloadTest, AmbiguousConversionWithAutoNotInvocable) { + auto overloaded = absl::Overload( // + [](auto a) { return a; }, // + [](auto c) { return c; } // + ); + static_assert(!std::is_invocable_v<decltype(overloaded), int>); +} + +#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L + +TEST(OverloadTest, AmbiguousConversionWithAutoAndTemplateNotInvocable) { + auto overloaded = absl::Overload( // + [](auto a) { return a; }, // + []<class T>(T c) { return c; } // + ); + static_assert(!std::is_invocable_v<decltype(overloaded), int>); +} + +TEST(OverloadTest, DispatchConsidersTypeWithTemplateFallback) { + auto overloaded = absl::Overload( // + [](int a) { return a; }, // + []<class T>(T c) { return c * 2; } // + ); + EXPECT_EQ(7, overloaded(7)); + EXPECT_EQ(14.0, overloaded(7.0)); +} + +#endif // ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L + TEST(OverloadTest, DispatchConsidersSfinae) { auto overloaded = absl::Overload( // [](auto a) -> decltype(a + 1) { return a + 1; } // @@ -125,6 +154,19 @@ TEST(OverloadTest, VariantVisitDispatchesCorrectly) { EXPECT_EQ("string", absl::visit(overloaded, v)); } +TEST(OverloadTest, VariantVisitWithAutoFallbackDispatchesCorrectly) { + absl::variant<std::string, int32_t, int64_t> v(int32_t{1}); + auto overloaded = absl::Overload( + [](const std::string& s) { return s.size(); }, // + [](const auto& s) { return sizeof(s); } // + ); + EXPECT_EQ(4, absl::visit(overloaded, v)); + v = int64_t{1}; + EXPECT_EQ(8, absl::visit(overloaded, v)); + v = std::string("hello"); + EXPECT_EQ(5, absl::visit(overloaded, v)); +} + } // namespace #endif |