Commit 6bf3c73f by Vitaly Goldshteyn Committed by Copybara-Service

Document and test ability to use absl::Overload with generic lambdas.

PiperOrigin-RevId: 613141617
Change-Id: Ife68495d4a5951b734db7407fb99686cf45a5133
parent 8dc90ff0
...@@ -35,7 +35,14 @@ ...@@ -35,7 +35,14 @@
// [](double) -> absl::string_view { return "double"; }), // [](double) -> absl::string_view { return "double"; }),
// v) == "int"); // 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_ #ifndef ABSL_FUNCTIONAL_OVERLOAD_H_
#define ABSL_FUNCTIONAL_OVERLOAD_H_ #define ABSL_FUNCTIONAL_OVERLOAD_H_
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
namespace { namespace {
TEST(OverloadTest, DispatchConsidersType) { TEST(OverloadTest, DispatchConsidersTypeWithAutoFallback) {
auto overloaded = absl::Overload( auto overloaded = absl::Overload(
[](int v) -> std::string { return absl::StrCat("int ", v); }, // [](int v) -> std::string { return absl::StrCat("int ", v); }, //
[](double v) -> std::string { return absl::StrCat("double ", v); }, // [](double v) -> std::string { return absl::StrCat("double ", v); }, //
...@@ -103,6 +103,35 @@ TEST(OverloadTest, AmbiguousConversionNotInvocable) { ...@@ -103,6 +103,35 @@ TEST(OverloadTest, AmbiguousConversionNotInvocable) {
static_assert(!std::is_invocable_v<decltype(overloaded), int>); 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) { TEST(OverloadTest, DispatchConsidersSfinae) {
auto overloaded = absl::Overload( // auto overloaded = absl::Overload( //
[](auto a) -> decltype(a + 1) { return a + 1; } // [](auto a) -> decltype(a + 1) { return a + 1; } //
...@@ -125,6 +154,19 @@ TEST(OverloadTest, VariantVisitDispatchesCorrectly) { ...@@ -125,6 +154,19 @@ TEST(OverloadTest, VariantVisitDispatchesCorrectly) {
EXPECT_EQ("string", absl::visit(overloaded, v)); 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 } // namespace
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment