[llvm] [ADT] Handle and document multiple matches in StringSwitch (PR #166177)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 3 07:17:16 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-adt
Author: Jakub Kuderski (kuhar)
<details>
<summary>Changes</summary>
Specify that the first match is returned and bail out early when processing multiple case values.
---
Full diff: https://github.com/llvm/llvm-project/pull/166177.diff
2 Files Affected:
- (modified) llvm/include/llvm/ADT/StringSwitch.h (+20-11)
- (modified) llvm/unittests/ADT/StringSwitchTest.cpp (+17)
``````````diff
diff --git a/llvm/include/llvm/ADT/StringSwitch.h b/llvm/include/llvm/ADT/StringSwitch.h
index 5bdbb302a6d75..cbe0f76ef0903 100644
--- a/llvm/include/llvm/ADT/StringSwitch.h
+++ b/llvm/include/llvm/ADT/StringSwitch.h
@@ -41,6 +41,8 @@ namespace llvm {
/// .Cases({"violet", "purple"}, Violet)
/// .Default(UnknownColor);
/// \endcode
+///
+/// When multiple matches are found, the value of the first match is returned.
template<typename T, typename R = T>
class StringSwitch {
/// The string we are matching.
@@ -213,23 +215,30 @@ class StringSwitch {
[[nodiscard]] operator R() { return DefaultUnreachable(); }
private:
- // Returns true when `Str` matches the `S` argument, and stores the result.
+ // Return true when a match is found. If `Str` matches the `S` argument,
+ // stores the result.
bool CaseImpl(StringLiteral S, T &Value) {
- if (!Result && Str == S) {
- Result = std::move(Value);
+ if (Result)
return true;
- }
- return false;
+
+ if (Str != S)
+ return false;
+
+ Result = std::move(Value);
+ return true;
}
- // Returns true when `Str` matches the `S` argument (case-insensitive), and
- // stores the result.
+ // Return true when a match is found. If `Str` matches the `S` argument
+ // (case-insensitive), stores the result.
bool CaseLowerImpl(StringLiteral S, T &Value) {
- if (!Result && Str.equals_insensitive(S)) {
- Result = std::move(Value);
+ if (Result)
return true;
- }
- return false;
+
+ if (!Str.equals_insensitive(S))
+ return false;
+
+ Result = std::move(Value);
+ return true;
}
StringSwitch &CasesImpl(std::initializer_list<StringLiteral> Cases,
diff --git a/llvm/unittests/ADT/StringSwitchTest.cpp b/llvm/unittests/ADT/StringSwitchTest.cpp
index c94feb54d0b7d..75d50f4dd1b5b 100644
--- a/llvm/unittests/ADT/StringSwitchTest.cpp
+++ b/llvm/unittests/ADT/StringSwitchTest.cpp
@@ -240,6 +240,23 @@ TEST(StringSwitchTest, CasesCopies) {
EXPECT_EQ(NumCopies, 1u);
}
+TEST(StringSwitchTest, StringSwitchMultipleMatches) {
+ auto Translate = [](StringRef S) {
+ return llvm::StringSwitch<int>(S)
+ .CaseLower("A", 0)
+ .Case("b", 1)
+ .Case("a", 2)
+ .CasesLower({"a", "b"}, 3)
+ .DefaultUnreachable();
+ };
+
+ // Check that the value of the first match is returned.
+ EXPECT_EQ(0, Translate("A"));
+ EXPECT_EQ(0, Translate("a"));
+ EXPECT_EQ(3, Translate("B"));
+ EXPECT_EQ(1, Translate("b"));
+}
+
TEST(StringSwitchTest, DefaultUnreachable) {
auto Translate = [](StringRef S) {
return llvm::StringSwitch<int>(S)
``````````
</details>
https://github.com/llvm/llvm-project/pull/166177
More information about the llvm-commits
mailing list