From: Sterling Augustine Date: Tue, 8 Jun 2021 23:57:26 +0000 (-0700) Subject: Add Twine support for std::string_view. X-Git-Tag: llvmorg-14-init~4488 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e11b5b87bebf2aad41ad769015a21567198291b9;p=platform%2Fupstream%2Fllvm.git Add Twine support for std::string_view. With Twine now ubiquitous after rG92a79dbe91413f685ab19295fc7a6297dbd6c824, it needs support for string_view when building clang with newer C++ standards. This is similar to how StringRef is handled. Differential Revision: https://reviews.llvm.org/D103935 --- diff --git a/llvm/include/llvm/ADT/Twine.h b/llvm/include/llvm/ADT/Twine.h index 4140c22..235b814 100644 --- a/llvm/include/llvm/ADT/Twine.h +++ b/llvm/include/llvm/ADT/Twine.h @@ -15,6 +15,9 @@ #include #include #include +#if __cplusplus > 201402L +#include +#endif namespace llvm { @@ -99,6 +102,11 @@ namespace llvm { /// A pointer to a StringRef instance. StringRefKind, +#if __cplusplus > 201402L + // A pointer to a std::string_view instance. + StdStringViewKind, +#endif + /// A pointer to a SmallString instance. SmallStringKind, @@ -139,6 +147,9 @@ namespace llvm { const char *cString; const std::string *stdString; const StringRef *stringRef; +#if __cplusplus > 201402L + const std::string_view *stdStringView; +#endif const SmallVectorImpl *smallString; const formatv_object_base *formatvObject; char character; @@ -283,6 +294,15 @@ namespace llvm { assert(isValid() && "Invalid twine!"); } +#if __cplusplus > 201402L + /// Construct from an std::string_view. + /*implicit*/ Twine(const std::string_view &Str) + : LHSKind(StdStringViewKind) { + LHS.stdStringView = &Str; + assert(isValid() && "Invalid twine!"); + } +#endif + /// Construct from a StringRef. /*implicit*/ Twine(const StringRef &Str) : LHSKind(StringRefKind) { LHS.stringRef = &Str; @@ -410,6 +430,9 @@ namespace llvm { case EmptyKind: case CStringKind: case StdStringKind: +#if __cplusplus > 201402L + case StdStringViewKind: +#endif case StringRefKind: case SmallStringKind: return true; @@ -440,10 +463,18 @@ namespace llvm { assert(isSingleStringRef() &&"This cannot be had as a single stringref!"); switch (getLHSKind()) { default: llvm_unreachable("Out of sync with isSingleStringRef"); - case EmptyKind: return StringRef(); - case CStringKind: return StringRef(LHS.cString); - case StdStringKind: return StringRef(*LHS.stdString); - case StringRefKind: return *LHS.stringRef; + case EmptyKind: + return StringRef(); + case CStringKind: + return StringRef(LHS.cString); + case StdStringKind: + return StringRef(*LHS.stdString); +#if __cplusplus > 201402L + case StdStringViewKind: + return StringRef(*LHS.stdStringView); +#endif + case StringRefKind: + return *LHS.stringRef; case SmallStringKind: return StringRef(LHS.smallString->data(), LHS.smallString->size()); } diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h index 86d6570..c669c2b 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h @@ -22,6 +22,9 @@ #include #include #include +#if __cplusplus > 201402L +#include +#endif #include #include @@ -233,6 +236,12 @@ public: return write(Str.data(), Str.length()); } +#if __cplusplus > 201402L + raw_ostream &operator<<(const std::string_view &Str) { + return write(Str.data(), Str.length()); + } +#endif + raw_ostream &operator<<(const SmallVectorImpl &Str) { return write(Str.data(), Str.size()); } diff --git a/llvm/lib/Support/Twine.cpp b/llvm/lib/Support/Twine.cpp index fbbcd88..c1a254c 100644 --- a/llvm/lib/Support/Twine.cpp +++ b/llvm/lib/Support/Twine.cpp @@ -68,6 +68,11 @@ void Twine::printOneChild(raw_ostream &OS, Child Ptr, case Twine::StdStringKind: OS << *Ptr.stdString; break; +#if __cplusplus > 201402L + case StdStringViewKind: + OS << StringRef(*Ptr.stdStringView); + break; +#endif case Twine::StringRefKind: OS << *Ptr.stringRef; break; @@ -123,6 +128,11 @@ void Twine::printOneChildRepr(raw_ostream &OS, Child Ptr, OS << "std::string:\"" << Ptr.stdString << "\""; break; +#if __cplusplus > 201402L + case Twine::StdStringViewKind: + OS << "std::string_view:\"" << StringRef(*Ptr.stdStringView) << "\""; + break; +#endif case Twine::StringRefKind: OS << "stringref:\"" << Ptr.stringRef << "\""; diff --git a/llvm/unittests/ADT/TwineTest.cpp b/llvm/unittests/ADT/TwineTest.cpp index 52cec68..b9d107de 100644 --- a/llvm/unittests/ADT/TwineTest.cpp +++ b/llvm/unittests/ADT/TwineTest.cpp @@ -32,6 +32,9 @@ TEST(TwineTest, Construction) { EXPECT_EQ("hi", Twine(StringRef("hithere", 2)).str()); EXPECT_EQ("hi", Twine(SmallString<4>("hi")).str()); EXPECT_EQ("hi", Twine(formatv("{0}", "hi")).str()); +#if __cplusplus > 201402L + EXPECT_EQ("hi", Twine(std::string_view("hi")).str()); +#endif } TEST(TwineTest, Numbers) { @@ -73,6 +76,10 @@ TEST(TwineTest, Concat) { repr(Twine().concat(Twine(formatv("howdy"))))); EXPECT_EQ("(Twine smallstring:\"hey\" cstring:\"there\")", repr(Twine(SmallString<7>("hey")).concat(Twine("there")))); +#if __cplusplus > 201402L + EXPECT_EQ("(Twine std::string_view:\"hey\" cstring:\"there\")", + repr(Twine(std::string_view("hey")).concat(Twine("there")))); +#endif // Concatenation of unary ropes. EXPECT_EQ("(Twine cstring:\"a\" cstring:\"b\")",