Index: include/llvm/ADT/StringSwitch.h =================================================================== --- include/llvm/ADT/StringSwitch.h +++ include/llvm/ADT/StringSwitch.h @@ -46,12 +46,12 @@ /// \brief The pointer to the result of this switch statement, once known, /// null before that. - const T *Result; + Optional Result; public: LLVM_ATTRIBUTE_ALWAYS_INLINE explicit StringSwitch(StringRef S) - : Str(S), Result(nullptr) { } + : Str(S), Result() { } // StringSwitch is not copyable. StringSwitch(const StringSwitch &) = delete; @@ -61,187 +61,154 @@ *this = std::move(other); } StringSwitch &operator=(StringSwitch &&other) { - Str = other.Str; - Result = other.Result; + Str = std::move(other.Str); + Result = std::move(other.Result); return *this; } ~StringSwitch() = default; // Case-sensitive case matchers - template LLVM_ATTRIBUTE_ALWAYS_INLINE - StringSwitch& Case(const char (&S)[N], const T& Value) { - assert(N); - if (!Result && N-1 == Str.size() && - (N == 1 || std::memcmp(S, Str.data(), N-1) == 0)) { - Result = &Value; + StringSwitch &Case(StringLiteral S, T Value) { + if (!Result && Str == S) { + Result = std::move(Value); } return *this; } template LLVM_ATTRIBUTE_ALWAYS_INLINE - StringSwitch& EndsWith(const char (&S)[N], const T &Value) { + StringSwitch& EndsWith(const char (&S)[N], T Value) { assert(N); if (!Result && Str.size() >= N-1 && (N == 1 || std::memcmp(S, Str.data() + Str.size() + 1 - N, N-1) == 0)) { - Result = &Value; + Result = std::move(Value); } return *this; } template LLVM_ATTRIBUTE_ALWAYS_INLINE - StringSwitch& StartsWith(const char (&S)[N], const T &Value) { + StringSwitch& StartsWith(const char (&S)[N], T Value) { assert(N); if (!Result && Str.size() >= N-1 && (N == 1 || std::memcmp(S, Str.data(), N-1) == 0)) { - Result = &Value; + Result = std::move(Value); } return *this; } - template LLVM_ATTRIBUTE_ALWAYS_INLINE - StringSwitch &Cases(const char (&S0)[N0], const char (&S1)[N1], - const T& Value) { + StringSwitch &Cases(StringLiteral S0, StringLiteral S1, T Value) { return Case(S0, Value).Case(S1, Value); } - template LLVM_ATTRIBUTE_ALWAYS_INLINE - StringSwitch &Cases(const char (&S0)[N0], const char (&S1)[N1], - const char (&S2)[N2], const T& Value) { + StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, + T Value) { return Case(S0, Value).Cases(S1, S2, Value); } - 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) { + StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, + StringLiteral S3, T Value) { return Case(S0, Value).Cases(S1, S2, S3, Value); } - 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) { + StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, + StringLiteral S3, StringLiteral S4, T Value) { return Case(S0, Value).Cases(S1, S2, S3, S4, Value); } - 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 char (&S5)[N5], - const T &Value) { + StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, + StringLiteral S3, StringLiteral S4, StringLiteral S5, + T Value) { return Case(S0, Value).Cases(S1, S2, S3, S4, S5, Value); } - 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 char (&S5)[N5], - const char (&S6)[N6], const T &Value) { + StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, + StringLiteral S3, StringLiteral S4, StringLiteral S5, + StringLiteral S6, T Value) { return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, Value); } - 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 char (&S5)[N5], - const char (&S6)[N6], const char (&S7)[N7], - const T &Value) { + StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, + StringLiteral S3, StringLiteral S4, StringLiteral S5, + StringLiteral S6, StringLiteral S7, T Value) { return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, Value); } - 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 char (&S5)[N5], - const char (&S6)[N6], const char (&S7)[N7], - const char (&S8)[N8], const T &Value) { + StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, + StringLiteral S3, StringLiteral S4, StringLiteral S5, + StringLiteral S6, StringLiteral S7, StringLiteral S8, + T Value) { return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, S8, Value); } - 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 char (&S5)[N5], - const char (&S6)[N6], const char (&S7)[N7], - const char (&S8)[N8], const char (&S9)[N9], - const T &Value) { + StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, + StringLiteral S3, StringLiteral S4, StringLiteral S5, + StringLiteral S6, StringLiteral S7, StringLiteral S8, + StringLiteral S9, T Value) { 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; + LLVM_ATTRIBUTE_ALWAYS_INLINE + StringSwitch &CaseLower(StringLiteral S, T Value) { + if (!Result && Str.equals_lower(S)) + Result = std::move(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; + LLVM_ATTRIBUTE_ALWAYS_INLINE + StringSwitch &EndsWithLower(StringLiteral S, T Value) { + if (!Result && Str.endswith_lower(S)) + 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; + LLVM_ATTRIBUTE_ALWAYS_INLINE + StringSwitch &StartsWithLower(StringLiteral S, T Value) { + if (!Result && Str.startswith_lower(S)) + Result = std::move(Value); return *this; } - template - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & - CasesLower(const char (&S0)[N0], const char (&S1)[N1], const T &Value) { + + LLVM_ATTRIBUTE_ALWAYS_INLINE + StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, 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) { + LLVM_ATTRIBUTE_ALWAYS_INLINE + StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, + 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) { + LLVM_ATTRIBUTE_ALWAYS_INLINE + StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, + StringLiteral S3, 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) { + LLVM_ATTRIBUTE_ALWAYS_INLINE + StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, + StringLiteral S3, StringLiteral S4, T Value) { return CaseLower(S0, Value).CasesLower(S1, S2, S3, S4, Value); } LLVM_ATTRIBUTE_ALWAYS_INLINE - R Default(const T &Value) const { + R Default(T Value) const { if (Result) return *Result; return Value; Index: unittests/ADT/StringSwitchTest.cpp =================================================================== --- unittests/ADT/StringSwitchTest.cpp +++ unittests/ADT/StringSwitchTest.cpp @@ -158,7 +158,7 @@ auto Translate = [](StringRef S) { return llvm::StringSwitch(S) - .Cases("wind\0ws", "win32", "winnt", OSType::Windows) + .Cases(llvm::StringRef("wind\0ws",7), "win32", "winnt", OSType::Windows) .Cases("linux", "unix", "*nix", "posix", OSType::Linux) .Default(OSType::Unknown); }; @@ -184,7 +184,8 @@ auto Translate = [](StringRef S) { return llvm::StringSwitch(S) - .CasesLower("wind\0ws", "win32", "winnt", OSType::Windows) + .CasesLower(llvm::StringRef("wind\0ws", 7), "win32", "winnt", + OSType::Windows) .CasesLower("linux", "unix", "*nix", "posix", OSType::Linux) .Default(OSType::Unknown); };