Skip to content

Commit 6af3568

Browse files
authored
Merge pull request llvm#11910 from swiftlang/jepa-release
[swift/release/6.3] Cherry-pick "[ADT] Allow arbitrary number of cases in StringSwitch (llvm#163117)"
2 parents c3def25 + 4c3f29d commit 6af3568

File tree

2 files changed

+45
-20
lines changed

2 files changed

+45
-20
lines changed

llvm/include/llvm/ADT/StringSwitch.h

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "llvm/ADT/StringRef.h"
1717
#include <cassert>
1818
#include <cstring>
19+
#include <initializer_list>
1920
#include <optional>
2021

2122
namespace llvm {
@@ -84,55 +85,60 @@ class StringSwitch {
8485
return *this;
8586
}
8687

88+
StringSwitch &Cases(std::initializer_list<StringLiteral> CaseStrings,
89+
T Value) {
90+
return CasesImpl(Value, CaseStrings);
91+
}
92+
8793
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, T Value) {
88-
return CasesImpl(Value, S0, S1);
94+
return CasesImpl(Value, {S0, S1});
8995
}
9096

9197
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
9298
T Value) {
93-
return CasesImpl(Value, S0, S1, S2);
99+
return CasesImpl(Value, {S0, S1, S2});
94100
}
95101

96102
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
97103
StringLiteral S3, T Value) {
98-
return CasesImpl(Value, S0, S1, S2, S3);
104+
return CasesImpl(Value, {S0, S1, S2, S3});
99105
}
100106

101107
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
102108
StringLiteral S3, StringLiteral S4, T Value) {
103-
return CasesImpl(Value, S0, S1, S2, S3, S4);
109+
return CasesImpl(Value, {S0, S1, S2, S3, S4});
104110
}
105111

106112
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
107113
StringLiteral S3, StringLiteral S4, StringLiteral S5,
108114
T Value) {
109-
return CasesImpl(Value, S0, S1, S2, S3, S4, S5);
115+
return CasesImpl(Value, {S0, S1, S2, S3, S4, S5});
110116
}
111117

112118
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
113119
StringLiteral S3, StringLiteral S4, StringLiteral S5,
114120
StringLiteral S6, T Value) {
115-
return CasesImpl(Value, S0, S1, S2, S3, S4, S5, S6);
121+
return CasesImpl(Value, {S0, S1, S2, S3, S4, S5, S6});
116122
}
117123

118124
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
119125
StringLiteral S3, StringLiteral S4, StringLiteral S5,
120126
StringLiteral S6, StringLiteral S7, T Value) {
121-
return CasesImpl(Value, S0, S1, S2, S3, S4, S5, S6, S7);
127+
return CasesImpl(Value, {S0, S1, S2, S3, S4, S5, S6, S7});
122128
}
123129

124130
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
125131
StringLiteral S3, StringLiteral S4, StringLiteral S5,
126132
StringLiteral S6, StringLiteral S7, StringLiteral S8,
127133
T Value) {
128-
return CasesImpl(Value, S0, S1, S2, S3, S4, S5, S6, S7, S8);
134+
return CasesImpl(Value, {S0, S1, S2, S3, S4, S5, S6, S7, S8});
129135
}
130136

131137
StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
132138
StringLiteral S3, StringLiteral S4, StringLiteral S5,
133139
StringLiteral S6, StringLiteral S7, StringLiteral S8,
134140
StringLiteral S9, T Value) {
135-
return CasesImpl(Value, S0, S1, S2, S3, S4, S5, S6, S7, S8, S9);
141+
return CasesImpl(Value, {S0, S1, S2, S3, S4, S5, S6, S7, S8, S9});
136142
}
137143

138144
// Case-insensitive case matchers.
@@ -155,23 +161,28 @@ class StringSwitch {
155161
return *this;
156162
}
157163

164+
StringSwitch &CasesLower(std::initializer_list<StringLiteral> CaseStrings,
165+
T Value) {
166+
return CasesLowerImpl(Value, CaseStrings);
167+
}
168+
158169
StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, T Value) {
159-
return CasesLowerImpl(Value, S0, S1);
170+
return CasesLowerImpl(Value, {S0, S1});
160171
}
161172

162173
StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2,
163174
T Value) {
164-
return CasesLowerImpl(Value, S0, S1, S2);
175+
return CasesLowerImpl(Value, {S0, S1, S2});
165176
}
166177

