/// A pointer to an std::string instance.
StdStringKind,
- /// A pointer to a StringRef instance.
- StringRefKind,
-
- /// A pointer to a SmallString instance.
- SmallStringKind,
-
- /// A Pointer and Length representation. Used for std::string_view.
- /// Can't use a StringRef here because they are not trivally
- /// constructible.
+ /// A Pointer and Length representation. Used for std::string_view,
+ /// StringRef, and SmallString. Can't use a StringRef here
+ /// because they are not trivally constructible.
PtrAndLengthKind,
/// A pointer to a formatv_object_base instance.
{
const Twine *twine;
const char *cString;
+ const std::string *stdString;
struct {
const char *ptr;
size_t length;
} ptrAndLength;
- const std::string *stdString;
- const StringRef *stringRef;
- const SmallVectorImpl<char> *smallString;
const formatv_object_base *formatvObject;
char character;
unsigned int decUI;
#endif
/// Construct from a StringRef.
- /*implicit*/ Twine(const StringRef &Str) : LHSKind(StringRefKind) {
- LHS.stringRef = &Str;
+ /*implicit*/ Twine(const StringRef &Str) : LHSKind(PtrAndLengthKind) {
+ LHS.ptrAndLength.ptr = Str.data();
+ LHS.ptrAndLength.length = Str.size();
assert(isValid() && "Invalid twine!");
}
/// Construct from a SmallString.
/*implicit*/ Twine(const SmallVectorImpl<char> &Str)
- : LHSKind(SmallStringKind) {
- LHS.smallString = &Str;
+ : LHSKind(PtrAndLengthKind) {
+ LHS.ptrAndLength.ptr = Str.data();
+ LHS.ptrAndLength.length = Str.size();
assert(isValid() && "Invalid twine!");
}
/// Construct as the concatenation of a C string and a StringRef.
/*implicit*/ Twine(const char *LHS, const StringRef &RHS)
- : LHSKind(CStringKind), RHSKind(StringRefKind) {
+ : LHSKind(CStringKind), RHSKind(PtrAndLengthKind) {
this->LHS.cString = LHS;
- this->RHS.stringRef = &RHS;
+ this->RHS.ptrAndLength.ptr = RHS.data();
+ this->RHS.ptrAndLength.length = RHS.size();
assert(isValid() && "Invalid twine!");
}
/// Construct as the concatenation of a StringRef and a C string.
/*implicit*/ Twine(const StringRef &LHS, const char *RHS)
- : LHSKind(StringRefKind), RHSKind(CStringKind) {
- this->LHS.stringRef = &LHS;
+ : LHSKind(PtrAndLengthKind), RHSKind(CStringKind) {
+ this->LHS.ptrAndLength.ptr = LHS.data();
+ this->LHS.ptrAndLength.length = LHS.size();
this->RHS.cString = RHS;
assert(isValid() && "Invalid twine!");
}
case EmptyKind:
case CStringKind:
case StdStringKind:
- case StringRefKind:
- case SmallStringKind:
case PtrAndLengthKind:
return true;
default:
return StringRef(LHS.cString);
case StdStringKind:
return StringRef(*LHS.stdString);
- case StringRefKind:
- return *LHS.stringRef;
- case SmallStringKind:
- return StringRef(LHS.smallString->data(), LHS.smallString->size());
case PtrAndLengthKind:
return StringRef(LHS.ptrAndLength.ptr, LHS.ptrAndLength.length);
}
case Twine::CStringKind:
OS << Ptr.cString;
break;
- case Twine::PtrAndLengthKind:
- OS << StringRef(Ptr.ptrAndLength.ptr, Ptr.ptrAndLength.length);
- break;
case Twine::StdStringKind:
OS << *Ptr.stdString;
break;
- case Twine::StringRefKind:
- OS << *Ptr.stringRef;
- break;
- case Twine::SmallStringKind:
- OS << *Ptr.smallString;
+ case Twine::PtrAndLengthKind:
+ OS << StringRef(Ptr.ptrAndLength.ptr, Ptr.ptrAndLength.length);
break;
case Twine::FormatvObjectKind:
OS << *Ptr.formatvObject;
OS << "cstring:\""
<< Ptr.cString << "\"";
break;
- case Twine::PtrAndLengthKind:
- OS << "ptrAndLength:\""
- << StringRef(Ptr.ptrAndLength.ptr, Ptr.ptrAndLength.length) << "\"";
- break;
case Twine::StdStringKind:
OS << "std::string:\""
<< Ptr.stdString << "\"";
break;
- case Twine::StringRefKind:
- OS << "stringref:\""
- << Ptr.stringRef << "\"";
- break;
- case Twine::SmallStringKind:
- OS << "smallstring:\"" << *Ptr.smallString << "\"";
+ case Twine::PtrAndLengthKind:
+ OS << "ptrAndLength:\""
+ << StringRef(Ptr.ptrAndLength.ptr, Ptr.ptrAndLength.length) << "\"";
break;
case Twine::FormatvObjectKind:
OS << "formatv:\"" << *Ptr.formatvObject << "\"";
repr(Twine("hi").concat(Twine())));
EXPECT_EQ("(Twine cstring:\"hi\" empty)",
repr(Twine().concat(Twine("hi"))));
- EXPECT_EQ("(Twine smallstring:\"hi\" empty)",
+ EXPECT_EQ("(Twine ptrAndLength:\"hi\" empty)",
repr(Twine().concat(Twine(SmallString<5>("hi")))));
EXPECT_EQ("(Twine formatv:\"howdy\" empty)",
repr(Twine(formatv("howdy")).concat(Twine())));
EXPECT_EQ("(Twine formatv:\"howdy\" empty)",
repr(Twine().concat(Twine(formatv("howdy")))));
- EXPECT_EQ("(Twine smallstring:\"hey\" cstring:\"there\")",
+ EXPECT_EQ("(Twine ptrAndLength:\"hey\" cstring:\"there\")",
repr(Twine(SmallString<7>("hey")).concat(Twine("there"))));
#if __cplusplus > 201402L
EXPECT_EQ("(Twine ptrAndLength:\"hey\" cstring:\"there\")",
repr(Twine("a").concat(Twine("b")).concat(Twine("c"))));
EXPECT_EQ("(Twine cstring:\"a\" rope:(Twine cstring:\"b\" cstring:\"c\"))",
repr(Twine("a").concat(Twine("b").concat(Twine("c")))));
- EXPECT_EQ("(Twine cstring:\"a\" rope:(Twine smallstring:\"b\" cstring:\"c\"))",
- repr(Twine("a").concat(Twine(SmallString<3>("b")).concat(Twine("c")))));
+ EXPECT_EQ(
+ "(Twine cstring:\"a\" rope:(Twine ptrAndLength:\"b\" cstring:\"c\"))",
+ repr(Twine("a").concat(Twine(SmallString<3>("b")).concat(Twine("c")))));
}
TEST(TwineTest, toNullTerminatedStringRef) {