LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 <cassert>
18 #include <cstring>
19 
20 namespace llvm {
21 
22 /// \brief A switch()-like statement whose cases are string literals.
23 ///
24 /// The StringSwitch class is a simple form of a switch() statement that
25 /// determines whether the given string matches one of the given string
26 /// literals. The template type parameter \p T is the type of the value that
27 /// will be returned from the string-switch expression. For example,
28 /// the following code switches on the name of a color in \c argv[i]:
29 ///
30 /// \code
31 /// Color color = StringSwitch<Color>(argv[i])
32 /// .Case("red", Red)
33 /// .Case("orange", Orange)
34 /// .Case("yellow", Yellow)
35 /// .Case("green", Green)
36 /// .Case("blue", Blue)
37 /// .Case("indigo", Indigo)
38 /// .Cases("violet", "purple", Violet)
39 /// .Default(UnknownColor);
40 /// \endcode
41 template<typename T, typename R = T>
42 class StringSwitch {
43  /// \brief The string we are matching.
44  StringRef Str;
45 
46  /// \brief The pointer to the result of this switch statement, once known,
47  /// null before that.
48  const T *Result;
49 
50 public:
51  explicit StringSwitch(StringRef S)
52  : Str(S), Result(0) { }
53 
54  template<unsigned N>
55  StringSwitch& Case(const char (&S)[N], const T& Value) {
56  if (!Result && N-1 == Str.size() &&
57  (std::memcmp(S, Str.data(), N-1) == 0)) {
58  Result = &Value;
59  }
60 
61  return *this;
62  }
63 
64  template<unsigned N>
65  StringSwitch& EndsWith(const char (&S)[N], const T &Value) {
66  if (!Result && Str.size() >= N-1 &&
67  std::memcmp(S, Str.data() + Str.size() + 1 - N, N-1) == 0) {
68  Result = &Value;
69  }
70 
71  return *this;
72  }
73 
74  template<unsigned N>
75  StringSwitch& StartsWith(const char (&S)[N], const T &Value) {
76  if (!Result && Str.size() >= N-1 &&
77  std::memcmp(S, Str.data(), N-1) == 0) {
78  Result = &Value;
79  }
80 
81  return *this;
82  }
83 
84  template<unsigned N0, unsigned N1>
85  StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
86  const T& Value) {
87  return Case(S0, Value).Case(S1, Value);
88  }
89 
90  template<unsigned N0, unsigned N1, unsigned N2>
91  StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
92  const char (&S2)[N2], const T& Value) {
93  return Case(S0, Value).Case(S1, Value).Case(S2, Value);
94  }
95 
96  template<unsigned N0, unsigned N1, unsigned N2, unsigned N3>
97  StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
98  const char (&S2)[N2], const char (&S3)[N3],
99  const T& Value) {
100  return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value);
101  }
102 
103  template<unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4>
104  StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
105  const char (&S2)[N2], const char (&S3)[N3],
106  const char (&S4)[N4], const T& Value) {
107  return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value)
108  .Case(S4, Value);
109  }
110 
111  R Default(const T& Value) const {
112  if (Result)
113  return *Result;
114 
115  return Value;
116  }
117 
118  operator R() const {
119  assert(Result && "Fell off the end of a string-switch");
120  return *Result;
121  }
122 };
123 
124 } // end namespace llvm
125 
126 #endif // LLVM_ADT_STRINGSWITCH_H
size_t size() const
size - Get the string size.
Definition: StringRef.h:113
StringSwitch & Case(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:55
StringSwitch & Cases(const char(&S0)[N0], const char(&S1)[N1], const char(&S2)[N2], const T &Value)
Definition: StringSwitch.h:91
StringSwitch & EndsWith(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:65
const char * data() const
Definition: StringRef.h:107
int memcmp(const void *s1, const void *s2, size_t n);
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
StringSwitch & Cases(const char(&S0)[N0], const char(&S1)[N1], const char(&S2)[N2], const char(&S3)[N3], const char(&S4)[N4], const T &Value)
Definition: StringSwitch.h:104
StringSwitch & Cases(const char(&S0)[N0], const char(&S1)[N1], const char(&S2)[N2], const char(&S3)[N3], const T &Value)
Definition: StringSwitch.h:97
StringSwitch & StartsWith(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:75
StringSwitch(StringRef S)
Definition: StringSwitch.h:51
R Default(const T &Value) const
Definition: StringSwitch.h:111
#define N
LLVM Value Representation.
Definition: Value.h:66
StringSwitch & Cases(const char(&S0)[N0], const char(&S1)[N1], const T &Value)
Definition: StringSwitch.h:85