167178
StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2,
168179
StringLiteral S3, T Value) {
169-
return CasesLowerImpl(Value, S0, S1, S2, S3);
180+
return CasesLowerImpl(Value, {S0, S1, S2, S3});
170181
}
171182

172183
StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2,
173184
StringLiteral S3, StringLiteral S4, T Value) {
174-
return CasesLowerImpl(Value, S0, S1, S2, S3, S4);
185+
return CasesLowerImpl(Value, {S0, S1, S2, S3, S4});
175186
}
176187

177188
[[nodiscard]] R Default(T Value) {
@@ -205,16 +216,21 @@ class StringSwitch {
205216
return false;
206217
}
207218

208-
template <typename... Args> StringSwitch &CasesImpl(T &Value, Args... Cases) {
219+
StringSwitch &CasesImpl(T &Value,
220+
std::initializer_list<StringLiteral> Cases) {
209221
// Stop matching after the string is found.
210-
(... || CaseImpl(Value, Cases));
222+
for (StringLiteral S : Cases)
223+
if (CaseImpl(Value, S))
224+
break;
211225
return *this;
212226
}
213227

214-
template <typename... Args>
215-
StringSwitch &CasesLowerImpl(T &Value, Args... Cases) {
228+
StringSwitch &CasesLowerImpl(T &Value,
229+
std::initializer_list<StringLiteral> Cases) {
216230
// Stop matching after the string is found.
217-
(... || CaseLowerImpl(Value, Cases));
231+
for (StringLiteral S : Cases)
232+
if (CaseLowerImpl(Value, S))
233+
break;
218234
return *this;
219235
}
220236
};

llvm/unittests/ADT/StringSwitchTest.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,14 @@ TEST(StringSwitchTest, EndsWithLower) {
153153
}
154154

155155
TEST(StringSwitchTest, Cases) {
156-
enum class OSType { Windows, Linux, Unknown };
156+
enum class OSType { Windows, Linux, MacOS, Unknown };
157157

158158
auto Translate = [](StringRef S) {
159159
return llvm::StringSwitch<OSType>(S)
160160
.Cases(StringLiteral::withInnerNUL("wind\0ws"), "win32", "winnt",
161161
OSType::Windows)
162162
.Cases("linux", "unix", "*nix", "posix", OSType::Linux)
163+
.Cases({"macos", "osx"}, OSType::MacOS)
163164
.Default(OSType::Unknown);
164165
};
165166

@@ -172,21 +173,26 @@ TEST(StringSwitchTest, Cases) {
172173
EXPECT_EQ(OSType::Linux, Translate("*nix"));
173174
EXPECT_EQ(OSType::Linux, Translate("posix"));
174175

176+
EXPECT_EQ(OSType::MacOS, Translate("macos"));
177+
EXPECT_EQ(OSType::MacOS, Translate("osx"));
178+
175179
// Note that the whole null-terminator embedded string is required for the
176180
// case to match.
177181
EXPECT_EQ(OSType::Unknown, Translate("wind"));
178182
EXPECT_EQ(OSType::Unknown, Translate("Windows"));
183+
EXPECT_EQ(OSType::Unknown, Translate("MacOS"));
179184
EXPECT_EQ(OSType::Unknown, Translate(""));
180185
}
181186

182187
TEST(StringSwitchTest, CasesLower) {
183-
enum class OSType { Windows, Linux, Unknown };
188+
enum class OSType { Windows, Linux, MacOS, Unknown };
184189

185190
auto Translate = [](StringRef S) {
186191
return llvm::StringSwitch<OSType>(S)
187192
.CasesLower(StringLiteral::withInnerNUL("wind\0ws"), "win32", "winnt",
188193
OSType::Windows)
189194
.CasesLower("linux", "unix", "*nix", "posix", OSType::Linux)
195+
.CasesLower({"macos", "osx"}, OSType::MacOS)
190196
.Default(OSType::Unknown);
191197
};
192198

@@ -202,6 +208,9 @@ TEST(StringSwitchTest, CasesLower) {
202208
EXPECT_EQ(OSType::Windows, Translate(llvm::StringRef("wind\0ws", 7)));
203209
EXPECT_EQ(OSType::Linux, Translate("linux"));
204210

211+
EXPECT_EQ(OSType::MacOS, Translate("macOS"));
212+
EXPECT_EQ(OSType::MacOS, Translate("OSX"));
213+
205214
EXPECT_EQ(OSType::Unknown, Translate("wind"));
206215
EXPECT_EQ(OSType::Unknown, Translate(""));
207216
}

0 commit comments

Comments
 (0)