aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/ADT/StringSwitch.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/ADT/StringSwitch.h')
-rw-r--r--include/llvm/ADT/StringSwitch.h50
1 files changed, 45 insertions, 5 deletions
diff --git a/include/llvm/ADT/StringSwitch.h b/include/llvm/ADT/StringSwitch.h
index 0393a0c373ef..42b0fc4bc441 100644
--- a/include/llvm/ADT/StringSwitch.h
+++ b/include/llvm/ADT/StringSwitch.h
@@ -14,6 +14,7 @@
#define LLVM_ADT_STRINGSWITCH_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstring>
@@ -48,10 +49,12 @@ class StringSwitch {
const T *Result;
public:
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
explicit StringSwitch(StringRef S)
: Str(S), Result(nullptr) { }
template<unsigned N>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& Case(const char (&S)[N], const T& Value) {
if (!Result && N-1 == Str.size() &&
(std::memcmp(S, Str.data(), N-1) == 0)) {
@@ -62,6 +65,7 @@ public:
}
template<unsigned N>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& EndsWith(const char (&S)[N], const T &Value) {
if (!Result && Str.size() >= N-1 &&
std::memcmp(S, Str.data() + Str.size() + 1 - N, N-1) == 0) {
@@ -72,6 +76,7 @@ public:
}
template<unsigned N>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& StartsWith(const char (&S)[N], const T &Value) {
if (!Result && Str.size() >= N-1 &&
std::memcmp(S, Str.data(), N-1) == 0) {
@@ -82,32 +87,66 @@ public:
}
template<unsigned N0, unsigned N1>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const T& Value) {
- return Case(S0, Value).Case(S1, Value);
+ if (!Result && (
+ (N0-1 == Str.size() && std::memcmp(S0, Str.data(), N0-1) == 0) ||
+ (N1-1 == Str.size() && std::memcmp(S1, Str.data(), N1-1) == 0))) {
+ Result = &Value;
+ }
+
+ return *this;
}
template<unsigned N0, unsigned N1, unsigned N2>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const char (&S2)[N2], const T& Value) {
- return Case(S0, Value).Case(S1, Value).Case(S2, Value);
+ if (!Result && (
+ (N0-1 == Str.size() && std::memcmp(S0, Str.data(), N0-1) == 0) ||
+ (N1-1 == Str.size() && std::memcmp(S1, Str.data(), N1-1) == 0) ||
+ (N2-1 == Str.size() && std::memcmp(S2, Str.data(), N2-1) == 0))) {
+ Result = &Value;
+ }
+
+ return *this;
}
template<unsigned N0, unsigned N1, unsigned N2, unsigned N3>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const char (&S2)[N2], const char (&S3)[N3],
const T& Value) {
- return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value);
+ if (!Result && (
+ (N0-1 == Str.size() && std::memcmp(S0, Str.data(), N0-1) == 0) ||
+ (N1-1 == Str.size() && std::memcmp(S1, Str.data(), N1-1) == 0) ||
+ (N2-1 == Str.size() && std::memcmp(S2, Str.data(), N2-1) == 0) ||
+ (N3-1 == Str.size() && std::memcmp(S3, Str.data(), N3-1) == 0))) {
+ Result = &Value;
+ }
+
+ return *this;
}
template<unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
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) {
- return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value)
- .Case(S4, Value);
+ if (!Result && (
+ (N0-1 == Str.size() && std::memcmp(S0, Str.data(), N0-1) == 0) ||
+ (N1-1 == Str.size() && std::memcmp(S1, Str.data(), N1-1) == 0) ||
+ (N2-1 == Str.size() && std::memcmp(S2, Str.data(), N2-1) == 0) ||
+ (N3-1 == Str.size() && std::memcmp(S3, Str.data(), N3-1) == 0) ||
+ (N4-1 == Str.size() && std::memcmp(S4, Str.data(), N4-1) == 0))) {
+ Result = &Value;
+ }
+
+ return *this;
}
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
R Default(const T& Value) const {
if (Result)
return *Result;
@@ -115,6 +154,7 @@ public:
return Value;
}
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
operator R() const {
assert(Result && "Fell off the end of a string-switch");
return *Result;