diff options
Diffstat (limited to 'include/llvm/ADT/StringSwitch.h')
-rw-r--r-- | include/llvm/ADT/StringSwitch.h | 188 |
1 files changed, 74 insertions, 114 deletions
diff --git a/include/llvm/ADT/StringSwitch.h b/include/llvm/ADT/StringSwitch.h index 75577b7738ba..b7860b98ce5d 100644 --- a/include/llvm/ADT/StringSwitch.h +++ b/include/llvm/ADT/StringSwitch.h @@ -20,7 +20,7 @@ namespace llvm { -/// \brief A switch()-like statement whose cases are string literals. +/// A switch()-like statement whose cases are string literals. /// /// The StringSwitch class is a simple form of a switch() statement that /// determines whether the given string matches one of the given string @@ -41,216 +41,176 @@ namespace llvm { /// \endcode template<typename T, typename R = T> class StringSwitch { - /// \brief The string we are matching. - StringRef Str; + /// The string we are matching. + const StringRef Str; - /// \brief The pointer to the result of this switch statement, once known, + /// The pointer to the result of this switch statement, once known, /// null before that. - const T *Result; + Optional<T> 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; + + // StringSwitch is not assignable due to 'Str' being 'const'. void operator=(const StringSwitch &) = delete; + void operator=(StringSwitch &&other) = delete; - StringSwitch(StringSwitch &&other) { - *this = std::move(other); - } - StringSwitch &operator=(StringSwitch &&other) { - Str = other.Str; - Result = other.Result; - return *this; - } + StringSwitch(StringSwitch &&other) + : Str(other.Str), Result(std::move(other.Result)) { } ~StringSwitch() = default; // Case-sensitive case matchers - template<unsigned N> 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<unsigned N> LLVM_ATTRIBUTE_ALWAYS_INLINE - StringSwitch& EndsWith(const char (&S)[N], const 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; + StringSwitch& EndsWith(StringLiteral S, T Value) { + if (!Result && Str.endswith(S)) { + Result = std::move(Value); } return *this; } - template<unsigned N> LLVM_ATTRIBUTE_ALWAYS_INLINE - StringSwitch& StartsWith(const char (&S)[N], const T &Value) { - assert(N); - if (!Result && Str.size() >= N-1 && - (N == 1 || std::memcmp(S, Str.data(), N-1) == 0)) { - Result = &Value; + StringSwitch& StartsWith(StringLiteral S, T Value) { + if (!Result && Str.startswith(S)) { + Result = std::move(Value); } return *this; } - template<unsigned N0, unsigned N1> 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<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) { + StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, + T Value) { return Case(S0, Value).Cases(S1, S2, Value); } - 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) { + StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, + StringLiteral S3, T Value) { return Case(S0, Value).Cases(S1, S2, S3, Value); } - 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) { + 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 <unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4, - unsigned N5> 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 <unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4, - unsigned N5, unsigned N6> 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 <unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4, - unsigned N5, unsigned N6, unsigned N7> 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 <unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4, - unsigned N5, unsigned N6, unsigned N7, unsigned N8> 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 <unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4, - unsigned N5, unsigned N6, unsigned N7, unsigned N8, unsigned N9> 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 <unsigned N> - 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 <unsigned N> - 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 <unsigned N> - 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 <unsigned N0, unsigned N1> - 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 <unsigned N0, unsigned N1, unsigned N2> - 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 <unsigned N0, unsigned N1, unsigned N2, unsigned N3> - 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 <unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4> - 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_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE - R Default(const T &Value) const { + R Default(T Value) { if (Result) - return *Result; + return std::move(*Result); return Value; } + LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE - operator R() const { + operator R() { assert(Result && "Fell off the end of a string-switch"); - return *Result; + return std::move(*Result); } }; |