LLVM  7.0.0svn
StringSwitch.h
Go to the documentation of this file.
1 //===--- StringSwitch.h - Switch-on-literal-string Construct --------------===/
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //===----------------------------------------------------------------------===/
8 //
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"
17 #include "llvm/Support/Compiler.h"
18 #include <cassert>
19 #include <cstring>
20 
21 namespace llvm {
22 
23 /// A switch()-like statement whose cases are string literals.
24 ///
25 /// The StringSwitch class is a simple form of a switch() statement that
26 /// determines whether the given string matches one of the given string
27 /// literals. The template type parameter \p T is the type of the value that
28 /// will be returned from the string-switch expression. For example,
29 /// the following code switches on the name of a color in \c argv[i]:
30 ///
31 /// \code
32 /// Color color = StringSwitch<Color>(argv[i])
33 /// .Case("red", Red)
34 /// .Case("orange", Orange)
35 /// .Case("yellow", Yellow)
36 /// .Case("green", Green)
37 /// .Case("blue", Blue)
38 /// .Case("indigo", Indigo)
39 /// .Cases("violet", "purple", Violet)
40 /// .Default(UnknownColor);
41 /// \endcode
42 template<typename T, typename R = T>
43 class StringSwitch {
44  /// The string we are matching.
45  const StringRef Str;
46 
47  /// The pointer to the result of this switch statement, once known,
48  /// null before that.
49  Optional<T> Result;
50 
51 public:
53  explicit StringSwitch(StringRef S)
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
71  if (!Result && Str == S) {
72  Result = std::move(Value);
73  }
74  return *this;
75  }
76 
79  if (!Result && Str.endswith(S)) {
80  Result = std::move(Value);
81  }
82  return *this;
83  }
84 
87  if (!Result && Str.startswith(S)) {
88  Result = std::move(Value);
89  }
90  return *this;
91  }
92 
95  return Case(S0, Value).Case(S1, Value);
96  }
97 
100  T Value) {
101  return Case(S0, Value).Cases(S1, S2, Value);
102  }
103 
106  StringLiteral S3, T Value) {
107  return Case(S0, Value).Cases(S1, S2, S3, Value);
108  }
109 
113  return Case(S0, Value).Cases(S1, S2, S3, S4, Value);
114  }
115 
119  T Value) {
120  return Case(S0, Value).Cases(S1, S2, S3, S4, S5, Value);
121  }
122 
126  StringLiteral S6, T Value) {
127  return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, Value);
128  }
129 
134  return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, Value);
135  }
136 
141  T Value) {
142  return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, S8, Value);
143  }
144 
149  StringLiteral S9, T Value) {
150  return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, S8, S9, Value);
151  }
152 
153  // Case-insensitive case matchers.
156  if (!Result && Str.equals_lower(S))
157  Result = std::move(Value);
158 
159  return *this;
160  }
161 
164  if (!Result && Str.endswith_lower(S))
165  Result = Value;
166 
167  return *this;
168  }
169 
172  if (!Result && Str.startswith_lower(S))
173  Result = std::move(Value);
174 
175  return *this;
176  }
177 
180  return CaseLower(S0, Value).CaseLower(S1, Value);
181  }
182 
185  T Value) {
186  return CaseLower(S0, Value).CasesLower(S1, S2, Value);
187  }
188 
191  StringLiteral S3, T Value) {
192  return CaseLower(S0, Value).CasesLower(S1, S2, S3, Value);
193  }
194 
198  return CaseLower(S0, Value).CasesLower(S1, S2, S3, S4, Value);
199  }
200 
204  if (Result)
205  return std::move(*Result);
206  return Value;
207  }
208 
211  operator R() {
212  assert(Result && "Fell off the end of a string-switch");
213  return std::move(*Result);
214  }
215 };
216 
217 } // end namespace llvm
218 
219 #endif // LLVM_ADT_STRINGSWITCH_H
LLVM_NODISCARD bool startswith_lower(StringRef Prefix) const
Check if this string starts with the given Prefix, ignoring case.
Definition: StringRef.cpp:47
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
Definition: StringRef.h:176
~StringSwitch()=default
LLVM_ATTRIBUTE_ALWAYS_INLINE 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:138
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, T Value)
Definition: StringSwitch.h:117
#define LLVM_NODISCARD
LLVM_NODISCARD - Warn if a type or return value is discarded.
Definition: Compiler.h:129
LLVM_NODISCARD bool endswith_lower(StringRef Suffix) const
Check if this string ends with the given Suffix, ignoring case.
Definition: StringRef.cpp:53
#define LLVM_ATTRIBUTE_ALWAYS_INLINE
LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do so, mark a method "always...
Definition: Compiler.h:201
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:279
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & CasesLower(StringLiteral S0, StringLiteral S1, T Value)
Definition: StringSwitch.h:179
Definition: BitVector.h:921
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & StartsWithLower(StringLiteral S, T Value)
Definition: StringSwitch.h:171
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, T Value)
Definition: StringSwitch.h:105
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, T Value)
Definition: StringSwitch.h:190
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, T Value)
Definition: StringSwitch.h:184
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
Definition: StringSwitch.h:203
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, T Value)
Definition: StringSwitch.h:196
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:267
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, T Value)
Definition: StringSwitch.h:99
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & EndsWithLower(StringLiteral S, T Value)
Definition: StringSwitch.h:163
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, StringLiteral S6, T Value)
Definition: StringSwitch.h:124
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition: StringRef.h:869
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, T Value)
Definition: StringSwitch.h:111
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & EndsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:78
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & StartsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:86
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:70
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch(StringRef S)
Definition: StringSwitch.h:53
StringSwitch(StringSwitch &&other)
Definition: StringSwitch.h:63
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Definition: StringSwitch.h:94
LLVM_ATTRIBUTE_ALWAYS_INLINE 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:146
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & CaseLower(StringLiteral S, T Value)
Definition: StringSwitch.h:155
LLVM Value Representation.
Definition: Value.h:73
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, StringLiteral S6, StringLiteral S7, T Value)
Definition: StringSwitch.h:131
void operator=(const StringSwitch &)=delete
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49