Index: include/llvm/ADT/StringSwitch.h =================================================================== --- include/llvm/ADT/StringSwitch.h +++ include/llvm/ADT/StringSwitch.h @@ -15,6 +15,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Error.h" #include #include @@ -68,6 +69,7 @@ ~StringSwitch() = default; + // Case-sensitive case matchers template LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch& Case(const char (&S)[N], const T& Value) { @@ -182,14 +184,76 @@ return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, S8, S9, Value); } + // Case-insensitive case matchers. + template + LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &CaseLower(const char (&S)[N], + const T &Value) { + if (!Result && Str.equals_lower(StringRef(S, N - 1))) + Result = &Value; + + return *this; + } + + template + LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &EndsWithLower(const char (&S)[N], + const T &Value) { + if (!Result && Str.endswith_lower(StringRef(S, N - 1))) + Result = &Value; + + return *this; + } + + template + LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &StartsWithLower(const char (&S)[N], + const T &Value) { + if (!Result && Str.startswith_lower(StringRef(S, N - 1))) + Result = &Value; + + return *this; + } + template + LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & + CasesLower(const char (&S0)[N0], const char (&S1)[N1], const T &Value) { + return CaseLower(S0, Value).CaseLower(S1, Value); + } + + template + LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & + CasesLower(const char (&S0)[N0], const char (&S1)[N1], const char (&S2)[N2], + const T &Value) { + return CaseLower(S0, Value).CasesLower(S1, S2, Value); + } + + template + LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & + CasesLower(const char (&S0)[N0], const char (&S1)[N1], const char (&S2)[N2], + const char (&S3)[N3], const T &Value) { + return CaseLower(S0, Value).CasesLower(S1, S2, S3, Value); + } + + template + LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & + CasesLower(const char (&S0)[N0], const char (&S1)[N1], const char (&S2)[N2], + const char (&S3)[N3], const char (&S4)[N4], const T &Value) { + return CaseLower(S0, Value).CasesLower(S1, S2, S3, S4, Value); + } + LLVM_ATTRIBUTE_ALWAYS_INLINE - R Default(const T& Value) const { + R Default(const T &Value) const { if (Result) return *Result; return Value; } LLVM_ATTRIBUTE_ALWAYS_INLINE + Expected Expect() const { + if (Result) + return *Result; + return make_error("Value did not occur in StringSwitch", + inconvertibleErrorCode()); + } + + LLVM_ATTRIBUTE_ALWAYS_INLINE operator R() const { assert(Result && "Fell off the end of a string-switch"); return *Result; Index: unittests/ADT/CMakeLists.txt =================================================================== --- unittests/ADT/CMakeLists.txt +++ unittests/ADT/CMakeLists.txt @@ -56,6 +56,7 @@ StringExtrasTest.cpp StringMapTest.cpp StringRefTest.cpp + StringSwitchTest.cpp TinyPtrVectorTest.cpp TripleTest.cpp TwineTest.cpp