#include <cassert>
#include <cstdint>
#include <string>
+#if __cplusplus > 201402L
+#include <string_view>
+#endif
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,
const char *cString;
const std::string *stdString;
const StringRef *stringRef;
+#if __cplusplus > 201402L
+ const std::string_view *stdStringView;
+#endif
const SmallVectorImpl<char> *smallString;
const formatv_object_base *formatvObject;
char character;
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;
case EmptyKind:
case CStringKind:
case StdStringKind:
+#if __cplusplus > 201402L
+ case StdStringViewKind:
+#endif
case StringRefKind:
case SmallStringKind:
return true;
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());
}
#include <cstdint>
#include <cstring>
#include <string>
+#if __cplusplus > 201402L
+#include <string_view>
+#endif
#include <system_error>
#include <type_traits>
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<char> &Str) {
return write(Str.data(), Str.size());
}
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;
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 << "\"";
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) {
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\")",