ICU-20921 Adding find and compare to StringPiece
This commit is contained in:
parent
a3078fb8c8
commit
b24538eb05
@ -51,6 +51,47 @@ void StringPiece::set(const char* str) {
|
||||
length_ = 0;
|
||||
}
|
||||
|
||||
int32_t StringPiece::find(StringPiece needle, int32_t offset) {
|
||||
if (length() == 0 && needle.length() == 0) {
|
||||
return 0;
|
||||
}
|
||||
// TODO: Improve to be better than O(N^2)?
|
||||
for (int32_t i = offset; i < length(); i++) {
|
||||
int32_t j = 0;
|
||||
for (; j < needle.length(); i++, j++) {
|
||||
if (data()[i] != needle.data()[j]) {
|
||||
i -= j;
|
||||
goto outer_end;
|
||||
}
|
||||
}
|
||||
return i - j;
|
||||
outer_end: void();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t StringPiece::compare(StringPiece other) {
|
||||
int32_t i = 0;
|
||||
for (; i < length(); i++) {
|
||||
if (i == other.length()) {
|
||||
// this is longer
|
||||
return 1;
|
||||
}
|
||||
char a = data()[i];
|
||||
char b = other.data()[i];
|
||||
if (a < b) {
|
||||
return -1;
|
||||
} else if (a > b) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (i < other.length()) {
|
||||
// other is longer
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_EXPORT UBool U_EXPORT2
|
||||
operator==(const StringPiece& x, const StringPiece& y) {
|
||||
int32_t len = x.size();
|
||||
|
@ -212,6 +212,26 @@ class U_COMMON_API StringPiece : public UMemory {
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef U_HIDE_DRAFT_API
|
||||
/**
|
||||
* Searches the StringPiece for the given search string (needle);
|
||||
* @param needle The string for which to search.
|
||||
* @param offset Where to start searching within this string (haystack).
|
||||
* @return The offset of needle in haystack, or -1 if not found.
|
||||
* @draft ICU 67
|
||||
*/
|
||||
int32_t find(StringPiece needle, int32_t offset);
|
||||
|
||||
/**
|
||||
* Compares this StringPiece with the other StringPiece, with semantics
|
||||
* similar to std::string::compare().
|
||||
* @param other The string to compare to.
|
||||
* @return below zero if this < other; above zero if this > other; 0 if this == other.
|
||||
* @draft ICU 67
|
||||
*/
|
||||
int32_t compare(StringPiece other);
|
||||
#endif // U_HIDE_DRAFT_API
|
||||
|
||||
/**
|
||||
* Maximum integer, used as a default value for substring methods.
|
||||
* @stable ICU 4.2
|
||||
|
@ -243,6 +243,7 @@ void StringTest::runIndexedTest(int32_t index, UBool exec, const char *&name, ch
|
||||
TESTCASE_AUTO(TestSTLCompatibility);
|
||||
TESTCASE_AUTO(TestStringPiece);
|
||||
TESTCASE_AUTO(TestStringPieceComparisons);
|
||||
TESTCASE_AUTO(TestStringPieceFind);
|
||||
TESTCASE_AUTO(TestStringPieceOther);
|
||||
#ifdef U_HAVE_STRING_VIEW
|
||||
TESTCASE_AUTO(TestStringPieceStringView);
|
||||
@ -407,6 +408,35 @@ StringTest::TestStringPieceComparisons() {
|
||||
if(abc==abcd) {
|
||||
errln("abc==abcd");
|
||||
}
|
||||
|
||||
assertTrue("null<abc", null.compare(abc) < 0);
|
||||
assertTrue("abc>null", abc.compare(null) > 0);
|
||||
assertTrue("abc<abcd", abc.compare(abcd) < 0);
|
||||
assertTrue("abcd>abc", abcd.compare(abc) > 0);
|
||||
assertTrue("abc<abx", abc.compare(abx) < 0);
|
||||
assertTrue("abx>abc", abx.compare(abc) > 0);
|
||||
assertTrue("abx>abcd", abx.compare(abcd) > 0);
|
||||
assertTrue("abcd<abx", abcd.compare(abx) < 0);
|
||||
assertTrue("abx==abx", abx.compare(abx) == 0);
|
||||
|
||||
// Behavior should be the same as std::string::compare
|
||||
{
|
||||
std::string null("");
|
||||
std::string abc("abc");
|
||||
std::string abcd("abcdefg", 4);
|
||||
std::string abx("abx");
|
||||
|
||||
assertTrue("std: null<abc", null.compare(abc) < 0);
|
||||
assertTrue("std: abc>null", abc.compare(null) > 0);
|
||||
assertTrue("std: abc<abcd", abc.compare(abcd) < 0);
|
||||
assertTrue("std: abcd>abc", abcd.compare(abc) > 0);
|
||||
assertTrue("std: abc<abx", abc.compare(abx) < 0);
|
||||
assertTrue("std: abx>abc", abx.compare(abc) > 0);
|
||||
assertTrue("std: abx>abcd", abx.compare(abcd) > 0);
|
||||
assertTrue("std: abcd<abx", abcd.compare(abx) < 0);
|
||||
assertTrue("std: abx==abx", abx.compare(abx) == 0);
|
||||
}
|
||||
|
||||
abcd.remove_suffix(1);
|
||||
if(abc!=abcd) {
|
||||
errln("abc!=abcd.remove_suffix(1)");
|
||||
@ -416,6 +446,51 @@ StringTest::TestStringPieceComparisons() {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StringTest::TestStringPieceFind() {
|
||||
struct TestCase {
|
||||
const char* haystack;
|
||||
const char* needle;
|
||||
int32_t expected;
|
||||
} cases[] = {
|
||||
{ "", "", 0 },
|
||||
{ "", "x", -1 },
|
||||
{ "x", "", 0 },
|
||||
{ "x", "x", 0 },
|
||||
{ "xy", "x", 0 },
|
||||
{ "xy", "y", 1 },
|
||||
{ "xy", "xy", 0 },
|
||||
{ "xy", "xyz", -1 },
|
||||
{ "qwerty", "qqw", -1 },
|
||||
{ "qwerty", "qw", 0 },
|
||||
{ "qwerty", "er", 2 },
|
||||
{ "qwerty", "err", -1 },
|
||||
{ "qwerty", "ert", 2 },
|
||||
{ "qwerty", "ty", 4 },
|
||||
{ "qwerty", "tyy", -1 },
|
||||
{ "qwerty", "a", -1 },
|
||||
{ "qwerty", "abc", -1 }
|
||||
};
|
||||
int32_t caseNumber = 0;
|
||||
for (auto& cas : cases) {
|
||||
StringPiece haystack(cas.haystack);
|
||||
StringPiece needle(cas.needle);
|
||||
assertEquals(Int64ToUnicodeString(caseNumber),
|
||||
cas.expected, haystack.find(needle, 0));
|
||||
// Should be same as std::string::find
|
||||
std::string stdhaystack(cas.haystack);
|
||||
std::string stdneedle(cas.needle);
|
||||
assertEquals(Int64ToUnicodeString(caseNumber) + u" (std)",
|
||||
cas.expected, stdhaystack.find(stdneedle, 0));
|
||||
// Test offsets against std::string::find
|
||||
for (int32_t offset = 0; offset < haystack.length(); offset++) {
|
||||
assertEquals(Int64ToUnicodeString(caseNumber) + "u @ " + Int64ToUnicodeString(offset),
|
||||
stdhaystack.find(stdneedle, offset), haystack.find(needle, offset));
|
||||
}
|
||||
caseNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StringTest::TestStringPieceOther() {
|
||||
static constexpr char msg[] = "Kapow!";
|
||||
|
@ -43,6 +43,7 @@ private:
|
||||
void TestLowerOrdinal();
|
||||
void Test_UTF8_COUNT_TRAIL_BYTES();
|
||||
void TestStringPiece();
|
||||
void TestStringPieceFind();
|
||||
void TestStringPieceComparisons();
|
||||
void TestStringPieceOther();
|
||||
#ifdef U_HAVE_STRING_VIEW
|
||||
|
Loading…
Reference in New Issue
Block a user