X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FStringSwitch.h;h=42b0fc4bc441f68b2d55e0b70e4e63b6fec0fb29;hb=HEAD;hp=7dd5647df6051b59c264009ede855b4c8aa504a3;hpb=d01518630ad165e0bc7d7194abb183abfa93e0d5;p=oota-llvm.git diff --git a/include/llvm/ADT/StringSwitch.h b/include/llvm/ADT/StringSwitch.h index 7dd5647df60..42b0fc4bc44 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 #include @@ -48,10 +49,12 @@ class StringSwitch { const T *Result; public: - explicit StringSwitch(StringRef Str) - : Str(Str), Result(0) { } + LLVM_ATTRIBUTE_ALWAYS_INLINE + explicit StringSwitch(StringRef S) + : Str(S), Result(nullptr) { } template + 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)) { @@ -61,33 +64,89 @@ public: return *this; } + template + 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) { + Result = &Value; + } + + return *this; + } + + template + 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) { + Result = &Value; + } + + return *this; + } + template + 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 + 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 + 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 + 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; @@ -95,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;