diff options
Diffstat (limited to 'include/llvm/ADT/StringSwitch.h')
-rw-r--r-- | include/llvm/ADT/StringSwitch.h | 50 |
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; |