LLVM 17.0.0git
StringSwitch.h
Go to the documentation of this file.
1//===--- StringSwitch.h - Switch-on-literal-string Construct --------------===/
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//===----------------------------------------------------------------------===/
7///
8/// \file
9/// This file implements the StringSwitch template, which mimics a switch()
10/// statement whose cases are string literals.
11///
12//===----------------------------------------------------------------------===/
13#ifndef LLVM_ADT_STRINGSWITCH_H
14#define LLVM_ADT_STRINGSWITCH_H
15
16#include "llvm/ADT/StringRef.h"
18#include <cassert>
19#include <cstring>
20#include <optional>
21
22namespace llvm {
23
24/// A switch()-like statement whose cases are string literals.
25///
26/// The StringSwitch class is a simple form of a switch() statement that
27/// determines whether the given string matches one of the given string
28/// literals. The template type parameter \p T is the type of the value that
29/// will be returned from the string-switch expression. For example,
30/// the following code switches on the name of a color in \c argv[i]:
31///
32/// \code
33/// Color color = StringSwitch<Color>(argv[i])
34/// .Case("red", Red)
35/// .Case("orange", Orange)
36/// .Case("yellow", Yellow)
37/// .Case("green", Green)
38/// .Case("blue", Blue)
39/// .Case("indigo", Indigo)
40/// .Cases("violet", "purple", Violet)
41/// .Default(UnknownColor);
42/// \endcode
43template<typename T, typename R = T>
45 /// The string we are matching.
46 const StringRef Str;
47
48 /// The pointer to the result of this switch statement, once known,
49 /// null before that.
50 std::optional<T> Result;
51
52public:
54 : Str(S), Result() { }
55
56 // StringSwitch is not copyable.
57 StringSwitch(const StringSwitch &) = delete;
58
59 // StringSwitch is not assignable due to 'Str' being 'const'.
60 void operator=(const StringSwitch &) = delete;
61 void operator=(StringSwitch &&other) = delete;
62
64 : Str(other.Str), Result(std::move(other.Result)) { }
65
66 ~StringSwitch() = default;
67
68 // Case-sensitive case matchers
70 if (!Result && Str == S) {
71 Result = std::move(Value);
72 }
73 return *this;
74 }
75
77 if (!Result && Str.endswith(S)) {
78 Result = std::move(Value);
79 }
80 return *this;
81 }
82
84 if (!Result && Str.startswith(S)) {
85 Result = std::move(Value);
86 }
87 return *this;
88 }
89
91 return Case(S0, Value).Case(S1, Value);
92 }
93
95 T Value) {
96 return Case(S0, Value).Cases(S1, S2, Value);
97 }
98
100 StringLiteral S3, T Value) {
101 return Case(S0, Value).Cases(S1, S2, S3, Value);
102 }
103
106 return Case(S0, Value).Cases(S1, S2, S3, S4, Value);
107 }
108
111 T Value) {
112 return Case(S0, Value).Cases(S1, S2, S3, S4, S5, Value);
113 }
114
117 StringLiteral S6, T Value) {
118 return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, Value);
119 }
120
124 return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, Value);
125 }
126
130 T Value) {
131 return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, S8, Value);
132 }
133
137 StringLiteral S9, T Value) {
138 return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, S8, S9, Value);
139 }
140
141 // Case-insensitive case matchers.
143 if (!Result && Str.equals_insensitive(S))
144 Result = std::move(Value);
145
146 return *this;
147 }
148
150 if (!Result && Str.endswith_insensitive(S))
151 Result = Value;
152
153 return *this;
154 }
155
157 if (!Result && Str.startswith_insensitive(S))
158 Result = std::move(Value);
159
160 return *this;
161 }
162
164 return CaseLower(S0, Value).CaseLower(S1, Value);
165 }
166
168 T Value) {
169 return CaseLower(S0, Value).CasesLower(S1, S2, Value);
170 }
171
173 StringLiteral S3, T Value) {
174 return CaseLower(S0, Value).CasesLower(S1, S2, S3, Value);
175 }
176
179 return CaseLower(S0, Value).CasesLower(S1, S2, S3, S4, Value);
180 }
181
182 [[nodiscard]] R Default(T Value) {
183 if (Result)
184 return std::move(*Result);
185 return Value;
186 }
187
188 [[nodiscard]] operator R() {
189 assert(Result && "Fell off the end of a string-switch");
190 return std::move(*Result);
191 }
192};
193
194} // end namespace llvm
195
196#endif // LLVM_ADT_STRINGSWITCH_H
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition: StringRef.h:841
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, T Value)
Definition: StringSwitch.h:177
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, T Value)
Definition: StringSwitch.h:109
StringSwitch & EndsWithLower(StringLiteral S, T Value)
Definition: StringSwitch.h:149
StringSwitch & StartsWithLower(StringLiteral S, T Value)
Definition: StringSwitch.h:156
StringSwitch & CaseLower(StringLiteral S, T Value)
Definition: StringSwitch.h:142
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
StringSwitch & CasesLower(StringLiteral S0, StringLiteral S1, T Value)
Definition: StringSwitch.h:163
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, T Value)
Definition: StringSwitch.h:104
void operator=(const StringSwitch &)=delete
StringSwitch & CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, T Value)
Definition: StringSwitch.h:172
R Default(T Value)
Definition: StringSwitch.h:182
StringSwitch & StartsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:83
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, StringLiteral S6, StringLiteral S7, StringLiteral S8, T Value)
Definition: StringSwitch.h:127
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Definition: StringSwitch.h:90
StringSwitch(const StringSwitch &)=delete
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, T Value)
Definition: StringSwitch.h:99
StringSwitch & EndsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:76
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, StringLiteral S6, StringLiteral S7, T Value)
Definition: StringSwitch.h:121
StringSwitch(StringSwitch &&other)
Definition: StringSwitch.h:63
void operator=(StringSwitch &&other)=delete
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, StringLiteral S6, T Value)
Definition: StringSwitch.h:115
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, T Value)
Definition: StringSwitch.h:94
StringSwitch(StringRef S)
Definition: StringSwitch.h:53
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, StringLiteral S6, StringLiteral S7, StringLiteral S8, StringLiteral S9, T Value)
Definition: StringSwitch.h:134
StringSwitch & CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, T Value)
Definition: StringSwitch.h:167
~StringSwitch()=default
LLVM Value Representation.
Definition: Value.h:74
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1862
Definition: BitVector.h:851