File indexing completed on 2026-05-10 08:43:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_ADT_STRINGSWITCH_H
0014 #define LLVM_ADT_STRINGSWITCH_H
0015
0016 #include "llvm/ADT/StringRef.h"
0017 #include "llvm/Support/Compiler.h"
0018 #include <cassert>
0019 #include <cstring>
0020 #include <optional>
0021
0022 namespace llvm {
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 template<typename T, typename R = T>
0044 class StringSwitch {
0045
0046 const StringRef Str;
0047
0048
0049
0050 std::optional<T> Result;
0051
0052 public:
0053 explicit StringSwitch(StringRef S)
0054 : Str(S), Result() { }
0055
0056
0057 StringSwitch(const StringSwitch &) = delete;
0058
0059
0060 void operator=(const StringSwitch &) = delete;
0061 void operator=(StringSwitch &&other) = delete;
0062
0063 StringSwitch(StringSwitch &&other)
0064 : Str(other.Str), Result(std::move(other.Result)) { }
0065
0066 ~StringSwitch() = default;
0067
0068
0069 StringSwitch &Case(StringLiteral S, T Value) {
0070 if (!Result && Str == S) {
0071 Result = std::move(Value);
0072 }
0073 return *this;
0074 }
0075
0076 StringSwitch& EndsWith(StringLiteral S, T Value) {
0077 if (!Result && Str.ends_with(S)) {
0078 Result = std::move(Value);
0079 }
0080 return *this;
0081 }
0082
0083 StringSwitch& StartsWith(StringLiteral S, T Value) {
0084 if (!Result && Str.starts_with(S)) {
0085 Result = std::move(Value);
0086 }
0087 return *this;
0088 }
0089
0090 StringSwitch &Cases(StringLiteral S0, StringLiteral S1, T Value) {
0091 return Case(S0, Value).Case(S1, Value);
0092 }
0093
0094 StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
0095 T Value) {
0096 return Case(S0, Value).Cases(S1, S2, Value);
0097 }
0098
0099 StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
0100 StringLiteral S3, T Value) {
0101 return Case(S0, Value).Cases(S1, S2, S3, Value);
0102 }
0103
0104 StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
0105 StringLiteral S3, StringLiteral S4, T Value) {
0106 return Case(S0, Value).Cases(S1, S2, S3, S4, Value);
0107 }
0108
0109 StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
0110 StringLiteral S3, StringLiteral S4, StringLiteral S5,
0111 T Value) {
0112 return Case(S0, Value).Cases(S1, S2, S3, S4, S5, Value);
0113 }
0114
0115 StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
0116 StringLiteral S3, StringLiteral S4, StringLiteral S5,
0117 StringLiteral S6, T Value) {
0118 return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, Value);
0119 }
0120
0121 StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
0122 StringLiteral S3, StringLiteral S4, StringLiteral S5,
0123 StringLiteral S6, StringLiteral S7, T Value) {
0124 return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, Value);
0125 }
0126
0127 StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
0128 StringLiteral S3, StringLiteral S4, StringLiteral S5,
0129 StringLiteral S6, StringLiteral S7, StringLiteral S8,
0130 T Value) {
0131 return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, S8, Value);
0132 }
0133
0134 StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
0135 StringLiteral S3, StringLiteral S4, StringLiteral S5,
0136 StringLiteral S6, StringLiteral S7, StringLiteral S8,
0137 StringLiteral S9, T Value) {
0138 return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, S8, S9, Value);
0139 }
0140
0141
0142 StringSwitch &CaseLower(StringLiteral S, T Value) {
0143 if (!Result && Str.equals_insensitive(S))
0144 Result = std::move(Value);
0145
0146 return *this;
0147 }
0148
0149 StringSwitch &EndsWithLower(StringLiteral S, T Value) {
0150 if (!Result && Str.ends_with_insensitive(S))
0151 Result = Value;
0152
0153 return *this;
0154 }
0155
0156 StringSwitch &StartsWithLower(StringLiteral S, T Value) {
0157 if (!Result && Str.starts_with_insensitive(S))
0158 Result = std::move(Value);
0159
0160 return *this;
0161 }
0162
0163 StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, T Value) {
0164 return CaseLower(S0, Value).CaseLower(S1, Value);
0165 }
0166
0167 StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2,
0168 T Value) {
0169 return CaseLower(S0, Value).CasesLower(S1, S2, Value);
0170 }
0171
0172 StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2,
0173 StringLiteral S3, T Value) {
0174 return CaseLower(S0, Value).CasesLower(S1, S2, S3, Value);
0175 }
0176
0177 StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2,
0178 StringLiteral S3, StringLiteral S4, T Value) {
0179 return CaseLower(S0, Value).CasesLower(S1, S2, S3, S4, Value);
0180 }
0181
0182 [[nodiscard]] R Default(T Value) {
0183 if (Result)
0184 return std::move(*Result);
0185 return Value;
0186 }
0187
0188 [[nodiscard]] operator R() {
0189 assert(Result && "Fell off the end of a string-switch");
0190 return std::move(*Result);
0191 }
0192 };
0193
0194 }
0195
0196 #endif