diff --git a/llvm/include/llvm/ADT/StringSwitch.h b/llvm/include/llvm/ADT/StringSwitch.h --- a/llvm/include/llvm/ADT/StringSwitch.h +++ b/llvm/include/llvm/ADT/StringSwitch.h @@ -185,6 +185,13 @@ return Value; } + [[nodiscard]] std::optional AsOptional() { + if (Result) + return std::optional(std::move(*Result)); + + return std::nullopt; + } + [[nodiscard]] operator R() { assert(Result && "Fell off the end of a string-switch"); return std::move(*Result); diff --git a/llvm/unittests/ADT/StringSwitchTest.cpp b/llvm/unittests/ADT/StringSwitchTest.cpp --- a/llvm/unittests/ADT/StringSwitchTest.cpp +++ b/llvm/unittests/ADT/StringSwitchTest.cpp @@ -205,3 +205,18 @@ EXPECT_EQ(OSType::Unknown, Translate("wind")); EXPECT_EQ(OSType::Unknown, Translate("")); } + +TEST(StringSwitchTest, AsOptional) { + enum class Color { Red }; + + auto Translate = [](StringRef S) { + return llvm::StringSwitch(S) + .Case("red", Color::Red) + .AsOptional(); + }; + + EXPECT_TRUE(Translate("red").has_value()); + EXPECT_EQ(Color::Red, Translate("red").value()); + + EXPECT_EQ(std::nullopt, Translate("blue")); +}