Skip to content

Commit ab903b4

Browse files
authored
[ADT] Add predicate based match support to StringSwitch (llvm#188046)
This introduces `Predicate` and `IfNotPredicate` case selection to StringSwitch to allow use cases like ``` StringSwitch<...>(..) .Case("foo", FooTok) .Predicate([](StringRef Str){ ... }, IdentifierTok) ... ``` This is mostly useful for improving conciseness and clarity when processing generated strings, diagnostics, and similar.
1 parent 5f0b3d6 commit ab903b4

2 files changed

Lines changed: 22 additions & 0 deletions

File tree

llvm/include/llvm/ADT/StringSwitch.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,14 @@ class StringSwitch {
123123
return *this;
124124
}
125125

126+
// A StringSwitch case that is selected if the specified predicate
127+
// returns true for the subject string.
128+
StringSwitch &Predicate(function_ref<bool(StringRef)> Pred, T Value) {
129+
if (!Result && Pred(Str))
130+
Result = std::move(Value);
131+
return *this;
132+
}
133+
126134
[[nodiscard]] R Default(T Value) {
127135
if (Result)
128136
return std::move(*Result);

llvm/unittests/ADT/StringSwitchTest.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,20 @@ TEST(StringSwitchTest, StringSwitchMultipleMatches) {
257257
EXPECT_EQ(1, Translate("b"));
258258
}
259259

260+
TEST(StringPredicateTest, Predicate) {
261+
auto MatchFn = [](StringRef Str) { return Str == "abc" || Str == "def"; };
262+
auto PredicateMatch = [&](StringRef S) {
263+
return llvm::StringSwitch<int>(S)
264+
.Case("abc", 0)
265+
.Predicate(MatchFn, 1)
266+
.Case("def", 2)
267+
.Default(3);
268+
};
269+
EXPECT_EQ(0, PredicateMatch("abc"));
270+
EXPECT_EQ(1, PredicateMatch("def"));
271+
EXPECT_EQ(3, PredicateMatch("ghi"));
272+
}
273+
260274
TEST(StringSwitchTest, DefaultUnreachable) {
261275
auto Translate = [](StringRef S) {
262276
return llvm::StringSwitch<int>(S)

0 commit comments

Comments
 (0)