11#include "gtest/gtest.h"
17static bool equals(
const kmp_str_ref &
s,
const char *expected) {
18 size_t expected_len = strlen(expected);
19 if (
s.length() != expected_len)
21 return memcmp(
s.begin(), expected, expected_len) == 0;
28TEST(kmp_str_ref_test, ConstructFromCString) {
30 EXPECT_EQ(
s.length(), 5u);
31 EXPECT_TRUE(equals(
s,
"Hello"));
34TEST(kmp_str_ref_test, ConstructFromCStringWithLength) {
36 EXPECT_EQ(
s.length(), 5u);
37 EXPECT_TRUE(equals(
s,
"Hello"));
40TEST(kmp_str_ref_test, ConstructEmpty) {
42 EXPECT_EQ(
s.length(), 0u);
43 EXPECT_TRUE(
s.empty());
46TEST(kmp_str_ref_test, ConstructFromNullptr) {
47 const char *null_str =
nullptr;
49 EXPECT_EQ(
s.length(), 0u);
50 EXPECT_TRUE(
s.empty());
53TEST(kmp_str_ref_test, ConstructFromNullptrWithLength) {
55 EXPECT_EQ(
s.length(), 0u);
56 EXPECT_TRUE(
s.empty());
59TEST(kmp_str_ref_test, NullptrOperations) {
60 const char *null_str =
nullptr;
65 EXPECT_EQ(
s.begin(),
s.end());
66 EXPECT_EQ(
s.end() -
s.begin(), 0);
71 EXPECT_TRUE(
result.empty());
74 EXPECT_TRUE(
s.consume_front(
""));
75 EXPECT_TRUE(
s.empty());
78 EXPECT_FALSE(
s.consume_front(
"x"));
81 EXPECT_EQ(
s.count_while([](
char) { return true; }), 0u);
84TEST(kmp_str_ref_test, Length) {
91TEST(kmp_str_ref_test, Size) {
102TEST(kmp_str_ref_test, EmptyString) {
104 EXPECT_TRUE(
s.empty());
107TEST(kmp_str_ref_test, NonEmptyString) {
109 EXPECT_FALSE(
s.empty());
112TEST(kmp_str_ref_test, EmptyAfterConsumeFront) {
114 EXPECT_FALSE(
s.empty());
116 s.consume_front(
"hello");
118 EXPECT_TRUE(
s.empty());
119 EXPECT_EQ(
s.length(), 0u);
122TEST(kmp_str_ref_test, EmptyAfterDropFront) {
124 EXPECT_FALSE(
s.empty());
128 EXPECT_TRUE(
s.empty());
129 EXPECT_EQ(
s.length(), 0u);
132TEST(kmp_str_ref_test, EmptyAfterDropWhile) {
134 EXPECT_FALSE(
s.empty());
136 s.drop_while([](
char c) {
137 return static_cast<bool>(isdigit(
static_cast<unsigned char>(c)));
140 EXPECT_TRUE(
s.empty());
141 EXPECT_EQ(
s.length(), 0u);
144TEST(kmp_str_ref_test, EmptyAfterConsumeInteger) {
147 EXPECT_FALSE(
s.empty());
151 EXPECT_TRUE(
s.empty());
152 EXPECT_EQ(
s.length(), 0u);
153 EXPECT_EQ(
value, 42);
156TEST(kmp_str_ref_test, NotEmptyAfterPartialConsume) {
162 EXPECT_FALSE(
s.empty());
163 EXPECT_EQ(
s.length(), 3u);
164 EXPECT_TRUE(equals(
s,
"abc"));
171TEST(kmp_str_ref_test, BeginEnd) {
173 EXPECT_EQ(
s.end() -
s.begin(), 5);
174 EXPECT_EQ(*
s.begin(),
'H');
177TEST(kmp_str_ref_test, RangeBasedFor) {
190TEST(kmp_str_ref_test, Assignment) {
196 EXPECT_TRUE(equals(s1,
"Second"));
197 EXPECT_EQ(s1.length(), 6u);
200TEST(kmp_str_ref_test, SelfAssignment) {
204 EXPECT_TRUE(equals(
s,
"Test"));
205 EXPECT_EQ(
s.length(), 4u);
212TEST(kmp_str_ref_test, ConsumeFrontSuccess) {
215 EXPECT_TRUE(
s.consume_front(
"Hello"));
216 EXPECT_EQ(
s.length(), 6u);
217 EXPECT_TRUE(equals(
s,
" World"));
220TEST(kmp_str_ref_test, ConsumeFrontFailure) {
223 EXPECT_FALSE(
s.consume_front(
"World"));
224 EXPECT_EQ(
s.length(), 11u);
225 EXPECT_TRUE(equals(
s,
"Hello World"));
228TEST(kmp_str_ref_test, ConsumeFrontEmpty) {
231 EXPECT_TRUE(
s.consume_front(
""));
232 EXPECT_EQ(
s.length(), 5u);
235TEST(kmp_str_ref_test, ConsumeFrontTooLong) {
238 EXPECT_FALSE(
s.consume_front(
"Hello"));
239 EXPECT_EQ(
s.length(), 2u);
242TEST(kmp_str_ref_test, ConsumeFrontExact) {
245 EXPECT_TRUE(
s.consume_front(
"Hello"));
246 EXPECT_EQ(
s.length(), 0u);
249TEST(kmp_str_ref_test, ConsumeFrontMultiple) {
252 EXPECT_TRUE(
s.consume_front(
"prefix"));
253 EXPECT_TRUE(
s.consume_front(
":"));
254 EXPECT_TRUE(
s.consume_front(
"middle"));
255 EXPECT_TRUE(
s.consume_front(
":"));
256 EXPECT_TRUE(equals(
s,
"suffix"));
263TEST(kmp_str_ref_test, ConsumeIntegerSimple) {
267 EXPECT_TRUE(
s.consume_integer(
value));
268 EXPECT_EQ(
value, 42);
269 EXPECT_EQ(
s.length(), 0u);
272TEST(kmp_str_ref_test, ConsumeIntegerWithTrailing) {
276 EXPECT_TRUE(
s.consume_integer(
value));
277 EXPECT_EQ(
value, 123);
278 EXPECT_TRUE(equals(
s,
"abc"));
281TEST(kmp_str_ref_test, ConsumeIntegerZero) {
286 EXPECT_TRUE(
s.consume_integer(
value));
288 EXPECT_EQ(
s.length(), 0u);
291TEST(kmp_str_ref_test, ConsumeIntegerZeroNotAllowed) {
295 EXPECT_FALSE(
s.consume_integer(
value,
false));
297 EXPECT_TRUE(equals(
s,
"0rest"));
300TEST(kmp_str_ref_test, ConsumeIntegerNoDigits) {
305 EXPECT_FALSE(
s.consume_integer(
value));
307 EXPECT_TRUE(equals(
s,
"abc"));
310TEST(kmp_str_ref_test, ConsumeIntegerEmpty) {
315 EXPECT_FALSE(
s.consume_integer(
value));
318TEST(kmp_str_ref_test, ConsumeIntegerLeadingZero) {
322 EXPECT_TRUE(
s.consume_integer(
value));
324 EXPECT_EQ(
s.length(), 0u);
327TEST(kmp_str_ref_test, ConsumeIntegerNegativeAllowed) {
331 EXPECT_TRUE(
s.consume_integer(
value,
true,
true));
332 EXPECT_EQ(
value, -42);
333 EXPECT_TRUE(equals(
s,
"rest"));
336TEST(kmp_str_ref_test, ConsumeIntegerNegativeNotAllowed) {
340 EXPECT_FALSE(
s.consume_integer(
value,
true,
false));
342 EXPECT_TRUE(equals(
s,
"-42"));
345TEST(kmp_str_ref_test, ConsumeIntegerMultipleDigits) {
349 EXPECT_TRUE(
s.consume_integer(
value));
350 EXPECT_EQ(
value, 1234567890);
357TEST(kmp_str_ref_test, Copy) {
359 char *copied =
s.copy();
361 EXPECT_NE(copied,
nullptr);
362 EXPECT_STREQ(copied,
"Hello");
363 EXPECT_NE(copied,
s.begin());
368TEST(kmp_str_ref_test, CopyEmpty) {
370 char *copied =
s.copy();
372 EXPECT_NE(copied,
nullptr);
373 EXPECT_STREQ(copied,
"");
378TEST(kmp_str_ref_test, CopySubstring) {
381 kmp_str_ref sub = full.take_while([](
char c) {
return c !=
')'; });
383 EXPECT_EQ(
sub.length(), 8u);
385 char *copied =
sub.copy();
387 EXPECT_NE(copied,
nullptr);
388 EXPECT_STREQ(copied,
"device-0");
389 EXPECT_EQ(strlen(copied), 8u);
398TEST(kmp_str_ref_test, DropFront) {
403 EXPECT_EQ(
s.length(), 5u);
404 EXPECT_TRUE(equals(
s,
"World"));
407TEST(kmp_str_ref_test, DropFrontZero) {
412 EXPECT_EQ(
s.length(), 5u);
413 EXPECT_TRUE(equals(
s,
"Hello"));
416TEST(kmp_str_ref_test, DropFrontAll) {
421 EXPECT_EQ(
s.length(), 0u);
424TEST(kmp_str_ref_test, DropFrontMoreThanLength) {
429 EXPECT_EQ(
s.length(), 0u);
436TEST(kmp_str_ref_test, DropWhileDigits) {
439 s.drop_while([](
char c) {
440 return static_cast<bool>(isdigit(
static_cast<unsigned char>(c)));
443 EXPECT_TRUE(equals(
s,
"abc"));
446TEST(kmp_str_ref_test, DropWhileSpaces) {
449 s.drop_while([](
char c) {
return c ==
' '; });
451 EXPECT_TRUE(equals(
s,
"hello"));
454TEST(kmp_str_ref_test, DropWhileNone) {
457 s.drop_while([](
char c) {
return c ==
' '; });
459 EXPECT_TRUE(equals(
s,
"hello"));
462TEST(kmp_str_ref_test, DropWhileAll) {
465 s.drop_while([](
char c) {
466 return static_cast<bool>(isdigit(
static_cast<unsigned char>(c)));
469 EXPECT_EQ(
s.length(), 0u);
476TEST(kmp_str_ref_test, CountWhileDigits) {
479 size_t n =
s.count_while(
480 [](
char c) {
return isdigit(
static_cast<unsigned char>(c)) != 0; });
485TEST(kmp_str_ref_test, CountWhileAll) {
488 size_t n =
s.count_while(
489 [](
char c) {
return isdigit(
static_cast<unsigned char>(c)) != 0; });
491 EXPECT_EQ(n,
s.length());
494TEST(kmp_str_ref_test, CountWhileNone) {
497 size_t n =
s.count_while(
498 [](
char c) {
return isdigit(
static_cast<unsigned char>(c)) != 0; });
503TEST(kmp_str_ref_test, CountWhileEmpty) {
506 size_t n =
s.count_while([](
char c) {
return c ==
'a'; });
515TEST(kmp_str_ref_test, FindIfDigit) {
518 size_t i =
s.find_if(
519 [](
char c) {
return isdigit(
static_cast<unsigned char>(c)) != 0; });
524TEST(kmp_str_ref_test, FindIfFirstChar) {
527 size_t i =
s.find_if([](
char c) {
return c ==
'h'; });
532TEST(kmp_str_ref_test, FindIfLastChar) {
535 size_t i =
s.find_if([](
char c) {
return c ==
'o'; });
540TEST(kmp_str_ref_test, FindIfNoMatch) {
543 size_t i =
s.find_if(
544 [](
char c) {
return isdigit(
static_cast<unsigned char>(c)) != 0; });
549TEST(kmp_str_ref_test, FindIfEmpty) {
552 size_t i =
s.find_if([](
char c) {
return c ==
'a'; });
561TEST(kmp_str_ref_test, FindIfNotDigit) {
564 size_t i =
s.find_if_not(
565 [](
char c) {
return isdigit(
static_cast<unsigned char>(c)) != 0; });
570TEST(kmp_str_ref_test, FindIfNotAllMatch) {
573 size_t i =
s.find_if_not(
574 [](
char c) {
return isdigit(
static_cast<unsigned char>(c)) != 0; });
579TEST(kmp_str_ref_test, FindIfNotNoneMatch) {
582 size_t i =
s.find_if_not(
583 [](
char c) {
return isdigit(
static_cast<unsigned char>(c)) != 0; });
588TEST(kmp_str_ref_test, FindIfNotEmpty) {
591 size_t i =
s.find_if_not([](
char c) {
return c ==
'a'; });
600TEST(kmp_str_ref_test, SkipSpace) {
605 EXPECT_TRUE(equals(
s,
"hello"));
608TEST(kmp_str_ref_test, SkipSpaceNoSpaces) {
613 EXPECT_TRUE(equals(
s,
"hello"));
616TEST(kmp_str_ref_test, SkipSpaceAllSpaces) {
621 EXPECT_EQ(
s.length(), 0u);
624TEST(kmp_str_ref_test, SkipSpaceOnlyLeading) {
629 EXPECT_TRUE(equals(
s,
"hello world "));
632TEST(kmp_str_ref_test, SkipSpaceWithTabs) {
637 EXPECT_TRUE(equals(
s,
"hello"));
644TEST(kmp_str_ref_test, TakeWhileDigits) {
648 return static_cast<bool>(isdigit(
static_cast<unsigned char>(c)));
651 EXPECT_EQ(digits.
length(), 3u);
652 EXPECT_TRUE(equals(digits,
"123"));
654 EXPECT_EQ(
s.length(), 6u);
657TEST(kmp_str_ref_test, TakeWhileAlpha) {
661 return static_cast<bool>(isalpha(
static_cast<unsigned char>(c)));
664 EXPECT_EQ(alpha.
length(), 5u);
665 EXPECT_TRUE(equals(alpha,
"hello"));
668TEST(kmp_str_ref_test, TakeWhileNone) {
672 return static_cast<bool>(isalpha(
static_cast<unsigned char>(c)));
675 EXPECT_EQ(
result.length(), 0u);
678TEST(kmp_str_ref_test, TakeWhileAll) {
682 return static_cast<bool>(isalpha(
static_cast<unsigned char>(c)));
685 EXPECT_EQ(
result.length(), 5u);
686 EXPECT_TRUE(equals(
result,
"hello"));
693TEST(kmp_str_ref_test, ParseKeyValuePair) {
697 s.drop_front(
key.length());
698 s.consume_front(
"=");
700 EXPECT_EQ(
key.length(), 3u);
701 EXPECT_TRUE(equals(
key,
"key"));
702 EXPECT_TRUE(equals(
s,
"value"));
705TEST(kmp_str_ref_test, ParseCommaSeparated) {
707 int values[3] = {0, 0, 0};
710 while (
s.length() > 0 &&
count < 3) {
711 s.consume_integer(values[
count++]);
712 s.consume_front(
",");
716 EXPECT_EQ(values[0], 1);
717 EXPECT_EQ(values[1], 2);
718 EXPECT_EQ(values[2], 3);
721TEST(kmp_str_ref_test, ParseWithWhitespace) {
725 kmp_str_ref word1 =
s.take_while([](
char c) {
return c !=
' '; });
728 kmp_str_ref word2 =
s.take_while([](
char c) {
return c !=
' '; });
730 EXPECT_EQ(word1.
length(), 5u);
731 EXPECT_TRUE(equals(word1,
"hello"));
732 EXPECT_EQ(word2.
length(), 5u);
733 EXPECT_TRUE(equals(word2,
"world"));
#define TEST(test_suite_name, test_name)
kmp_str_ref is a non-owning string class (similar to llvm::StringRef).
static constexpr size_t npos
size_t length() const
Get the length of the string.
void const char const char int ITT_FORMAT __itt_group_sync s
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t count
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void ITT_FORMAT p const __itt_domain __itt_id __itt_string_handle const wchar_t size_t length
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t size
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key
#define KMP_INTERNAL_FREE(p)