[PATCH] D140221: [Support] Add StringSwitch::AsOptional

Sam Elliott via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 16 08:03:19 PST 2022


lenary created this revision.
Herald added a project: All.
lenary requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

A StringSwitch does not always have a default value. In these cases, you
can currently achieve the same using the following, which is pretty
ugly:

  std::optional<InnerT> Foo = llvm::StringSwitch<std::optional<InnerT>>(str)
    .Case("foo", std::optional(InnerT(...)))
    .Default(std::nullopt);

This commit allows you to achieve the same using the following, which I
think makes the intent a lot clearer (and avoids a nested optional
internally):

  std::optional<InnerT> Foo = llvm::StringSwitch<InnerT>(str)
    .Case("foo", InnerT(...))
    .AsOptional();


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140221

Files:
  llvm/include/llvm/ADT/StringSwitch.h
  llvm/unittests/ADT/StringSwitchTest.cpp


Index: llvm/unittests/ADT/StringSwitchTest.cpp
===================================================================
--- llvm/unittests/ADT/StringSwitchTest.cpp
+++ 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<Color>(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"));
+}
Index: llvm/include/llvm/ADT/StringSwitch.h
===================================================================
--- llvm/include/llvm/ADT/StringSwitch.h
+++ llvm/include/llvm/ADT/StringSwitch.h
@@ -185,6 +185,13 @@
     return Value;
   }
 
+  [[nodiscard]] std::optional<R> 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);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D140221.483548.patch
Type: text/x-patch
Size: 1202 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221216/98638f7b/attachment.bin>


More information about the llvm-commits mailing list