diff --git a/libc/src/__support/CPP/StringView.h b/libc/src/__support/CPP/StringView.h --- a/libc/src/__support/CPP/StringView.h +++ b/libc/src/__support/CPP/StringView.h @@ -137,6 +137,11 @@ compareMemory(Data, Prefix.Data, Prefix.Len) == 0; } + // Check if this string starts with the given Prefix. + bool starts_with(const char Prefix) const { + return Len >= 1 && Data[0] == Prefix; + } + // Check if this string ends with the given Suffix. bool ends_with(StringView Suffix) const { return Len >= Suffix.Len && @@ -157,6 +162,20 @@ return StringView(Data + Start, min(N, Len - Start)); } + // Search for the first character matching the character + // + // Returns The index of the first character satisfying the character starting + // from From, or npos if not found. + size_t find_first_of(const char c, size_t From = 0) const noexcept { + StringView S = drop_front(From); + while (!S.empty()) { + if (S.front() == c) + return size() - S.size(); + S = S.drop_front(); + } + return npos; + } + // Search for the first character satisfying the predicate Function // // Returns The index of the first character satisfying Function starting from diff --git a/libc/test/src/__support/CPP/stringview_test.cpp b/libc/test/src/__support/CPP/stringview_test.cpp --- a/libc/test/src/__support/CPP/stringview_test.cpp +++ b/libc/test/src/__support/CPP/stringview_test.cpp @@ -49,11 +49,13 @@ TEST(LlvmLibcStringViewTest, startsWith) { StringView v("abc"); + ASSERT_TRUE(v.starts_with('a')); ASSERT_TRUE(v.starts_with(StringView("a"))); ASSERT_TRUE(v.starts_with(StringView("ab"))); ASSERT_TRUE(v.starts_with(StringView("abc"))); ASSERT_TRUE(v.starts_with(StringView())); ASSERT_TRUE(v.starts_with(StringView(""))); + ASSERT_FALSE(v.starts_with('1')); ASSERT_FALSE(v.starts_with(StringView("123"))); ASSERT_FALSE(v.starts_with(StringView("abd"))); ASSERT_FALSE(v.starts_with(StringView("aaa"))); @@ -176,3 +178,17 @@ ASSERT_TRUE(Tmp.consume_back("bc")); ASSERT_TRUE(Tmp.equals("a")); } + +TEST(LlvmLibcStringViewTest, FindFirstOf) { + StringView Tmp("abca"); + ASSERT_TRUE(Tmp.find_first_of('a') == 0); + ASSERT_TRUE(Tmp.find_first_of('d') == StringView::npos); + ASSERT_TRUE(Tmp.find_first_of('b') == 1); + ASSERT_TRUE(Tmp.find_first_of('a', 0) == 0); + ASSERT_TRUE(Tmp.find_first_of('b', 1) == 1); + ASSERT_TRUE(Tmp.find_first_of('a', 1) == 3); + ASSERT_TRUE(Tmp.find_first_of('a', 42) == StringView::npos); + ASSERT_FALSE(Tmp.find_first_of('c') == 1); + ASSERT_FALSE(Tmp.find_first_of('c', 0) == 1); + ASSERT_FALSE(Tmp.find_first_of('c', 1) == 1); +}