1//===- llvm/unittest/ADT/StringRefTest.cpp - StringRef unit tests ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/ADT/StringRef.h"
10#include "llvm/ADT/Hashing.h"
11#include "llvm/ADT/STLExtras.h"
12#include "llvm/ADT/SmallVector.h"
13#include "llvm/ADT/StringExtras.h"
14#include "llvm/Support/Allocator.h"
15#include "llvm/Support/raw_ostream.h"
16#include "gtest/gtest.h"
17using namespace llvm;
18
19namespace llvm {
20
21std::ostream &operator<<(std::ostream &OS, const StringRef &S) {
22 OS << S.str();
23 return OS;
24}
25
26std::ostream &operator<<(std::ostream &OS,
27 const std::pair<StringRef, StringRef> &P) {
28 OS << "(" << P.first << ", " << P.second << ")";
29 return OS;
30}
31
32}
33
34// Check that we can't accidentally assign a temporary std::string to a
35// StringRef. (Unfortunately we can't make use of the same thing with
36// constructors.)
37static_assert(!std::is_assignable_v<StringRef &, std::string>,
38 "Assigning from prvalue std::string");
39static_assert(!std::is_assignable_v<StringRef &, std::string &&>,
40 "Assigning from xvalue std::string");
41static_assert(std::is_assignable_v<StringRef &, std::string &>,
42 "Assigning from lvalue std::string");
43static_assert(std::is_assignable_v<StringRef &, const char *>,
44 "Assigning from prvalue C string");
45static_assert(std::is_assignable_v<StringRef &, const char *&&>,
46 "Assigning from xvalue C string");
47static_assert(std::is_assignable_v<StringRef &, const char *&>,
48 "Assigning from lvalue C string");
49
50namespace {
51TEST(StringRefTest, Construction) {
52 EXPECT_EQ("", StringRef());
53 EXPECT_EQ("hello", StringRef("hello"));
54 EXPECT_EQ("hello", StringRef("hello world", 5));
55 EXPECT_EQ("hello", StringRef(std::string("hello")));
56 EXPECT_EQ("hello", StringRef(std::string_view("hello")));
57}
58
59TEST(StringRefTest, Conversion) {
60 EXPECT_EQ("hello", std::string(StringRef("hello")));
61 EXPECT_EQ("hello", std::string_view(StringRef("hello")));
62 static_assert(std::string_view(StringRef("hello")) == "hello");
63}
64
65TEST(StringRefTest, EmptyInitializerList) {
66 StringRef S = {};
67 EXPECT_TRUE(S.empty());
68
69 S = {};
70 EXPECT_TRUE(S.empty());
71}
72
73TEST(StringRefTest, Iteration) {
74 StringRef S("hello");
75 const char *p = "hello";
76 for (const char *it = S.begin(), *ie = S.end(); it != ie; ++it, ++p)
77 EXPECT_EQ(*it, *p);
78}
79
80TEST(StringRefTest, StringOps) {
81 const char *p = "hello";
82
83 EXPECT_EQ(p, StringRef(p, 0).data());
84 static_assert(StringRef("hello").data()[0] == 'h');
85 static_assert(StringRef("hello").data()[1] == 'e');
86 static_assert(StringRef("hello").data()[2] == 'l');
87 static_assert(StringRef("hello").data()[3] == 'l');
88 static_assert(StringRef("hello").data()[4] == 'o');
89 static_assert(StringRef("hello").data()[5] == '\0');
90
91 EXPECT_TRUE(StringRef().empty());
92 static_assert(StringRef("").empty());
93 static_assert(!StringRef("hello").empty());
94
95 EXPECT_EQ((size_t) 5, StringRef("hello").size());
96 static_assert(StringRef("hello").size() == 5);
97
98 EXPECT_GT( 0, StringRef("aab").compare("aad"));
99 EXPECT_EQ( 0, StringRef("aab").compare("aab"));
100 EXPECT_LT( 0, StringRef("aab").compare("aaa"));
101 EXPECT_GT( 0, StringRef("aab").compare("aabb"));
102 EXPECT_LT( 0, StringRef("aab").compare("aa"));
103 EXPECT_LT( 0, StringRef("\xFF").compare("\1"));
104
105 EXPECT_EQ(-1, StringRef("AaB").compare_insensitive("aAd"));
106 EXPECT_EQ( 0, StringRef("AaB").compare_insensitive("aab"));
107 EXPECT_EQ( 1, StringRef("AaB").compare_insensitive("AAA"));
108 EXPECT_EQ(-1, StringRef("AaB").compare_insensitive("aaBb"));
109 EXPECT_EQ(-1, StringRef("AaB").compare_insensitive("bb"));
110 EXPECT_EQ( 1, StringRef("aaBb").compare_insensitive("AaB"));
111 EXPECT_EQ( 1, StringRef("bb").compare_insensitive("AaB"));
112 EXPECT_EQ( 1, StringRef("AaB").compare_insensitive("aA"));
113 EXPECT_EQ( 1, StringRef("\xFF").compare_insensitive("\1"));
114
115 EXPECT_EQ(-1, StringRef("aab").compare_numeric("aad"));
116 EXPECT_EQ( 0, StringRef("aab").compare_numeric("aab"));
117 EXPECT_EQ( 1, StringRef("aab").compare_numeric("aaa"));
118 EXPECT_EQ(-1, StringRef("aab").compare_numeric("aabb"));
119 EXPECT_EQ( 1, StringRef("aab").compare_numeric("aa"));
120 EXPECT_EQ(-1, StringRef("1").compare_numeric("10"));
121 EXPECT_EQ( 0, StringRef("10").compare_numeric("10"));
122 EXPECT_EQ( 0, StringRef("10a").compare_numeric("10a"));
123 EXPECT_EQ( 1, StringRef("2").compare_numeric("1"));
124 EXPECT_EQ( 0, StringRef("llvm_v1i64_ty").compare_numeric("llvm_v1i64_ty"));
125 EXPECT_EQ( 1, StringRef("\xFF").compare_numeric("\1"));
126 EXPECT_EQ( 1, StringRef("V16").compare_numeric("V1_q0"));
127 EXPECT_EQ(-1, StringRef("V1_q0").compare_numeric("V16"));
128 EXPECT_EQ(-1, StringRef("V8_q0").compare_numeric("V16"));
129 EXPECT_EQ( 1, StringRef("V16").compare_numeric("V8_q0"));
130 EXPECT_EQ(-1, StringRef("V1_q0").compare_numeric("V8_q0"));
131 EXPECT_EQ( 1, StringRef("V8_q0").compare_numeric("V1_q0"));
132}
133
134TEST(StringRefTest, Operators) {
135 EXPECT_EQ("", StringRef());
136 EXPECT_TRUE(StringRef("aab") < StringRef("aad"));
137 EXPECT_FALSE(StringRef("aab") < StringRef("aab"));
138 EXPECT_TRUE(StringRef("aab") <= StringRef("aab"));
139 EXPECT_FALSE(StringRef("aab") <= StringRef("aaa"));
140 EXPECT_TRUE(StringRef("aad") > StringRef("aab"));
141 EXPECT_FALSE(StringRef("aab") > StringRef("aab"));
142 EXPECT_TRUE(StringRef("aab") >= StringRef("aab"));
143 EXPECT_FALSE(StringRef("aaa") >= StringRef("aab"));
144 EXPECT_EQ(StringRef("aab"), StringRef("aab"));
145 EXPECT_FALSE(StringRef("aab") == StringRef("aac"));
146 EXPECT_FALSE(StringRef("aab") != StringRef("aab"));
147 EXPECT_TRUE(StringRef("aab") != StringRef("aac"));
148 EXPECT_EQ('a', StringRef("aab")[1]);
149}
150
151TEST(StringRefTest, Substr) {
152 StringRef Str("hello");
153 EXPECT_EQ("lo", Str.substr(3));
154 EXPECT_EQ("", Str.substr(100));
155 EXPECT_EQ("hello", Str.substr(0, 100));
156 EXPECT_EQ("o", Str.substr(4, 10));
157}
158
159TEST(StringRefTest, Slice) {
160 StringRef Str("hello");
161 EXPECT_EQ("l", Str.slice(2, 3));
162 EXPECT_EQ("ell", Str.slice(1, 4));
163 EXPECT_EQ("llo", Str.slice(2, 100));
164 EXPECT_EQ("", Str.slice(2, 1));
165 EXPECT_EQ("", Str.slice(10, 20));
166}
167
168TEST(StringRefTest, Split) {
169 StringRef Str("hello");
170 EXPECT_EQ(std::make_pair(StringRef("hello"), StringRef("")),
171 Str.split('X'));
172 EXPECT_EQ(std::make_pair(StringRef("h"), StringRef("llo")),
173 Str.split('e'));
174 EXPECT_EQ(std::make_pair(StringRef(""), StringRef("ello")),
175 Str.split('h'));
176 EXPECT_EQ(std::make_pair(StringRef("he"), StringRef("lo")),
177 Str.split('l'));
178 EXPECT_EQ(std::make_pair(StringRef("hell"), StringRef("")),
179 Str.split('o'));
180
181 EXPECT_EQ(std::make_pair(StringRef("hello"), StringRef("")),
182 Str.rsplit('X'));
183 EXPECT_EQ(std::make_pair(StringRef("h"), StringRef("llo")),
184 Str.rsplit('e'));
185 EXPECT_EQ(std::make_pair(StringRef(""), StringRef("ello")),
186 Str.rsplit('h'));
187 EXPECT_EQ(std::make_pair(StringRef("hel"), StringRef("o")),
188 Str.rsplit('l'));
189 EXPECT_EQ(std::make_pair(StringRef("hell"), StringRef("")),
190 Str.rsplit('o'));
191
192 EXPECT_EQ(std::make_pair(StringRef("he"), StringRef("o")),
193 Str.rsplit("ll"));
194 EXPECT_EQ(std::make_pair(StringRef(""), StringRef("ello")),
195 Str.rsplit("h"));
196 EXPECT_EQ(std::make_pair(StringRef("hell"), StringRef("")),
197 Str.rsplit("o"));
198 EXPECT_EQ(std::make_pair(StringRef("hello"), StringRef("")),
199 Str.rsplit("::"));
200 EXPECT_EQ(std::make_pair(StringRef("hel"), StringRef("o")),
201 Str.rsplit("l"));
202}
203
204TEST(StringRefTest, Split2) {
205 SmallVector<StringRef, 5> parts;
206 SmallVector<StringRef, 5> expected;
207
208 expected.push_back(Elt: "ab"); expected.push_back(Elt: "c");
209 StringRef(",ab,,c,").split(A&: parts, Separator: ",", MaxSplit: -1, KeepEmpty: false);
210 EXPECT_TRUE(parts == expected);
211
212 expected.clear(); parts.clear();
213 expected.push_back(Elt: ""); expected.push_back(Elt: "ab"); expected.push_back(Elt: "");
214 expected.push_back(Elt: "c"); expected.push_back(Elt: "");
215 StringRef(",ab,,c,").split(A&: parts, Separator: ",", MaxSplit: -1, KeepEmpty: true);
216 EXPECT_TRUE(parts == expected);
217
218 expected.clear(); parts.clear();
219 expected.push_back(Elt: "");
220 StringRef("").split(A&: parts, Separator: ",", MaxSplit: -1, KeepEmpty: true);
221 EXPECT_TRUE(parts == expected);
222
223 expected.clear(); parts.clear();
224 StringRef("").split(A&: parts, Separator: ",", MaxSplit: -1, KeepEmpty: false);
225 EXPECT_TRUE(parts == expected);
226
227 expected.clear(); parts.clear();
228 StringRef(",").split(A&: parts, Separator: ",", MaxSplit: -1, KeepEmpty: false);
229 EXPECT_TRUE(parts == expected);
230
231 expected.clear(); parts.clear();
232 expected.push_back(Elt: ""); expected.push_back(Elt: "");
233 StringRef(",").split(A&: parts, Separator: ",", MaxSplit: -1, KeepEmpty: true);
234 EXPECT_TRUE(parts == expected);
235
236 expected.clear(); parts.clear();
237 expected.push_back(Elt: "a"); expected.push_back(Elt: "b");
238 StringRef("a,b").split(A&: parts, Separator: ",", MaxSplit: -1, KeepEmpty: true);
239 EXPECT_TRUE(parts == expected);
240
241 // Test MaxSplit
242 expected.clear(); parts.clear();
243 expected.push_back(Elt: "a,,b,c");
244 StringRef("a,,b,c").split(A&: parts, Separator: ",", MaxSplit: 0, KeepEmpty: true);
245 EXPECT_TRUE(parts == expected);
246
247 expected.clear(); parts.clear();
248 expected.push_back(Elt: "a,,b,c");
249 StringRef("a,,b,c").split(A&: parts, Separator: ",", MaxSplit: 0, KeepEmpty: false);
250 EXPECT_TRUE(parts == expected);
251
252 expected.clear(); parts.clear();
253 expected.push_back(Elt: "a"); expected.push_back(Elt: ",b,c");
254 StringRef("a,,b,c").split(A&: parts, Separator: ",", MaxSplit: 1, KeepEmpty: true);
255 EXPECT_TRUE(parts == expected);
256
257 expected.clear(); parts.clear();
258 expected.push_back(Elt: "a"); expected.push_back(Elt: ",b,c");
259 StringRef("a,,b,c").split(A&: parts, Separator: ",", MaxSplit: 1, KeepEmpty: false);
260 EXPECT_TRUE(parts == expected);
261
262 expected.clear(); parts.clear();
263 expected.push_back(Elt: "a"); expected.push_back(Elt: ""); expected.push_back(Elt: "b,c");
264 StringRef("a,,b,c").split(A&: parts, Separator: ",", MaxSplit: 2, KeepEmpty: true);
265 EXPECT_TRUE(parts == expected);
266
267 expected.clear(); parts.clear();
268 expected.push_back(Elt: "a"); expected.push_back(Elt: "b,c");
269 StringRef("a,,b,c").split(A&: parts, Separator: ",", MaxSplit: 2, KeepEmpty: false);
270 EXPECT_TRUE(parts == expected);
271
272 expected.clear(); parts.clear();
273 expected.push_back(Elt: "a"); expected.push_back(Elt: ""); expected.push_back(Elt: "b");
274 expected.push_back(Elt: "c");
275 StringRef("a,,b,c").split(A&: parts, Separator: ",", MaxSplit: 3, KeepEmpty: true);
276 EXPECT_TRUE(parts == expected);
277
278 expected.clear(); parts.clear();
279 expected.push_back(Elt: "a"); expected.push_back(Elt: "b"); expected.push_back(Elt: "c");
280 StringRef("a,,b,c").split(A&: parts, Separator: ",", MaxSplit: 3, KeepEmpty: false);
281 EXPECT_TRUE(parts == expected);
282
283 expected.clear(); parts.clear();
284 expected.push_back(Elt: "a"); expected.push_back(Elt: "b"); expected.push_back(Elt: "c");
285 StringRef("a,,b,c").split(A&: parts, Separator: ',', MaxSplit: 3, KeepEmpty: false);
286 EXPECT_TRUE(parts == expected);
287
288 expected.clear(); parts.clear();
289 expected.push_back(Elt: "");
290 StringRef().split(A&: parts, Separator: ",", MaxSplit: 0, KeepEmpty: true);
291 EXPECT_TRUE(parts == expected);
292
293 expected.clear(); parts.clear();
294 expected.push_back(Elt: StringRef());
295 StringRef("").split(A&: parts, Separator: ",", MaxSplit: 0, KeepEmpty: true);
296 EXPECT_TRUE(parts == expected);
297
298 expected.clear(); parts.clear();
299 StringRef("").split(A&: parts, Separator: ",", MaxSplit: 0, KeepEmpty: false);
300 EXPECT_TRUE(parts == expected);
301 StringRef().split(A&: parts, Separator: ",", MaxSplit: 0, KeepEmpty: false);
302 EXPECT_TRUE(parts == expected);
303
304 expected.clear(); parts.clear();
305 expected.push_back(Elt: "a");
306 expected.push_back(Elt: "");
307 expected.push_back(Elt: "b");
308 expected.push_back(Elt: "c,d");
309 StringRef("a,,b,c,d").split(A&: parts, Separator: ",", MaxSplit: 3, KeepEmpty: true);
310 EXPECT_TRUE(parts == expected);
311
312 expected.clear(); parts.clear();
313 expected.push_back(Elt: "");
314 StringRef().split(A&: parts, Separator: ',', MaxSplit: 0, KeepEmpty: true);
315 EXPECT_TRUE(parts == expected);
316
317 expected.clear(); parts.clear();
318 expected.push_back(Elt: StringRef());
319 StringRef("").split(A&: parts, Separator: ',', MaxSplit: 0, KeepEmpty: true);
320 EXPECT_TRUE(parts == expected);
321
322 expected.clear(); parts.clear();
323 StringRef("").split(A&: parts, Separator: ',', MaxSplit: 0, KeepEmpty: false);
324 EXPECT_TRUE(parts == expected);
325 StringRef().split(A&: parts, Separator: ',', MaxSplit: 0, KeepEmpty: false);
326 EXPECT_TRUE(parts == expected);
327
328 expected.clear(); parts.clear();
329 expected.push_back(Elt: "a");
330 expected.push_back(Elt: "");
331 expected.push_back(Elt: "b");
332 expected.push_back(Elt: "c,d");
333 StringRef("a,,b,c,d").split(A&: parts, Separator: ',', MaxSplit: 3, KeepEmpty: true);
334 EXPECT_TRUE(parts == expected);
335}
336
337TEST(StringRefTest, Trim) {
338 StringRef Str0("hello");
339 StringRef Str1(" hello ");
340 StringRef Str2(" hello ");
341 StringRef Str3("\t\n\v\f\r hello \t\n\v\f\r");
342
343 EXPECT_EQ(StringRef("hello"), Str0.rtrim());
344 EXPECT_EQ(StringRef(" hello"), Str1.rtrim());
345 EXPECT_EQ(StringRef(" hello"), Str2.rtrim());
346 EXPECT_EQ(StringRef("\t\n\v\f\r hello"), Str3.rtrim());
347 EXPECT_EQ(StringRef("hello"), Str0.ltrim());
348 EXPECT_EQ(StringRef("hello "), Str1.ltrim());
349 EXPECT_EQ(StringRef("hello "), Str2.ltrim());
350 EXPECT_EQ(StringRef("hello \t\n\v\f\r"), Str3.ltrim());
351 EXPECT_EQ(StringRef("hello"), Str0.trim());
352 EXPECT_EQ(StringRef("hello"), Str1.trim());
353 EXPECT_EQ(StringRef("hello"), Str2.trim());
354 EXPECT_EQ(StringRef("hello"), Str3.trim());
355
356 EXPECT_EQ(StringRef("ello"), Str0.trim("hhhhhhhhhhh"));
357
358 EXPECT_EQ(StringRef(""), StringRef("").trim());
359 EXPECT_EQ(StringRef(""), StringRef(" ").trim());
360 EXPECT_EQ(StringRef("\0", 1), StringRef(" \0 ", 3).trim());
361 EXPECT_EQ(StringRef("\0\0", 2), StringRef("\0\0", 2).trim());
362 EXPECT_EQ(StringRef("x"), StringRef("\0\0x\0\0", 5).trim('\0'));
363}
364
365TEST(StringRefTest, StartsWith) {
366 StringRef Str("hello");
367 EXPECT_TRUE(Str.starts_with(""));
368 EXPECT_TRUE(Str.starts_with("he"));
369 EXPECT_FALSE(Str.starts_with("helloworld"));
370 EXPECT_FALSE(Str.starts_with("hi"));
371}
372
373TEST(StringRefTest, StartsWithInsensitive) {
374 StringRef Str("heLLo");
375 EXPECT_TRUE(Str.starts_with_insensitive(""));
376 EXPECT_TRUE(Str.starts_with_insensitive("he"));
377 EXPECT_TRUE(Str.starts_with_insensitive("hell"));
378 EXPECT_TRUE(Str.starts_with_insensitive("HELlo"));
379 EXPECT_FALSE(Str.starts_with_insensitive("helloworld"));
380 EXPECT_FALSE(Str.starts_with_insensitive("hi"));
381}
382
383TEST(StringRefTest, ConsumeFront) {
384 StringRef Str("hello");
385 EXPECT_TRUE(Str.consume_front(""));
386 EXPECT_EQ("hello", Str);
387 EXPECT_TRUE(Str.consume_front("he"));
388 EXPECT_EQ("llo", Str);
389 EXPECT_FALSE(Str.consume_front("lloworld"));
390 EXPECT_EQ("llo", Str);
391 EXPECT_FALSE(Str.consume_front("lol"));
392 EXPECT_EQ("llo", Str);
393 EXPECT_TRUE(Str.consume_front("llo"));
394 EXPECT_EQ("", Str);
395 EXPECT_FALSE(Str.consume_front("o"));
396 EXPECT_TRUE(Str.consume_front(""));
397}
398
399TEST(StringRefTest, ConsumeFrontInsensitive) {
400 StringRef Str("heLLo");
401 EXPECT_TRUE(Str.consume_front_insensitive(""));
402 EXPECT_EQ("heLLo", Str);
403 EXPECT_FALSE(Str.consume_front("HEl"));
404 EXPECT_EQ("heLLo", Str);
405 EXPECT_TRUE(Str.consume_front_insensitive("HEl"));
406 EXPECT_EQ("Lo", Str);
407 EXPECT_FALSE(Str.consume_front_insensitive("loworld"));
408 EXPECT_EQ("Lo", Str);
409 EXPECT_FALSE(Str.consume_front_insensitive("ol"));
410 EXPECT_EQ("Lo", Str);
411 EXPECT_TRUE(Str.consume_front_insensitive("lo"));
412 EXPECT_EQ("", Str);
413 EXPECT_FALSE(Str.consume_front_insensitive("o"));
414 EXPECT_TRUE(Str.consume_front_insensitive(""));
415}
416
417TEST(StringRefTest, EndsWith) {
418 StringRef Str("hello");
419 EXPECT_TRUE(Str.ends_with(""));
420 EXPECT_TRUE(Str.ends_with("lo"));
421 EXPECT_FALSE(Str.ends_with("helloworld"));
422 EXPECT_FALSE(Str.ends_with("worldhello"));
423 EXPECT_FALSE(Str.ends_with("so"));
424}
425
426TEST(StringRefTest, EndsWithInsensitive) {
427 StringRef Str("heLLo");
428 EXPECT_TRUE(Str.ends_with_insensitive(""));
429 EXPECT_TRUE(Str.ends_with_insensitive("lo"));
430 EXPECT_TRUE(Str.ends_with_insensitive("LO"));
431 EXPECT_TRUE(Str.ends_with_insensitive("ELlo"));
432 EXPECT_FALSE(Str.ends_with_insensitive("helloworld"));
433 EXPECT_FALSE(Str.ends_with_insensitive("hi"));
434}
435
436TEST(StringRefTest, ConsumeBack) {
437 StringRef Str("hello");
438 EXPECT_TRUE(Str.consume_back(""));
439 EXPECT_EQ("hello", Str);
440 EXPECT_TRUE(Str.consume_back("lo"));
441 EXPECT_EQ("hel", Str);
442 EXPECT_FALSE(Str.consume_back("helhel"));
443 EXPECT_EQ("hel", Str);
444 EXPECT_FALSE(Str.consume_back("hle"));
445 EXPECT_EQ("hel", Str);
446 EXPECT_TRUE(Str.consume_back("hel"));
447 EXPECT_EQ("", Str);
448 EXPECT_FALSE(Str.consume_back("h"));
449 EXPECT_TRUE(Str.consume_back(""));
450}
451
452TEST(StringRefTest, ConsumeBackInsensitive) {
453 StringRef Str("heLLo");
454 EXPECT_TRUE(Str.consume_back_insensitive(""));
455 EXPECT_EQ("heLLo", Str);
456 EXPECT_FALSE(Str.consume_back("lO"));
457 EXPECT_EQ("heLLo", Str);
458 EXPECT_TRUE(Str.consume_back_insensitive("lO"));
459 EXPECT_EQ("heL", Str);
460 EXPECT_FALSE(Str.consume_back_insensitive("helhel"));
461 EXPECT_EQ("heL", Str);
462 EXPECT_FALSE(Str.consume_back_insensitive("hle"));
463 EXPECT_EQ("heL", Str);
464 EXPECT_TRUE(Str.consume_back_insensitive("hEl"));
465 EXPECT_EQ("", Str);
466 EXPECT_FALSE(Str.consume_back_insensitive("h"));
467 EXPECT_TRUE(Str.consume_back_insensitive(""));
468}
469
470TEST(StringRefTest, Find) {
471 StringRef Str("helloHELLO");
472 StringRef LongStr("hellx xello hell ello world foo bar hello HELLO");
473
474 struct {
475 StringRef Str;
476 char C;
477 std::size_t From;
478 std::size_t Pos;
479 std::size_t InsensitivePos;
480 } CharExpectations[] = {
481 {.Str: Str, .C: 'h', .From: 0U, .Pos: 0U, .InsensitivePos: 0U},
482 {.Str: Str, .C: 'e', .From: 0U, .Pos: 1U, .InsensitivePos: 1U},
483 {.Str: Str, .C: 'l', .From: 0U, .Pos: 2U, .InsensitivePos: 2U},
484 {.Str: Str, .C: 'l', .From: 3U, .Pos: 3U, .InsensitivePos: 3U},
485 {.Str: Str, .C: 'o', .From: 0U, .Pos: 4U, .InsensitivePos: 4U},
486 {.Str: Str, .C: 'L', .From: 0U, .Pos: 7U, .InsensitivePos: 2U},
487 {.Str: Str, .C: 'z', .From: 0U, .Pos: StringRef::npos, .InsensitivePos: StringRef::npos},
488 };
489
490 struct {
491 StringRef Str;
492 llvm::StringRef S;
493 std::size_t From;
494 std::size_t Pos;
495 std::size_t InsensitivePos;
496 } StrExpectations[] = {
497 {.Str: Str, .S: "helloword", .From: 0, .Pos: StringRef::npos, .InsensitivePos: StringRef::npos},
498 {.Str: Str, .S: "hello", .From: 0, .Pos: 0U, .InsensitivePos: 0U},
499 {.Str: Str, .S: "ello", .From: 0, .Pos: 1U, .InsensitivePos: 1U},
500 {.Str: Str, .S: "zz", .From: 0, .Pos: StringRef::npos, .InsensitivePos: StringRef::npos},
501 {.Str: Str, .S: "ll", .From: 2U, .Pos: 2U, .InsensitivePos: 2U},
502 {.Str: Str, .S: "ll", .From: 3U, .Pos: StringRef::npos, .InsensitivePos: 7U},
503 {.Str: Str, .S: "LL", .From: 2U, .Pos: 7U, .InsensitivePos: 2U},
504 {.Str: Str, .S: "LL", .From: 3U, .Pos: 7U, .InsensitivePos: 7U},
505 {.Str: Str, .S: "", .From: 0U, .Pos: 0U, .InsensitivePos: 0U},
506 {.Str: LongStr, .S: "hello", .From: 0U, .Pos: 36U, .InsensitivePos: 36U},
507 {.Str: LongStr, .S: "foo", .From: 0U, .Pos: 28U, .InsensitivePos: 28U},
508 {.Str: LongStr, .S: "hell", .From: 2U, .Pos: 12U, .InsensitivePos: 12U},
509 {.Str: LongStr, .S: "HELL", .From: 2U, .Pos: 42U, .InsensitivePos: 12U},
510 {.Str: LongStr, .S: "", .From: 0U, .Pos: 0U, .InsensitivePos: 0U}};
511
512 for (auto &E : CharExpectations) {
513 EXPECT_EQ(E.Pos, E.Str.find(E.C, E.From));
514 EXPECT_EQ(E.InsensitivePos, E.Str.find_insensitive(E.C, E.From));
515 EXPECT_EQ(E.InsensitivePos, E.Str.find_insensitive(toupper(E.C), E.From));
516 }
517
518 for (auto &E : StrExpectations) {
519 EXPECT_EQ(E.Pos, E.Str.find(E.S, E.From));
520 EXPECT_EQ(E.InsensitivePos, E.Str.find_insensitive(E.S, E.From));
521 EXPECT_EQ(E.InsensitivePos, E.Str.find_insensitive(E.S.upper(), E.From));
522 }
523
524 EXPECT_EQ(3U, Str.rfind('l'));
525 EXPECT_EQ(StringRef::npos, Str.rfind('z'));
526 EXPECT_EQ(StringRef::npos, Str.rfind("helloworld"));
527 EXPECT_EQ(0U, Str.rfind("hello"));
528 EXPECT_EQ(1U, Str.rfind("ello"));
529 EXPECT_EQ(StringRef::npos, Str.rfind("zz"));
530
531 EXPECT_EQ(8U, Str.rfind_insensitive('l'));
532 EXPECT_EQ(8U, Str.rfind_insensitive('L'));
533 EXPECT_EQ(StringRef::npos, Str.rfind_insensitive('z'));
534 EXPECT_EQ(StringRef::npos, Str.rfind_insensitive("HELLOWORLD"));
535 EXPECT_EQ(5U, Str.rfind("HELLO"));
536 EXPECT_EQ(6U, Str.rfind("ELLO"));
537 EXPECT_EQ(StringRef::npos, Str.rfind("ZZ"));
538
539 EXPECT_EQ(2U, Str.find_first_of('l'));
540 EXPECT_EQ(1U, Str.find_first_of("el"));
541 EXPECT_EQ(StringRef::npos, Str.find_first_of("xyz"));
542
543 Str = "hello";
544 EXPECT_EQ(1U, Str.find_first_not_of('h'));
545 EXPECT_EQ(4U, Str.find_first_not_of("hel"));
546 EXPECT_EQ(StringRef::npos, Str.find_first_not_of("hello"));
547
548 EXPECT_EQ(3U, Str.find_last_not_of('o'));
549 EXPECT_EQ(1U, Str.find_last_not_of("lo"));
550 EXPECT_EQ(StringRef::npos, Str.find_last_not_of("helo"));
551}
552
553TEST(StringRefTest, Count) {
554 StringRef Str("hello");
555 EXPECT_EQ(2U, Str.count('l'));
556 EXPECT_EQ(1U, Str.count('o'));
557 EXPECT_EQ(0U, Str.count('z'));
558 EXPECT_EQ(0U, Str.count("helloworld"));
559 EXPECT_EQ(1U, Str.count("hello"));
560 EXPECT_EQ(1U, Str.count("ello"));
561 EXPECT_EQ(0U, Str.count("zz"));
562 EXPECT_EQ(0U, Str.count(""));
563
564 StringRef OverlappingAbba("abbabba");
565 EXPECT_EQ(1U, OverlappingAbba.count("abba"));
566 StringRef NonOverlappingAbba("abbaabba");
567 EXPECT_EQ(2U, NonOverlappingAbba.count("abba"));
568 StringRef ComplexAbba("abbabbaxyzabbaxyz");
569 EXPECT_EQ(2U, ComplexAbba.count("abba"));
570}
571
572TEST(StringRefTest, EditDistance) {
573 StringRef Hello("hello");
574 EXPECT_EQ(2U, Hello.edit_distance("hill"));
575
576 StringRef Industry("industry");
577 EXPECT_EQ(6U, Industry.edit_distance("interest"));
578
579 StringRef Soylent("soylent green is people");
580 EXPECT_EQ(19U, Soylent.edit_distance("people soiled our green"));
581 EXPECT_EQ(26U, Soylent.edit_distance("people soiled our green",
582 /* allow replacements = */ false));
583 EXPECT_EQ(9U, Soylent.edit_distance("people soiled our green",
584 /* allow replacements = */ true,
585 /* max edit distance = */ 8));
586 EXPECT_EQ(53U, Soylent.edit_distance("people soiled our green "
587 "people soiled our green "
588 "people soiled our green "));
589}
590
591TEST(StringRefTest, EditDistanceInsensitive) {
592 StringRef Hello("HELLO");
593 EXPECT_EQ(2U, Hello.edit_distance_insensitive("hill"));
594 EXPECT_EQ(0U, Hello.edit_distance_insensitive("hello"));
595
596 StringRef Industry("InDuStRy");
597 EXPECT_EQ(6U, Industry.edit_distance_insensitive("iNtErEsT"));
598}
599
600TEST(StringRefTest, Misc) {
601 std::string Storage;
602 raw_string_ostream OS(Storage);
603 OS << StringRef("hello");
604 EXPECT_EQ("hello", OS.str());
605}
606
607TEST(StringRefTest, Hashing) {
608 EXPECT_EQ(hash_value(std::string()), hash_value(StringRef()));
609 EXPECT_EQ(hash_value(std::string()), hash_value(StringRef("")));
610 std::string S = "hello world";
611 hash_code H = hash_value(arg: S);
612 EXPECT_EQ(H, hash_value(StringRef("hello world")));
613 EXPECT_EQ(H, hash_value(StringRef(S)));
614 EXPECT_NE(H, hash_value(StringRef("hello worl")));
615 EXPECT_EQ(hash_value(std::string("hello worl")),
616 hash_value(StringRef("hello worl")));
617 EXPECT_NE(H, hash_value(StringRef("hello world ")));
618 EXPECT_EQ(hash_value(std::string("hello world ")),
619 hash_value(StringRef("hello world ")));
620 EXPECT_EQ(H, hash_value(StringRef("hello world\0")));
621 EXPECT_NE(hash_value(std::string("ello worl")),
622 hash_value(StringRef("hello world").slice(1, -1)));
623}
624
625struct UnsignedPair {
626 const char *Str;
627 uint64_t Expected;
628} Unsigned[] =
629 { {.Str: "0", .Expected: 0}
630 , {.Str: "255", .Expected: 255}
631 , {.Str: "256", .Expected: 256}
632 , {.Str: "65535", .Expected: 65535}
633 , {.Str: "65536", .Expected: 65536}
634 , {.Str: "4294967295", .Expected: 4294967295ULL}
635 , {.Str: "4294967296", .Expected: 4294967296ULL}
636 , {.Str: "18446744073709551615", .Expected: 18446744073709551615ULL}
637 , {.Str: "042", .Expected: 34}
638 , {.Str: "0x42", .Expected: 66}
639 , {.Str: "0b101010", .Expected: 42}
640 };
641
642struct SignedPair {
643 const char *Str;
644 int64_t Expected;
645} Signed[] =
646 { {.Str: "0", .Expected: 0}
647 , {.Str: "-0", .Expected: 0}
648 , {.Str: "127", .Expected: 127}
649 , {.Str: "128", .Expected: 128}
650 , {.Str: "-128", .Expected: -128}
651 , {.Str: "-129", .Expected: -129}
652 , {.Str: "32767", .Expected: 32767}
653 , {.Str: "32768", .Expected: 32768}
654 , {.Str: "-32768", .Expected: -32768}
655 , {.Str: "-32769", .Expected: -32769}
656 , {.Str: "2147483647", .Expected: 2147483647LL}
657 , {.Str: "2147483648", .Expected: 2147483648LL}
658 , {.Str: "-2147483648", .Expected: -2147483648LL}
659 , {.Str: "-2147483649", .Expected: -2147483649LL}
660 , {.Str: "-9223372036854775808", .Expected: -(9223372036854775807LL) - 1}
661 , {.Str: "042", .Expected: 34}
662 , {.Str: "0x42", .Expected: 66}
663 , {.Str: "0b101010", .Expected: 42}
664 , {.Str: "-042", .Expected: -34}
665 , {.Str: "-0x42", .Expected: -66}
666 , {.Str: "-0b101010", .Expected: -42}
667 };
668
669TEST(StringRefTest, getAsInteger) {
670 uint8_t U8;
671 uint16_t U16;
672 uint32_t U32;
673 uint64_t U64;
674
675 for (size_t i = 0; i < std::size(Unsigned); ++i) {
676 bool U8Success = StringRef(Unsigned[i].Str).getAsInteger(Radix: 0, Result&: U8);
677 if (static_cast<uint8_t>(Unsigned[i].Expected) == Unsigned[i].Expected) {
678 ASSERT_FALSE(U8Success);
679 EXPECT_EQ(U8, Unsigned[i].Expected);
680 } else {
681 ASSERT_TRUE(U8Success);
682 }
683 bool U16Success = StringRef(Unsigned[i].Str).getAsInteger(Radix: 0, Result&: U16);
684 if (static_cast<uint16_t>(Unsigned[i].Expected) == Unsigned[i].Expected) {
685 ASSERT_FALSE(U16Success);
686 EXPECT_EQ(U16, Unsigned[i].Expected);
687 } else {
688 ASSERT_TRUE(U16Success);
689 }
690 bool U32Success = StringRef(Unsigned[i].Str).getAsInteger(Radix: 0, Result&: U32);
691 if (static_cast<uint32_t>(Unsigned[i].Expected) == Unsigned[i].Expected) {
692 ASSERT_FALSE(U32Success);
693 EXPECT_EQ(U32, Unsigned[i].Expected);
694 } else {
695 ASSERT_TRUE(U32Success);
696 }
697 bool U64Success = StringRef(Unsigned[i].Str).getAsInteger(Radix: 0, Result&: U64);
698 ASSERT_FALSE(U64Success);
699 EXPECT_EQ(U64, Unsigned[i].Expected);
700 }
701
702 int8_t S8;
703 int16_t S16;
704 int32_t S32;
705 int64_t S64;
706
707 for (size_t i = 0; i < std::size(Signed); ++i) {
708 bool S8Success = StringRef(Signed[i].Str).getAsInteger(Radix: 0, Result&: S8);
709 if (static_cast<int8_t>(Signed[i].Expected) == Signed[i].Expected) {
710 ASSERT_FALSE(S8Success);
711 EXPECT_EQ(S8, Signed[i].Expected);
712 } else {
713 ASSERT_TRUE(S8Success);
714 }
715 bool S16Success = StringRef(Signed[i].Str).getAsInteger(Radix: 0, Result&: S16);
716 if (static_cast<int16_t>(Signed[i].Expected) == Signed[i].Expected) {
717 ASSERT_FALSE(S16Success);
718 EXPECT_EQ(S16, Signed[i].Expected);
719 } else {
720 ASSERT_TRUE(S16Success);
721 }
722 bool S32Success = StringRef(Signed[i].Str).getAsInteger(Radix: 0, Result&: S32);
723 if (static_cast<int32_t>(Signed[i].Expected) == Signed[i].Expected) {
724 ASSERT_FALSE(S32Success);
725 EXPECT_EQ(S32, Signed[i].Expected);
726 } else {
727 ASSERT_TRUE(S32Success);
728 }
729 bool S64Success = StringRef(Signed[i].Str).getAsInteger(Radix: 0, Result&: S64);
730 ASSERT_FALSE(S64Success);
731 EXPECT_EQ(S64, Signed[i].Expected);
732 }
733}
734
735
736static const char* BadStrings[] = {
737 "" // empty string
738 , "18446744073709551617" // value just over max
739 , "123456789012345678901" // value way too large
740 , "4t23v" // illegal decimal characters
741 , "0x123W56" // illegal hex characters
742 , "0b2" // illegal bin characters
743 , "08" // illegal oct characters
744 , "0o8" // illegal oct characters
745 , "-123" // negative unsigned value
746 , "0x"
747 , "0b"
748};
749
750
751TEST(StringRefTest, getAsUnsignedIntegerBadStrings) {
752 unsigned long long U64;
753 for (size_t i = 0; i < std::size(BadStrings); ++i) {
754 bool IsBadNumber = StringRef(BadStrings[i]).getAsInteger(Radix: 0, Result&: U64);
755 ASSERT_TRUE(IsBadNumber);
756 }
757}
758
759struct ConsumeUnsignedPair {
760 const char *Str;
761 uint64_t Expected;
762 const char *Leftover;
763} ConsumeUnsigned[] = {
764 {.Str: "0", .Expected: 0, .Leftover: ""},
765 {.Str: "255", .Expected: 255, .Leftover: ""},
766 {.Str: "256", .Expected: 256, .Leftover: ""},
767 {.Str: "65535", .Expected: 65535, .Leftover: ""},
768 {.Str: "65536", .Expected: 65536, .Leftover: ""},
769 {.Str: "4294967295", .Expected: 4294967295ULL, .Leftover: ""},
770 {.Str: "4294967296", .Expected: 4294967296ULL, .Leftover: ""},
771 {.Str: "255A376", .Expected: 255, .Leftover: "A376"},
772 {.Str: "18446744073709551615", .Expected: 18446744073709551615ULL, .Leftover: ""},
773 {.Str: "18446744073709551615ABC", .Expected: 18446744073709551615ULL, .Leftover: "ABC"},
774 {.Str: "042", .Expected: 34, .Leftover: ""},
775 {.Str: "0x42", .Expected: 66, .Leftover: ""},
776 {.Str: "0x42-0x34", .Expected: 66, .Leftover: "-0x34"},
777 {.Str: "0b101010", .Expected: 42, .Leftover: ""},
778 {.Str: "0429F", .Expected: 042, .Leftover: "9F"}, // Auto-sensed octal radix, invalid digit
779 {.Str: "0x42G12", .Expected: 0x42, .Leftover: "G12"}, // Auto-sensed hex radix, invalid digit
780 {.Str: "0b10101020101", .Expected: 42, .Leftover: "20101"}}; // Auto-sensed binary radix, invalid digit.
781
782struct ConsumeSignedPair {
783 const char *Str;
784 int64_t Expected;
785 const char *Leftover;
786} ConsumeSigned[] = {
787 {.Str: "0", .Expected: 0, .Leftover: ""},
788 {.Str: "-0", .Expected: 0, .Leftover: ""},
789 {.Str: "0-1", .Expected: 0, .Leftover: "-1"},
790 {.Str: "-0-1", .Expected: 0, .Leftover: "-1"},
791 {.Str: "127", .Expected: 127, .Leftover: ""},
792 {.Str: "128", .Expected: 128, .Leftover: ""},
793 {.Str: "127-1", .Expected: 127, .Leftover: "-1"},
794 {.Str: "128-1", .Expected: 128, .Leftover: "-1"},
795 {.Str: "-128", .Expected: -128, .Leftover: ""},
796 {.Str: "-129", .Expected: -129, .Leftover: ""},
797 {.Str: "-128-1", .Expected: -128, .Leftover: "-1"},
798 {.Str: "-129-1", .Expected: -129, .Leftover: "-1"},
799 {.Str: "32767", .Expected: 32767, .Leftover: ""},
800 {.Str: "32768", .Expected: 32768, .Leftover: ""},
801 {.Str: "32767-1", .Expected: 32767, .Leftover: "-1"},
802 {.Str: "32768-1", .Expected: 32768, .Leftover: "-1"},
803 {.Str: "-32768", .Expected: -32768, .Leftover: ""},
804 {.Str: "-32769", .Expected: -32769, .Leftover: ""},
805 {.Str: "-32768-1", .Expected: -32768, .Leftover: "-1"},
806 {.Str: "-32769-1", .Expected: -32769, .Leftover: "-1"},
807 {.Str: "2147483647", .Expected: 2147483647LL, .Leftover: ""},
808 {.Str: "2147483648", .Expected: 2147483648LL, .Leftover: ""},
809 {.Str: "2147483647-1", .Expected: 2147483647LL, .Leftover: "-1"},
810 {.Str: "2147483648-1", .Expected: 2147483648LL, .Leftover: "-1"},
811 {.Str: "-2147483648", .Expected: -2147483648LL, .Leftover: ""},
812 {.Str: "-2147483649", .Expected: -2147483649LL, .Leftover: ""},
813 {.Str: "-2147483648-1", .Expected: -2147483648LL, .Leftover: "-1"},
814 {.Str: "-2147483649-1", .Expected: -2147483649LL, .Leftover: "-1"},
815 {.Str: "-9223372036854775808", .Expected: -(9223372036854775807LL) - 1, .Leftover: ""},
816 {.Str: "-9223372036854775808-1", .Expected: -(9223372036854775807LL) - 1, .Leftover: "-1"},
817 {.Str: "042", .Expected: 34, .Leftover: ""},
818 {.Str: "042-1", .Expected: 34, .Leftover: "-1"},
819 {.Str: "0x42", .Expected: 66, .Leftover: ""},
820 {.Str: "0x42-1", .Expected: 66, .Leftover: "-1"},
821 {.Str: "0b101010", .Expected: 42, .Leftover: ""},
822 {.Str: "0b101010-1", .Expected: 42, .Leftover: "-1"},
823 {.Str: "-042", .Expected: -34, .Leftover: ""},
824 {.Str: "-042-1", .Expected: -34, .Leftover: "-1"},
825 {.Str: "-0x42", .Expected: -66, .Leftover: ""},
826 {.Str: "-0x42-1", .Expected: -66, .Leftover: "-1"},
827 {.Str: "-0b101010", .Expected: -42, .Leftover: ""},
828 {.Str: "-0b101010-1", .Expected: -42, .Leftover: "-1"}};
829
830TEST(StringRefTest, consumeIntegerUnsigned) {
831 uint8_t U8;
832 uint16_t U16;
833 uint32_t U32;
834 uint64_t U64;
835 APInt U;
836
837 for (size_t i = 0; i < std::size(ConsumeUnsigned); ++i) {
838 StringRef Str = ConsumeUnsigned[i].Str;
839 bool U8Success = Str.consumeInteger(Radix: 0, Result&: U8);
840 if (static_cast<uint8_t>(ConsumeUnsigned[i].Expected) ==
841 ConsumeUnsigned[i].Expected) {
842 ASSERT_FALSE(U8Success);
843 EXPECT_EQ(U8, ConsumeUnsigned[i].Expected);
844 EXPECT_EQ(Str, ConsumeUnsigned[i].Leftover);
845 } else {
846 ASSERT_TRUE(U8Success);
847 }
848
849 Str = ConsumeUnsigned[i].Str;
850 bool U16Success = Str.consumeInteger(Radix: 0, Result&: U16);
851 if (static_cast<uint16_t>(ConsumeUnsigned[i].Expected) ==
852 ConsumeUnsigned[i].Expected) {
853 ASSERT_FALSE(U16Success);
854 EXPECT_EQ(U16, ConsumeUnsigned[i].Expected);
855 EXPECT_EQ(Str, ConsumeUnsigned[i].Leftover);
856 } else {
857 ASSERT_TRUE(U16Success);
858 }
859
860 Str = ConsumeUnsigned[i].Str;
861 bool U32Success = Str.consumeInteger(Radix: 0, Result&: U32);
862 if (static_cast<uint32_t>(ConsumeUnsigned[i].Expected) ==
863 ConsumeUnsigned[i].Expected) {
864 ASSERT_FALSE(U32Success);
865 EXPECT_EQ(U32, ConsumeUnsigned[i].Expected);
866 EXPECT_EQ(Str, ConsumeUnsigned[i].Leftover);
867 } else {
868 ASSERT_TRUE(U32Success);
869 }
870
871 Str = ConsumeUnsigned[i].Str;
872 bool U64Success = Str.consumeInteger(Radix: 0, Result&: U64);
873 ASSERT_FALSE(U64Success);
874 EXPECT_EQ(U64, ConsumeUnsigned[i].Expected);
875 EXPECT_EQ(Str, ConsumeUnsigned[i].Leftover);
876
877 Str = ConsumeUnsigned[i].Str;
878 U64Success = Str.consumeInteger(Radix: 0, Result&: U);
879 ASSERT_FALSE(U64Success);
880 EXPECT_EQ(U.getZExtValue(), ConsumeUnsigned[i].Expected);
881 EXPECT_EQ(Str, ConsumeUnsigned[i].Leftover);
882 }
883}
884
885TEST(StringRefTest, consumeIntegerSigned) {
886 int8_t S8;
887 int16_t S16;
888 int32_t S32;
889 int64_t S64;
890
891 for (size_t i = 0; i < std::size(ConsumeSigned); ++i) {
892 StringRef Str = ConsumeSigned[i].Str;
893 bool S8Success = Str.consumeInteger(Radix: 0, Result&: S8);
894 if (static_cast<int8_t>(ConsumeSigned[i].Expected) ==
895 ConsumeSigned[i].Expected) {
896 ASSERT_FALSE(S8Success);
897 EXPECT_EQ(S8, ConsumeSigned[i].Expected);
898 EXPECT_EQ(Str, ConsumeSigned[i].Leftover);
899 } else {
900 ASSERT_TRUE(S8Success);
901 }
902
903 Str = ConsumeSigned[i].Str;
904 bool S16Success = Str.consumeInteger(Radix: 0, Result&: S16);
905 if (static_cast<int16_t>(ConsumeSigned[i].Expected) ==
906 ConsumeSigned[i].Expected) {
907 ASSERT_FALSE(S16Success);
908 EXPECT_EQ(S16, ConsumeSigned[i].Expected);
909 EXPECT_EQ(Str, ConsumeSigned[i].Leftover);
910 } else {
911 ASSERT_TRUE(S16Success);
912 }
913
914 Str = ConsumeSigned[i].Str;
915 bool S32Success = Str.consumeInteger(Radix: 0, Result&: S32);
916 if (static_cast<int32_t>(ConsumeSigned[i].Expected) ==
917 ConsumeSigned[i].Expected) {
918 ASSERT_FALSE(S32Success);
919 EXPECT_EQ(S32, ConsumeSigned[i].Expected);
920 EXPECT_EQ(Str, ConsumeSigned[i].Leftover);
921 } else {
922 ASSERT_TRUE(S32Success);
923 }
924
925 Str = ConsumeSigned[i].Str;
926 bool S64Success = Str.consumeInteger(Radix: 0, Result&: S64);
927 ASSERT_FALSE(S64Success);
928 EXPECT_EQ(S64, ConsumeSigned[i].Expected);
929 EXPECT_EQ(Str, ConsumeSigned[i].Leftover);
930 }
931}
932
933struct GetDoubleStrings {
934 const char *Str;
935 bool AllowInexact;
936 bool ShouldFail;
937 double D;
938} DoubleStrings[] = {{.Str: "0", .AllowInexact: false, .ShouldFail: false, .D: 0.0},
939 {.Str: "0.0", .AllowInexact: false, .ShouldFail: false, .D: 0.0},
940 {.Str: "-0.0", .AllowInexact: false, .ShouldFail: false, .D: -0.0},
941 {.Str: "123.45", .AllowInexact: false, .ShouldFail: true, .D: 123.45},
942 {.Str: "123.45", .AllowInexact: true, .ShouldFail: false, .D: 123.45},
943 {.Str: "1.8e308", .AllowInexact: true, .ShouldFail: false, .D: std::numeric_limits<double>::infinity()},
944 {.Str: "1.8e308", .AllowInexact: false, .ShouldFail: true, .D: std::numeric_limits<double>::infinity()},
945 {.Str: "0x0.0000000000001P-1023", .AllowInexact: false, .ShouldFail: true, .D: 0.0},
946 {.Str: "0x0.0000000000001P-1023", .AllowInexact: true, .ShouldFail: false, .D: 0.0},
947 };
948
949TEST(StringRefTest, getAsDouble) {
950 for (const auto &Entry : DoubleStrings) {
951 double Result;
952 StringRef S(Entry.Str);
953 EXPECT_EQ(Entry.ShouldFail, S.getAsDouble(Result, Entry.AllowInexact));
954 if (!Entry.ShouldFail) {
955 EXPECT_EQ(Result, Entry.D);
956 }
957 }
958}
959
960static const char *join_input[] = { "a", "b", "c" };
961static const char join_result1[] = "a";
962static const char join_result2[] = "a:b:c";
963static const char join_result3[] = "a::b::c";
964
965TEST(StringRefTest, joinStrings) {
966 std::vector<StringRef> v1;
967 std::vector<std::string> v2;
968 for (size_t i = 0; i < std::size(join_input); ++i) {
969 v1.push_back(x: join_input[i]);
970 v2.push_back(x: join_input[i]);
971 }
972
973 bool v1_join1 = join(Begin: v1.begin(), End: v1.begin() + 1, Separator: ":") == join_result1;
974 EXPECT_TRUE(v1_join1);
975 bool v1_join2 = join(Begin: v1.begin(), End: v1.end(), Separator: ":") == join_result2;
976 EXPECT_TRUE(v1_join2);
977 bool v1_join3 = join(Begin: v1.begin(), End: v1.end(), Separator: "::") == join_result3;
978 EXPECT_TRUE(v1_join3);
979
980 bool v2_join1 = join(Begin: v2.begin(), End: v2.begin() + 1, Separator: ":") == join_result1;
981 EXPECT_TRUE(v2_join1);
982 bool v2_join2 = join(Begin: v2.begin(), End: v2.end(), Separator: ":") == join_result2;
983 EXPECT_TRUE(v2_join2);
984 bool v2_join3 = join(Begin: v2.begin(), End: v2.end(), Separator: "::") == join_result3;
985 EXPECT_TRUE(v2_join3);
986 v2_join3 = join(R&: v2, Separator: "::") == join_result3;
987 EXPECT_TRUE(v2_join3);
988}
989
990
991TEST(StringRefTest, AllocatorCopy) {
992 BumpPtrAllocator Alloc;
993 // First test empty strings. We don't want these to allocate anything on the
994 // allocator.
995 StringRef StrEmpty = "";
996 StringRef StrEmptyc = StrEmpty.copy(A&: Alloc);
997 EXPECT_TRUE(StrEmpty.equals(StrEmptyc));
998 EXPECT_EQ(StrEmptyc.data(), nullptr);
999 EXPECT_EQ(StrEmptyc.size(), 0u);
1000 EXPECT_EQ(Alloc.getTotalMemory(), 0u);
1001
1002 StringRef Str1 = "hello";
1003 StringRef Str2 = "bye";
1004 StringRef Str1c = Str1.copy(A&: Alloc);
1005 StringRef Str2c = Str2.copy(A&: Alloc);
1006 EXPECT_TRUE(Str1.equals(Str1c));
1007 EXPECT_NE(Str1.data(), Str1c.data());
1008 EXPECT_TRUE(Str2.equals(Str2c));
1009 EXPECT_NE(Str2.data(), Str2c.data());
1010}
1011
1012TEST(StringRefTest, Drop) {
1013 StringRef Test("StringRefTest::Drop");
1014
1015 StringRef Dropped = Test.drop_front(N: 5);
1016 EXPECT_EQ(Dropped, "gRefTest::Drop");
1017
1018 Dropped = Test.drop_back(N: 5);
1019 EXPECT_EQ(Dropped, "StringRefTest:");
1020
1021 Dropped = Test.drop_front(N: 0);
1022 EXPECT_EQ(Dropped, Test);
1023
1024 Dropped = Test.drop_back(N: 0);
1025 EXPECT_EQ(Dropped, Test);
1026
1027 Dropped = Test.drop_front(N: Test.size());
1028 EXPECT_TRUE(Dropped.empty());
1029
1030 Dropped = Test.drop_back(N: Test.size());
1031 EXPECT_TRUE(Dropped.empty());
1032}
1033
1034TEST(StringRefTest, Take) {
1035 StringRef Test("StringRefTest::Take");
1036
1037 StringRef Taken = Test.take_front(N: 5);
1038 EXPECT_EQ(Taken, "Strin");
1039
1040 Taken = Test.take_back(N: 5);
1041 EXPECT_EQ(Taken, ":Take");
1042
1043 Taken = Test.take_front(N: Test.size());
1044 EXPECT_EQ(Taken, Test);
1045
1046 Taken = Test.take_back(N: Test.size());
1047 EXPECT_EQ(Taken, Test);
1048
1049 Taken = Test.take_front(N: 0);
1050 EXPECT_TRUE(Taken.empty());
1051
1052 Taken = Test.take_back(N: 0);
1053 EXPECT_TRUE(Taken.empty());
1054}
1055
1056TEST(StringRefTest, FindIf) {
1057 StringRef Punct("Test.String");
1058 StringRef NoPunct("ABCDEFG");
1059 StringRef Empty;
1060
1061 auto IsPunct = [](char c) { return ::ispunct(c); };
1062 auto IsAlpha = [](char c) { return ::isalpha(c); };
1063 EXPECT_EQ(4U, Punct.find_if(IsPunct));
1064 EXPECT_EQ(StringRef::npos, NoPunct.find_if(IsPunct));
1065 EXPECT_EQ(StringRef::npos, Empty.find_if(IsPunct));
1066
1067 EXPECT_EQ(4U, Punct.find_if_not(IsAlpha));
1068 EXPECT_EQ(StringRef::npos, NoPunct.find_if_not(IsAlpha));
1069 EXPECT_EQ(StringRef::npos, Empty.find_if_not(IsAlpha));
1070}
1071
1072TEST(StringRefTest, TakeWhileUntil) {
1073 StringRef Test("String With 1 Number");
1074
1075 StringRef Taken = Test.take_while(F: [](char c) { return ::isdigit(c); });
1076 EXPECT_EQ("", Taken);
1077
1078 Taken = Test.take_until(F: [](char c) { return ::isdigit(c); });
1079 EXPECT_EQ("String With ", Taken);
1080
1081 Taken = Test.take_while(F: [](char c) { return true; });
1082 EXPECT_EQ(Test, Taken);
1083
1084 Taken = Test.take_until(F: [](char c) { return true; });
1085 EXPECT_EQ("", Taken);
1086
1087 Test = "";
1088 Taken = Test.take_while(F: [](char c) { return true; });
1089 EXPECT_EQ("", Taken);
1090}
1091
1092TEST(StringRefTest, DropWhileUntil) {
1093 StringRef Test("String With 1 Number");
1094
1095 StringRef Taken = Test.drop_while(F: [](char c) { return ::isdigit(c); });
1096 EXPECT_EQ(Test, Taken);
1097
1098 Taken = Test.drop_until(F: [](char c) { return ::isdigit(c); });
1099 EXPECT_EQ("1 Number", Taken);
1100
1101 Taken = Test.drop_while(F: [](char c) { return true; });
1102 EXPECT_EQ("", Taken);
1103
1104 Taken = Test.drop_until(F: [](char c) { return true; });
1105 EXPECT_EQ(Test, Taken);
1106
1107 StringRef EmptyString = "";
1108 Taken = EmptyString.drop_while(F: [](char c) { return true; });
1109 EXPECT_EQ("", Taken);
1110}
1111
1112TEST(StringRefTest, StringLiteral) {
1113 constexpr StringRef StringRefs[] = {"Foo", "Bar"};
1114 EXPECT_EQ(StringRef("Foo"), StringRefs[0]);
1115 EXPECT_EQ(3u, (std::integral_constant<size_t, StringRefs[0].size()>::value));
1116 EXPECT_EQ(false, (std::integral_constant<bool, StringRefs[0].empty()>::value));
1117 EXPECT_EQ(StringRef("Bar"), StringRefs[1]);
1118
1119 constexpr StringLiteral Strings[] = {"Foo", "Bar"};
1120 EXPECT_EQ(StringRef("Foo"), Strings[0]);
1121 EXPECT_EQ(3u, (std::integral_constant<size_t, Strings[0].size()>::value));
1122 EXPECT_EQ(false, (std::integral_constant<bool, Strings[0].empty()>::value));
1123 EXPECT_EQ(StringRef("Bar"), Strings[1]);
1124}
1125
1126// Check gtest prints StringRef as a string instead of a container of chars.
1127// The code is in utils/unittest/googletest/internal/custom/gtest-printers.h
1128TEST(StringRefTest, GTestPrinter) {
1129 EXPECT_EQ(R"("foo")", ::testing::PrintToString(StringRef("foo")));
1130}
1131
1132TEST(StringRefTest, LFLineEnding) {
1133 constexpr StringRef Cases[] = {"\nDoggo\nPupper", "Floofer\n", "Woofer"};
1134 EXPECT_EQ(StringRef("\n"), Cases[0].detectEOL());
1135 EXPECT_EQ(StringRef("\n"), Cases[1].detectEOL());
1136 EXPECT_EQ(StringRef("\n"), Cases[2].detectEOL());
1137}
1138
1139TEST(StringRefTest, CRLineEnding) {
1140 constexpr StringRef Cases[] = {"\rDoggo\rPupper", "Floofer\r", "Woo\rfer\n"};
1141 EXPECT_EQ(StringRef("\r"), Cases[0].detectEOL());
1142 EXPECT_EQ(StringRef("\r"), Cases[1].detectEOL());
1143 EXPECT_EQ(StringRef("\r"), Cases[2].detectEOL());
1144}
1145
1146TEST(StringRefTest, CRLFLineEnding) {
1147 constexpr StringRef Cases[] = {"\r\nDoggo\r\nPupper", "Floofer\r\n",
1148 "Woofer\r\nSubWoofer\n"};
1149 EXPECT_EQ(StringRef("\r\n"), Cases[0].detectEOL());
1150 EXPECT_EQ(StringRef("\r\n"), Cases[1].detectEOL());
1151 EXPECT_EQ(StringRef("\r\n"), Cases[2].detectEOL());
1152}
1153
1154TEST(StringRefTest, LFCRLineEnding) {
1155 constexpr StringRef Cases[] = {"\n\rDoggo\n\rPupper", "Floofer\n\r",
1156 "Woofer\n\rSubWoofer\n"};
1157 EXPECT_EQ(StringRef("\n\r"), Cases[0].detectEOL());
1158 EXPECT_EQ(StringRef("\n\r"), Cases[1].detectEOL());
1159 EXPECT_EQ(StringRef("\n\r"), Cases[2].detectEOL());
1160}
1161
1162static_assert(std::is_trivially_copyable_v<StringRef>, "trivially copyable");
1163
1164} // end anonymous namespace
1165

source code of llvm/unittests/ADT/StringRefTest.cpp