X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FStringSwitch.h;h=74805830d8546ec6317ed52c4a24ee033212ef5e;hb=e82fafe9e22c7f0bb35ec4cb7d5428bf9e930807;hp=6562d57d3bb0ef64215d7068b6005e17d45075f4;hpb=2cd8abbf8631921c744d021214dd21998a25a946;p=oota-llvm.git diff --git a/include/llvm/ADT/StringSwitch.h b/include/llvm/ADT/StringSwitch.h index 6562d57d3bb..74805830d85 100644 --- a/include/llvm/ADT/StringSwitch.h +++ b/include/llvm/ADT/StringSwitch.h @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===/ // // This file implements the StringSwitch template, which mimics a switch() -// statements whose cases are string literals. +// statement whose cases are string literals. // //===----------------------------------------------------------------------===/ #ifndef LLVM_ADT_STRINGSWITCH_H @@ -18,7 +18,7 @@ #include namespace llvm { - + /// \brief A switch()-like statement whose cases are string literals. /// /// The StringSwitch class is a simple form of a switch() statement that @@ -35,48 +35,64 @@ namespace llvm { /// .Case("green", Green) /// .Case("blue", Blue) /// .Case("indigo", Indigo) -/// .Case("violet", Violet) +/// .Cases("violet", "purple", Violet) /// .Default(UnknownColor); /// \endcode -template +template class StringSwitch { /// \brief The string we are matching. StringRef Str; - - /// \brief The result of this switch statement, once known. - T Result; - - /// \brief Set true when the result of this switch is already known; in this - /// case, Result is valid. - bool ResultKnown; - + + /// \brief The pointer to the result of this switch statement, once known, + /// null before that. + const T *Result; + public: - explicit StringSwitch(StringRef Str) - : Str(Str), ResultKnown(false) { } - + explicit StringSwitch(StringRef Str) + : Str(Str), Result(0) { } + template StringSwitch& Case(const char (&S)[N], const T& Value) { - if (!ResultKnown && N-1 == Str.size() && + if (!Result && N-1 == Str.size() && (std::memcmp(S, Str.data(), N-1) == 0)) { - Result = Value; - ResultKnown = true; + Result = &Value; + } + + return *this; + } + + template + 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 + 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 StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1], const T& Value) { return Case(S0, Value).Case(S1, Value); } - + template 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); } - + template StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1], const char (&S2)[N2], const char (&S3)[N3], @@ -87,21 +103,21 @@ public: template 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) { + const char (&S4)[N4], const T& Value) { return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value) .Case(S4, Value); } - - T Default(const T& Value) { - if (ResultKnown) - return Result; - + + R Default(const T& Value) const { + if (Result) + return *Result; + return Value; } - - operator T() { - assert(ResultKnown && "Fell off the end of a string-switch"); - return Result; + + operator R() const { + assert(Result && "Fell off the end of a string-switch"); + return *Result; } };