[llvm] 25ed923 - [ADT] Handle and document multiple matches in StringSwitch (#166177)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 3 08:40:23 PST 2025
Author: Jakub Kuderski
Date: 2025-11-03T11:40:18-05:00
New Revision: 25ed9231159f4b2d82b0cf0eb36db65c7599df45
URL: https://github.com/llvm/llvm-project/commit/25ed9231159f4b2d82b0cf0eb36db65c7599df45
DIFF: https://github.com/llvm/llvm-project/commit/25ed9231159f4b2d82b0cf0eb36db65c7599df45.diff
LOG: [ADT] Handle and document multiple matches in StringSwitch (#166177)
Specify that the first match is returned and bail out early when
processing multiple case values.
Added:
Modified:
llvm/include/llvm/ADT/StringSwitch.h
llvm/unittests/ADT/StringSwitchTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ADT/StringSwitch.h b/llvm/include/llvm/ADT/StringSwitch.h
index 5bdbb302a6d75..53ebec1eb3a54 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.
+ // Returns 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.
+ // Returns 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)
More information about the llvm-commits
mailing list