#include "gtest/gtest.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-namespace {
+namespace llvm {
std::ostream &operator<<(std::ostream &OS, const StringRef &S) {
- OS << S;
+ OS << S.str();
return OS;
}
return OS;
}
+}
+
+namespace {
TEST(StringRefTest, Construction) {
EXPECT_EQ("", StringRef());
EXPECT_EQ("hello", StringRef("hello"));
EXPECT_EQ( 1, StringRef("aab").compare("aaa"));
EXPECT_EQ(-1, StringRef("aab").compare("aabb"));
EXPECT_EQ( 1, StringRef("aab").compare("aa"));
+ EXPECT_EQ( 1, StringRef("\xFF").compare("\1"));
+
+ EXPECT_EQ(-1, StringRef("AaB").compare_lower("aAd"));
+ EXPECT_EQ( 0, StringRef("AaB").compare_lower("aab"));
+ EXPECT_EQ( 1, StringRef("AaB").compare_lower("AAA"));
+ EXPECT_EQ(-1, StringRef("AaB").compare_lower("aaBb"));
+ EXPECT_EQ( 1, StringRef("AaB").compare_lower("aA"));
+ EXPECT_EQ( 1, StringRef("\xFF").compare_lower("\1"));
+
+ EXPECT_EQ(-1, StringRef("aab").compare_numeric("aad"));
+ EXPECT_EQ( 0, StringRef("aab").compare_numeric("aab"));
+ EXPECT_EQ( 1, StringRef("aab").compare_numeric("aaa"));
+ EXPECT_EQ(-1, StringRef("aab").compare_numeric("aabb"));
+ EXPECT_EQ( 1, StringRef("aab").compare_numeric("aa"));
+ EXPECT_EQ(-1, StringRef("1").compare_numeric("10"));
+ EXPECT_EQ( 0, StringRef("10").compare_numeric("10"));
+ EXPECT_EQ( 0, StringRef("10a").compare_numeric("10a"));
+ EXPECT_EQ( 1, StringRef("2").compare_numeric("1"));
+ EXPECT_EQ( 0, StringRef("llvm_v1i64_ty").compare_numeric("llvm_v1i64_ty"));
+ EXPECT_EQ( 1, StringRef("\xFF").compare_numeric("\1"));
+ EXPECT_EQ( 1, StringRef("V16").compare_numeric("V1_q0"));
+ EXPECT_EQ(-1, StringRef("V1_q0").compare_numeric("V16"));
+ EXPECT_EQ(-1, StringRef("V8_q0").compare_numeric("V16"));
+ EXPECT_EQ( 1, StringRef("V16").compare_numeric("V8_q0"));
+ EXPECT_EQ(-1, StringRef("V1_q0").compare_numeric("V8_q0"));
+ EXPECT_EQ( 1, StringRef("V8_q0").compare_numeric("V1_q0"));
}
TEST(StringRefTest, Operators) {
Str.rsplit('o'));
}
-// XFAIL for PR5482, StringRef is miscompiled by Apple gcc.
-#if (!defined(__llvm__) && defined(__APPLE__) && defined(__OPTIMIZE__))
-#define SKIP_SPLIT2
-#endif
-#ifndef SKIP_SPLIT2
TEST(StringRefTest, Split2) {
SmallVector<StringRef, 5> parts;
SmallVector<StringRef, 5> expected;
StringRef("a,,b,c").split(parts, ",", 3, false);
EXPECT_TRUE(parts == expected);
}
-#endif
TEST(StringRefTest, StartsWith) {
StringRef Str("hello");
EXPECT_FALSE(Str.startswith("hi"));
}
+TEST(StringRefTest, EndsWith) {
+ StringRef Str("hello");
+ EXPECT_TRUE(Str.endswith("lo"));
+ EXPECT_FALSE(Str.endswith("helloworld"));
+ EXPECT_FALSE(Str.endswith("worldhello"));
+ EXPECT_FALSE(Str.endswith("so"));
+}
+
TEST(StringRefTest, Find) {
StringRef Str("hello");
EXPECT_EQ(2U, Str.find('l'));
EXPECT_EQ(StringRef::npos, Str.find("zz"));
EXPECT_EQ(2U, Str.find("ll", 2));
EXPECT_EQ(StringRef::npos, Str.find("ll", 3));
+ EXPECT_EQ(0U, Str.find(""));
+ StringRef LongStr("hellx xello hell ello world foo bar hello");
+ EXPECT_EQ(36U, LongStr.find("hello"));
+ EXPECT_EQ(28U, LongStr.find("foo"));
+ EXPECT_EQ(12U, LongStr.find("hell", 2));
+ EXPECT_EQ(0U, LongStr.find(""));
EXPECT_EQ(3U, Str.rfind('l'));
EXPECT_EQ(StringRef::npos, Str.rfind('z'));
EXPECT_EQ(0U, Str.count("zz"));
}
+TEST(StringRefTest, EditDistance) {
+ StringRef Str("hello");
+ EXPECT_EQ(2U, Str.edit_distance("hill"));
+}
+
TEST(StringRefTest, Misc) {
std::string Storage;
raw_string_ostream OS(Storage);
EXPECT_EQ("hello", OS.str());
}
+TEST(StringRefTest, Hashing) {
+ EXPECT_EQ(hash_value(std::string()), hash_value(StringRef()));
+ EXPECT_EQ(hash_value(std::string()), hash_value(StringRef("")));
+ std::string S = "hello world";
+ hash_code H = hash_value(S);
+ EXPECT_EQ(H, hash_value(StringRef("hello world")));
+ EXPECT_EQ(H, hash_value(StringRef(S)));
+ EXPECT_NE(H, hash_value(StringRef("hello worl")));
+ EXPECT_EQ(hash_value(std::string("hello worl")),
+ hash_value(StringRef("hello worl")));
+ EXPECT_NE(H, hash_value(StringRef("hello world ")));
+ EXPECT_EQ(hash_value(std::string("hello world ")),
+ hash_value(StringRef("hello world ")));
+ EXPECT_EQ(H, hash_value(StringRef("hello world\0")));
+ EXPECT_NE(hash_value(std::string("ello worl")),
+ hash_value(StringRef("hello world").slice(1, -1)));
+}
+
+struct UnsignedPair {
+ const char *Str;
+ uint64_t Expected;
+} Unsigned[] =
+ { {"0", 0}
+ , {"255", 255}
+ , {"256", 256}
+ , {"65535", 65535}
+ , {"65536", 65536}
+ , {"4294967295", 4294967295ULL}
+ , {"4294967296", 4294967296ULL}
+ , {"18446744073709551615", 18446744073709551615ULL}
+ , {"042", 34}
+ , {"0x42", 66}
+ , {"0b101010", 42}
+ };
+
+struct SignedPair {
+ const char *Str;
+ int64_t Expected;
+} Signed[] =
+ { {"0", 0}
+ , {"-0", 0}
+ , {"127", 127}
+ , {"128", 128}
+ , {"-128", -128}
+ , {"-129", -129}
+ , {"32767", 32767}
+ , {"32768", 32768}
+ , {"-32768", -32768}
+ , {"-32769", -32769}
+ , {"2147483647", 2147483647LL}
+ , {"2147483648", 2147483648LL}
+ , {"-2147483648", -2147483648LL}
+ , {"-2147483649", -2147483649LL}
+ , {"-9223372036854775808", -(9223372036854775807LL) - 1}
+ , {"042", 34}
+ , {"0x42", 66}
+ , {"0b101010", 42}
+ , {"-042", -34}
+ , {"-0x42", -66}
+ , {"-0b101010", -42}
+ };
+
+TEST(StringRefTest, getAsInteger) {
+ uint8_t U8;
+ uint16_t U16;
+ uint32_t U32;
+ uint64_t U64;
+
+ for (size_t i = 0; i < array_lengthof(Unsigned); ++i) {
+ bool U8Success = StringRef(Unsigned[i].Str).getAsInteger(0, U8);
+ if (static_cast<uint8_t>(Unsigned[i].Expected) == Unsigned[i].Expected) {
+ ASSERT_FALSE(U8Success);
+ EXPECT_EQ(U8, Unsigned[i].Expected);
+ } else {
+ ASSERT_TRUE(U8Success);
+ }
+ bool U16Success = StringRef(Unsigned[i].Str).getAsInteger(0, U16);
+ if (static_cast<uint16_t>(Unsigned[i].Expected) == Unsigned[i].Expected) {
+ ASSERT_FALSE(U16Success);
+ EXPECT_EQ(U16, Unsigned[i].Expected);
+ } else {
+ ASSERT_TRUE(U16Success);
+ }
+ bool U32Success = StringRef(Unsigned[i].Str).getAsInteger(0, U32);
+ if (static_cast<uint32_t>(Unsigned[i].Expected) == Unsigned[i].Expected) {
+ ASSERT_FALSE(U32Success);
+ EXPECT_EQ(U32, Unsigned[i].Expected);
+ } else {
+ ASSERT_TRUE(U32Success);
+ }
+ bool U64Success = StringRef(Unsigned[i].Str).getAsInteger(0, U64);
+ if (static_cast<uint64_t>(Unsigned[i].Expected) == Unsigned[i].Expected) {
+ ASSERT_FALSE(U64Success);
+ EXPECT_EQ(U64, Unsigned[i].Expected);
+ } else {
+ ASSERT_TRUE(U64Success);
+ }
+ }
+
+ int8_t S8;
+ int16_t S16;
+ int32_t S32;
+ int64_t S64;
+
+ for (size_t i = 0; i < array_lengthof(Signed); ++i) {
+ bool S8Success = StringRef(Signed[i].Str).getAsInteger(0, S8);
+ if (static_cast<int8_t>(Signed[i].Expected) == Signed[i].Expected) {
+ ASSERT_FALSE(S8Success);
+ EXPECT_EQ(S8, Signed[i].Expected);
+ } else {
+ ASSERT_TRUE(S8Success);
+ }
+ bool S16Success = StringRef(Signed[i].Str).getAsInteger(0, S16);
+ if (static_cast<int16_t>(Signed[i].Expected) == Signed[i].Expected) {
+ ASSERT_FALSE(S16Success);
+ EXPECT_EQ(S16, Signed[i].Expected);
+ } else {
+ ASSERT_TRUE(S16Success);
+ }
+ bool S32Success = StringRef(Signed[i].Str).getAsInteger(0, S32);
+ if (static_cast<int32_t>(Signed[i].Expected) == Signed[i].Expected) {
+ ASSERT_FALSE(S32Success);
+ EXPECT_EQ(S32, Signed[i].Expected);
+ } else {
+ ASSERT_TRUE(S32Success);
+ }
+ bool S64Success = StringRef(Signed[i].Str).getAsInteger(0, S64);
+ if (static_cast<int64_t>(Signed[i].Expected) == Signed[i].Expected) {
+ ASSERT_FALSE(S64Success);
+ EXPECT_EQ(S64, Signed[i].Expected);
+ } else {
+ ASSERT_TRUE(S64Success);
+ }
+ }
+}
+
} // end anonymous namespace