Skip to content

Commit e11b5b8

Browse files
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
1 parent 242ddd5 commit e11b5b8

File tree

4 files changed

+61
-4
lines changed

4 files changed

+61
-4
lines changed

llvm/include/llvm/ADT/Twine.h

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
#include <cassert>
1616
#include <cstdint>
1717
#include <string>
18+
#if __cplusplus > 201402L
19+
#include <string_view>
20+
#endif
1821

1922
namespace llvm {
2023

@@ -99,6 +102,11 @@ namespace llvm {
99102
/// A pointer to a StringRef instance.
100103
StringRefKind,
101104

105+
#if __cplusplus > 201402L
106+
// A pointer to a std::string_view instance.
107+
StdStringViewKind,
108+
#endif
109+
102110
/// A pointer to a SmallString instance.
103111
SmallStringKind,
104112

@@ -139,6 +147,9 @@ namespace llvm {
139147
const char *cString;
140148
const std::string *stdString;
141149
const StringRef *stringRef;
150+
#if __cplusplus > 201402L
151+
const std::string_view *stdStringView;
152+
#endif
142153
const SmallVectorImpl<char> *smallString;
143154
const formatv_object_base *formatvObject;
144155
char character;
@@ -283,6 +294,15 @@ namespace llvm {
283294
assert(isValid() && "Invalid twine!");
284295
}
285296

297+
#if __cplusplus > 201402L
298+
/// Construct from an std::string_view.
299+
/*implicit*/ Twine(const std::string_view &Str)
300+
: LHSKind(StdStringViewKind) {
301+
LHS.stdStringView = &Str;
302+
assert(isValid() && "Invalid twine!");
303+
}
304+
#endif
305+
286306
/// Construct from a StringRef.
287307
/*implicit*/ Twine(const StringRef &Str) : LHSKind(StringRefKind) {
288308
LHS.stringRef = &Str;
@@ -410,6 +430,9 @@ namespace llvm {
410430
case EmptyKind:
411431
case CStringKind:
412432
case StdStringKind:
433+
#if __cplusplus > 201402L
434+
case StdStringViewKind:
435+
#endif
413436
case StringRefKind:
414437
case SmallStringKind:
415438
return true;
@@ -440,10 +463,18 @@ namespace llvm {
440463
assert(isSingleStringRef() &&"This cannot be had as a single stringref!");
441464
switch (getLHSKind()) {
442465
default: llvm_unreachable("Out of sync with isSingleStringRef");
443-
case EmptyKind: return StringRef();
444-
case CStringKind: return StringRef(LHS.cString);
445-
case StdStringKind: return StringRef(*LHS.stdString);
446-
case StringRefKind: return *LHS.stringRef;
466+
case EmptyKind:
467+
return StringRef();
468+
case CStringKind:
469+
return StringRef(LHS.cString);
470+
case StdStringKind:
471+
return StringRef(*LHS.stdString);
472+
#if __cplusplus > 201402L
473+
case StdStringViewKind:
474+
return StringRef(*LHS.stdStringView);
475+
#endif
476+
case StringRefKind:
477+
return *LHS.stringRef;
447478
case SmallStringKind:
448479
return StringRef(LHS.smallString->data(), LHS.smallString->size());
449480
}

llvm/include/llvm/Support/raw_ostream.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
#include <cstdint>
2323
#include <cstring>
2424
#include <string>
25+
#if __cplusplus > 201402L
26+
#include <string_view>
27+
#endif
2528
#include <system_error>
2629
#include <type_traits>
2730

@@ -233,6 +236,12 @@ class raw_ostream {
233236
return write(Str.data(), Str.length());
234237
}
235238

239+
#if __cplusplus > 201402L
240+
raw_ostream &operator<<(const std::string_view &Str) {
241+
return write(Str.data(), Str.length());
242+
}
243+
#endif
244+
236245
raw_ostream &operator<<(const SmallVectorImpl<char> &Str) {
237246
return write(Str.data(), Str.size());
238247
}

llvm/lib/Support/Twine.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ void Twine::printOneChild(raw_ostream &OS, Child Ptr,
6868
case Twine::StdStringKind:
6969
OS << *Ptr.stdString;
7070
break;
71+
#if __cplusplus > 201402L
72+
case StdStringViewKind:
73+
OS << StringRef(*Ptr.stdStringView);
74+
break;
75+
#endif
7176
case Twine::StringRefKind:
7277
OS << *Ptr.stringRef;
7378
break;
@@ -123,6 +128,11 @@ void Twine::printOneChildRepr(raw_ostream &OS, Child Ptr,
123128
OS << "std::string:\""
124129
<< Ptr.stdString << "\"";
125130
break;
131+
#if __cplusplus > 201402L
132+
case Twine::StdStringViewKind:
133+
OS << "std::string_view:\"" << StringRef(*Ptr.stdStringView) << "\"";
134+
break;
135+
#endif
126136
case Twine::StringRefKind:
127137
OS << "stringref:\""
128138
<< Ptr.stringRef << "\"";

llvm/unittests/ADT/TwineTest.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ TEST(TwineTest, Construction) {
3232
EXPECT_EQ("hi", Twine(StringRef("hithere", 2)).str());
3333
EXPECT_EQ("hi", Twine(SmallString<4>("hi")).str());
3434
EXPECT_EQ("hi", Twine(formatv("{0}", "hi")).str());
35+
#if __cplusplus > 201402L
36+
EXPECT_EQ("hi", Twine(std::string_view("hi")).str());
37+
#endif
3538
}
3639

3740
TEST(TwineTest, Numbers) {
@@ -73,6 +76,10 @@ TEST(TwineTest, Concat) {
7376
repr(Twine().concat(Twine(formatv("howdy")))));
7477
EXPECT_EQ("(Twine smallstring:\"hey\" cstring:\"there\")",
7578
repr(Twine(SmallString<7>("hey")).concat(Twine("there"))));
79+
#if __cplusplus > 201402L
80+
EXPECT_EQ("(Twine std::string_view:\"hey\" cstring:\"there\")",
81+
repr(Twine(std::string_view("hey")).concat(Twine("there"))));
82+
#endif
7683

7784
// Concatenation of unary ropes.
7885
EXPECT_EQ("(Twine cstring:\"a\" cstring:\"b\")",

0 commit comments

Comments
 (0)