diff options
-rw-r--r-- | include/llvm/ADT/StringRef.h | 6 | ||||
-rw-r--r-- | lib/Support/StringRef.cpp | 21 | ||||
-rw-r--r-- | unittests/ADT/StringRefTest.cpp | 13 |
3 files changed, 40 insertions, 0 deletions
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index 1766d2b9f2..adff42fe2d 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -125,6 +125,12 @@ namespace llvm { return Length < RHS.Length ? -1 : 1; } + /// compare - Compare two strings; the result is -1, 0, or 1 if this string + /// is lexicographically less than, equal to, or greater than the \arg RHS. + /// This is different than compare with no size specified as it only + /// compares at most the first n bytes. + int compare(StringRef RHS, size_t n) const; + /// compare_lower - Compare two strings, ignoring case. int compare_lower(StringRef RHS) const; diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp index 8c3fc094cd..066e7743ae 100644 --- a/lib/Support/StringRef.cpp +++ b/lib/Support/StringRef.cpp @@ -29,6 +29,27 @@ static bool ascii_isdigit(char x) { return x >= '0' && x <= '9'; } +/// compare - Compare two strings; the result is -1, 0, or 1 if this string +/// is lexicographically less than, equal to, or greater than the \arg RHS. +/// This is different than compare with no size specified as it only +/// compares at most the first n bytes. +int StringRef::compare(StringRef RHS, size_t n) const { + // Check the prefix for a mismatch. + size_t maxToCmp = min(Length, RHS.Length); + maxToCmp = min(maxToCmp, n); + if (int Res = memcmp(Data, RHS.Data, maxToCmp)) + return Res < 0 ? -1 : 1; + + // Otherwise the prefixes match, so we only need to check the lengths. + // Be mindful that if the n is less than or equal to the length of either + // string, that is the same as the strings matching because in that case + // we only care about the prefix. + if (((n <= Length) && (n <= RHS.Length)) || + (Length == RHS.Length)) + return 0; + return Length < RHS.Length ? -1 : 1; +} + /// compare_lower - Compare strings, ignoring case. int StringRef::compare_lower(StringRef RHS) const { for (size_t I = 0, E = min(Length, RHS.Length); I != E; ++I) { diff --git a/unittests/ADT/StringRefTest.cpp b/unittests/ADT/StringRefTest.cpp index 5731e4abaf..633fcc81fd 100644 --- a/unittests/ADT/StringRefTest.cpp +++ b/unittests/ADT/StringRefTest.cpp @@ -55,6 +55,19 @@ TEST(StringRefTest, StringOps) { EXPECT_EQ( 1, StringRef("aab").compare("aa")); EXPECT_EQ( 1, StringRef("\xFF").compare("\1")); + EXPECT_EQ(-1, StringRef("aab").compare("aad", 3)); + EXPECT_EQ( 0, StringRef("aab").compare("aab", 3)); + EXPECT_EQ( 1, StringRef("aab").compare("aaa", 3)); + EXPECT_EQ(-1, StringRef("aab").compare("aabb", 4)); + EXPECT_EQ( 1, StringRef("aab").compare("aa", 3)); + EXPECT_EQ( 1, StringRef("\xFF").compare("\1", 3)); + EXPECT_EQ( 0, StringRef("aab").compare("aad", 2)); + EXPECT_EQ( 0, StringRef("aab").compare("aab", 2)); + EXPECT_EQ( 0, StringRef("aab").compare("aab", 4)); + EXPECT_EQ( 0, StringRef("aab").compare("aaa", 2)); + EXPECT_EQ( 0, StringRef("aab").compare("aabb", 3)); + EXPECT_EQ( 0, StringRef("aab").compare("aa", 2)); + EXPECT_EQ(-1, StringRef("AaB").compare_lower("aAd")); EXPECT_EQ( 0, StringRef("AaB").compare_lower("aab")); EXPECT_EQ( 1, StringRef("AaB").compare_lower("AAA")); |