1616#include " llvm/Support/Compiler.h"
1717#include < cassert>
1818#include < cstring>
19+ #include < initializer_list>
1920
2021inline namespace __swift { inline namespace __runtime {
2122namespace llvm {
@@ -66,9 +67,7 @@ class StringSwitch {
6667
6768 // Case-sensitive case matchers
6869 StringSwitch &Case (StringLiteral S, T Value) {
69- if (!Result && Str == S) {
70- Result = std::move (Value);
71- }
70+ CaseImpl (Value, S);
7271 return *this ;
7372 }
7473
@@ -86,62 +85,14 @@ class StringSwitch {
8685 return *this ;
8786 }
8887
89- StringSwitch &Cases (StringLiteral S0, StringLiteral S1, T Value) {
90- return Case (S0, Value).Case (S1, Value);
91- }
92-
93- StringSwitch &Cases (StringLiteral S0, StringLiteral S1, StringLiteral S2,
94- T Value) {
95- return Case (S0, Value).Cases (S1, S2, Value);
96- }
97-
98- StringSwitch &Cases (StringLiteral S0, StringLiteral S1, StringLiteral S2,
99- StringLiteral S3, T Value) {
100- return Case (S0, Value).Cases (S1, S2, S3, Value);
101- }
102-
103- StringSwitch &Cases (StringLiteral S0, StringLiteral S1, StringLiteral S2,
104- StringLiteral S3, StringLiteral S4, T Value) {
105- return Case (S0, Value).Cases (S1, S2, S3, S4, Value);
106- }
107-
108- StringSwitch &Cases (StringLiteral S0, StringLiteral S1, StringLiteral S2,
109- StringLiteral S3, StringLiteral S4, StringLiteral S5,
88+ StringSwitch &Cases (std::initializer_list<StringLiteral> CaseStrings,
11089 T Value) {
111- return Case (S0, Value).Cases (S1, S2, S3, S4, S5, Value);
112- }
113-
114- StringSwitch &Cases (StringLiteral S0, StringLiteral S1, StringLiteral S2,
115- StringLiteral S3, StringLiteral S4, StringLiteral S5,
116- StringLiteral S6, T Value) {
117- return Case (S0, Value).Cases (S1, S2, S3, S4, S5, S6, Value);
118- }
119-
120- StringSwitch &Cases (StringLiteral S0, StringLiteral S1, StringLiteral S2,
121- StringLiteral S3, StringLiteral S4, StringLiteral S5,
122- StringLiteral S6, StringLiteral S7, T Value) {
123- return Case (S0, Value).Cases (S1, S2, S3, S4, S5, S6, S7, Value);
124- }
125-
126- StringSwitch &Cases (StringLiteral S0, StringLiteral S1, StringLiteral S2,
127- StringLiteral S3, StringLiteral S4, StringLiteral S5,
128- StringLiteral S6, StringLiteral S7, StringLiteral S8,
129- T Value) {
130- return Case (S0, Value).Cases (S1, S2, S3, S4, S5, S6, S7, S8, Value);
131- }
132-
133- StringSwitch &Cases (StringLiteral S0, StringLiteral S1, StringLiteral S2,
134- StringLiteral S3, StringLiteral S4, StringLiteral S5,
135- StringLiteral S6, StringLiteral S7, StringLiteral S8,
136- StringLiteral S9, T Value) {
137- return Case (S0, Value).Cases (S1, S2, S3, S4, S5, S6, S7, S8, S9, Value);
90+ return CasesImpl (Value, CaseStrings);
13891 }
13992
14093 // Case-insensitive case matchers.
14194 StringSwitch &CaseLower (StringLiteral S, T Value) {
142- if (!Result && Str.equals_insensitive (S))
143- Result = std::move (Value);
144-
95+ CaseLowerImpl (Value, S);
14596 return *this ;
14697 }
14798
@@ -159,37 +110,59 @@ class StringSwitch {
159110 return *this ;
160111 }
161112
162- StringSwitch &CasesLower (StringLiteral S0, StringLiteral S1, T Value) {
163- return CaseLower (S0, Value).CaseLower (S1, Value);
164- }
165-
166- StringSwitch &CasesLower (StringLiteral S0, StringLiteral S1, StringLiteral S2,
113+ StringSwitch &CasesLower (std::initializer_list<StringLiteral> CaseStrings,
167114 T Value) {
168- return CaseLower (S0, Value). CasesLower (S1, S2, Value );
115+ return CasesLowerImpl ( Value, CaseStrings );
169116 }
170117
171- StringSwitch &CasesLower (StringLiteral S0, StringLiteral S1, StringLiteral S2,
172- StringLiteral S3, T Value) {
173- return CaseLower (S0, Value).CasesLower (S1, S2, S3, Value);
174- }
175-
176- StringSwitch &CasesLower (StringLiteral S0, StringLiteral S1, StringLiteral S2,
177- StringLiteral S3, StringLiteral S4, T Value) {
178- return CaseLower (S0, Value).CasesLower (S1, S2, S3, S4, Value);
179- }
180-
181- [[nodiscard]]
182- R Default (T Value) {
118+ [[nodiscard]] R Default (T Value) {
183119 if (Result)
184120 return std::move (*Result);
185121 return Value;
186122 }
187123
188- [[nodiscard]]
189- operator R () {
124+ [[nodiscard]] operator R () {
190125 assert (Result && " Fell off the end of a string-switch" );
191126 return std::move (*Result);
192127 }
128+
129+ private:
130+ // Returns true when `Str` matches the `S` argument, and stores the result.
131+ bool CaseImpl (T &Value, StringLiteral S) {
132+ if (!Result && Str == S) {
133+ Result = std::move (Value);
134+ return true ;
135+ }
136+ return false ;
137+ }
138+
139+ // Returns true when `Str` matches the `S` argument (case-insensitive), and
140+ // stores the result.
141+ bool CaseLowerImpl (T &Value, StringLiteral S) {
142+ if (!Result && Str.equals_insensitive (S)) {
143+ Result = std::move (Value);
144+ return true ;
145+ }
146+ return false ;
147+ }
148+
149+ StringSwitch &CasesImpl (T &Value,
150+ std::initializer_list<StringLiteral> Cases) {
151+ // Stop matching after the string is found.
152+ for (StringLiteral S : Cases)
153+ if (CaseImpl (Value, S))
154+ break ;
155+ return *this ;
156+ }
157+
158+ StringSwitch &CasesLowerImpl (T &Value,
159+ std::initializer_list<StringLiteral> Cases) {
160+ // Stop matching after the string is found.
161+ for (StringLiteral S : Cases)
162+ if (CaseLowerImpl (Value, S))
163+ break ;
164+ return *this ;
165+ }
193166};
194167
195168} // end namespace llvm
0 commit comments