mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
ae65e281f3
to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. llvm-svn: 351636
1065 lines
34 KiB
C++
1065 lines
34 KiB
C++
//===- llvm/unittest/ADT/StringRefTest.cpp - StringRef unit tests ---------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/ADT/Hashing.h"
|
|
#include "llvm/ADT/STLExtras.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/ADT/StringExtras.h"
|
|
#include "llvm/Support/Allocator.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include "gtest/gtest.h"
|
|
using namespace llvm;
|
|
|
|
namespace llvm {
|
|
|
|
std::ostream &operator<<(std::ostream &OS, const StringRef &S) {
|
|
OS << S.str();
|
|
return OS;
|
|
}
|
|
|
|
std::ostream &operator<<(std::ostream &OS,
|
|
const std::pair<StringRef, StringRef> &P) {
|
|
OS << "(" << P.first << ", " << P.second << ")";
|
|
return OS;
|
|
}
|
|
|
|
}
|
|
|
|
// Check that we can't accidentally assign a temporary std::string to a
|
|
// StringRef. (Unfortunately we can't make use of the same thing with
|
|
// constructors.)
|
|
//
|
|
// Disable this check under MSVC; even MSVC 2015 isn't consistent between
|
|
// std::is_assignable and actually writing such an assignment.
|
|
#if !defined(_MSC_VER)
|
|
static_assert(
|
|
!std::is_assignable<StringRef&, std::string>::value,
|
|
"Assigning from prvalue std::string");
|
|
static_assert(
|
|
!std::is_assignable<StringRef&, std::string &&>::value,
|
|
"Assigning from xvalue std::string");
|
|
static_assert(
|
|
std::is_assignable<StringRef&, std::string &>::value,
|
|
"Assigning from lvalue std::string");
|
|
static_assert(
|
|
std::is_assignable<StringRef&, const char *>::value,
|
|
"Assigning from prvalue C string");
|
|
static_assert(
|
|
std::is_assignable<StringRef&, const char * &&>::value,
|
|
"Assigning from xvalue C string");
|
|
static_assert(
|
|
std::is_assignable<StringRef&, const char * &>::value,
|
|
"Assigning from lvalue C string");
|
|
#endif
|
|
|
|
|
|
namespace {
|
|
TEST(StringRefTest, Construction) {
|
|
EXPECT_EQ("", StringRef());
|
|
EXPECT_EQ("hello", StringRef("hello"));
|
|
EXPECT_EQ("hello", StringRef("hello world", 5));
|
|
EXPECT_EQ("hello", StringRef(std::string("hello")));
|
|
}
|
|
|
|
TEST(StringRefTest, EmptyInitializerList) {
|
|
StringRef S = {};
|
|
EXPECT_TRUE(S.empty());
|
|
|
|
S = {};
|
|
EXPECT_TRUE(S.empty());
|
|
}
|
|
|
|
TEST(StringRefTest, Iteration) {
|
|
StringRef S("hello");
|
|
const char *p = "hello";
|
|
for (const char *it = S.begin(), *ie = S.end(); it != ie; ++it, ++p)
|
|
EXPECT_EQ(*it, *p);
|
|
}
|
|
|
|
TEST(StringRefTest, StringOps) {
|
|
const char *p = "hello";
|
|
EXPECT_EQ(p, StringRef(p, 0).data());
|
|
EXPECT_TRUE(StringRef().empty());
|
|
EXPECT_EQ((size_t) 5, StringRef("hello").size());
|
|
EXPECT_EQ(-1, StringRef("aab").compare("aad"));
|
|
EXPECT_EQ( 0, StringRef("aab").compare("aab"));
|
|
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("bb"));
|
|
EXPECT_EQ( 1, StringRef("aaBb").compare_lower("AaB"));
|
|
EXPECT_EQ( 1, StringRef("bb").compare_lower("AaB"));
|
|
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) {
|
|
EXPECT_EQ("", StringRef());
|
|
EXPECT_TRUE(StringRef("aab") < StringRef("aad"));
|
|
EXPECT_FALSE(StringRef("aab") < StringRef("aab"));
|
|
EXPECT_TRUE(StringRef("aab") <= StringRef("aab"));
|
|
EXPECT_FALSE(StringRef("aab") <= StringRef("aaa"));
|
|
EXPECT_TRUE(StringRef("aad") > StringRef("aab"));
|
|
EXPECT_FALSE(StringRef("aab") > StringRef("aab"));
|
|
EXPECT_TRUE(StringRef("aab") >= StringRef("aab"));
|
|
EXPECT_FALSE(StringRef("aaa") >= StringRef("aab"));
|
|
EXPECT_EQ(StringRef("aab"), StringRef("aab"));
|
|
EXPECT_FALSE(StringRef("aab") == StringRef("aac"));
|
|
EXPECT_FALSE(StringRef("aab") != StringRef("aab"));
|
|
EXPECT_TRUE(StringRef("aab") != StringRef("aac"));
|
|
EXPECT_EQ('a', StringRef("aab")[1]);
|
|
}
|
|
|
|
TEST(StringRefTest, Substr) {
|
|
StringRef Str("hello");
|
|
EXPECT_EQ("lo", Str.substr(3));
|
|
EXPECT_EQ("", Str.substr(100));
|
|
EXPECT_EQ("hello", Str.substr(0, 100));
|
|
EXPECT_EQ("o", Str.substr(4, 10));
|
|
}
|
|
|
|
TEST(StringRefTest, Slice) {
|
|
StringRef Str("hello");
|
|
EXPECT_EQ("l", Str.slice(2, 3));
|
|
EXPECT_EQ("ell", Str.slice(1, 4));
|
|
EXPECT_EQ("llo", Str.slice(2, 100));
|
|
EXPECT_EQ("", Str.slice(2, 1));
|
|
EXPECT_EQ("", Str.slice(10, 20));
|
|
}
|
|
|
|
TEST(StringRefTest, Split) {
|
|
StringRef Str("hello");
|
|
EXPECT_EQ(std::make_pair(StringRef("hello"), StringRef("")),
|
|
Str.split('X'));
|
|
EXPECT_EQ(std::make_pair(StringRef("h"), StringRef("llo")),
|
|
Str.split('e'));
|
|
EXPECT_EQ(std::make_pair(StringRef(""), StringRef("ello")),
|
|
Str.split('h'));
|
|
EXPECT_EQ(std::make_pair(StringRef("he"), StringRef("lo")),
|
|
Str.split('l'));
|
|
EXPECT_EQ(std::make_pair(StringRef("hell"), StringRef("")),
|
|
Str.split('o'));
|
|
|
|
EXPECT_EQ(std::make_pair(StringRef("hello"), StringRef("")),
|
|
Str.rsplit('X'));
|
|
EXPECT_EQ(std::make_pair(StringRef("h"), StringRef("llo")),
|
|
Str.rsplit('e'));
|
|
EXPECT_EQ(std::make_pair(StringRef(""), StringRef("ello")),
|
|
Str.rsplit('h'));
|
|
EXPECT_EQ(std::make_pair(StringRef("hel"), StringRef("o")),
|
|
Str.rsplit('l'));
|
|
EXPECT_EQ(std::make_pair(StringRef("hell"), StringRef("")),
|
|
Str.rsplit('o'));
|
|
|
|
EXPECT_EQ(std::make_pair(StringRef("he"), StringRef("o")),
|
|
Str.rsplit("ll"));
|
|
EXPECT_EQ(std::make_pair(StringRef(""), StringRef("ello")),
|
|
Str.rsplit("h"));
|
|
EXPECT_EQ(std::make_pair(StringRef("hell"), StringRef("")),
|
|
Str.rsplit("o"));
|
|
EXPECT_EQ(std::make_pair(StringRef("hello"), StringRef("")),
|
|
Str.rsplit("::"));
|
|
EXPECT_EQ(std::make_pair(StringRef("hel"), StringRef("o")),
|
|
Str.rsplit("l"));
|
|
}
|
|
|
|
TEST(StringRefTest, Split2) {
|
|
SmallVector<StringRef, 5> parts;
|
|
SmallVector<StringRef, 5> expected;
|
|
|
|
expected.push_back("ab"); expected.push_back("c");
|
|
StringRef(",ab,,c,").split(parts, ",", -1, false);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back(""); expected.push_back("ab"); expected.push_back("");
|
|
expected.push_back("c"); expected.push_back("");
|
|
StringRef(",ab,,c,").split(parts, ",", -1, true);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back("");
|
|
StringRef("").split(parts, ",", -1, true);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
StringRef("").split(parts, ",", -1, false);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
StringRef(",").split(parts, ",", -1, false);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back(""); expected.push_back("");
|
|
StringRef(",").split(parts, ",", -1, true);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back("a"); expected.push_back("b");
|
|
StringRef("a,b").split(parts, ",", -1, true);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
// Test MaxSplit
|
|
expected.clear(); parts.clear();
|
|
expected.push_back("a,,b,c");
|
|
StringRef("a,,b,c").split(parts, ",", 0, true);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back("a,,b,c");
|
|
StringRef("a,,b,c").split(parts, ",", 0, false);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back("a"); expected.push_back(",b,c");
|
|
StringRef("a,,b,c").split(parts, ",", 1, true);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back("a"); expected.push_back(",b,c");
|
|
StringRef("a,,b,c").split(parts, ",", 1, false);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back("a"); expected.push_back(""); expected.push_back("b,c");
|
|
StringRef("a,,b,c").split(parts, ",", 2, true);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back("a"); expected.push_back("b,c");
|
|
StringRef("a,,b,c").split(parts, ",", 2, false);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back("a"); expected.push_back(""); expected.push_back("b");
|
|
expected.push_back("c");
|
|
StringRef("a,,b,c").split(parts, ",", 3, true);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back("a"); expected.push_back("b"); expected.push_back("c");
|
|
StringRef("a,,b,c").split(parts, ",", 3, false);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back("a"); expected.push_back("b"); expected.push_back("c");
|
|
StringRef("a,,b,c").split(parts, ',', 3, false);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back("");
|
|
StringRef().split(parts, ",", 0, true);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back(StringRef());
|
|
StringRef("").split(parts, ",", 0, true);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
StringRef("").split(parts, ",", 0, false);
|
|
EXPECT_TRUE(parts == expected);
|
|
StringRef().split(parts, ",", 0, false);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back("a");
|
|
expected.push_back("");
|
|
expected.push_back("b");
|
|
expected.push_back("c,d");
|
|
StringRef("a,,b,c,d").split(parts, ",", 3, true);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back("");
|
|
StringRef().split(parts, ',', 0, true);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back(StringRef());
|
|
StringRef("").split(parts, ',', 0, true);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
StringRef("").split(parts, ',', 0, false);
|
|
EXPECT_TRUE(parts == expected);
|
|
StringRef().split(parts, ',', 0, false);
|
|
EXPECT_TRUE(parts == expected);
|
|
|
|
expected.clear(); parts.clear();
|
|
expected.push_back("a");
|
|
expected.push_back("");
|
|
expected.push_back("b");
|
|
expected.push_back("c,d");
|
|
StringRef("a,,b,c,d").split(parts, ',', 3, true);
|
|
EXPECT_TRUE(parts == expected);
|
|
}
|
|
|
|
TEST(StringRefTest, Trim) {
|
|
StringRef Str0("hello");
|
|
StringRef Str1(" hello ");
|
|
StringRef Str2(" hello ");
|
|
|
|
EXPECT_EQ(StringRef("hello"), Str0.rtrim());
|
|
EXPECT_EQ(StringRef(" hello"), Str1.rtrim());
|
|
EXPECT_EQ(StringRef(" hello"), Str2.rtrim());
|
|
EXPECT_EQ(StringRef("hello"), Str0.ltrim());
|
|
EXPECT_EQ(StringRef("hello "), Str1.ltrim());
|
|
EXPECT_EQ(StringRef("hello "), Str2.ltrim());
|
|
EXPECT_EQ(StringRef("hello"), Str0.trim());
|
|
EXPECT_EQ(StringRef("hello"), Str1.trim());
|
|
EXPECT_EQ(StringRef("hello"), Str2.trim());
|
|
|
|
EXPECT_EQ(StringRef("ello"), Str0.trim("hhhhhhhhhhh"));
|
|
|
|
EXPECT_EQ(StringRef(""), StringRef("").trim());
|
|
EXPECT_EQ(StringRef(""), StringRef(" ").trim());
|
|
EXPECT_EQ(StringRef("\0", 1), StringRef(" \0 ", 3).trim());
|
|
EXPECT_EQ(StringRef("\0\0", 2), StringRef("\0\0", 2).trim());
|
|
EXPECT_EQ(StringRef("x"), StringRef("\0\0x\0\0", 5).trim('\0'));
|
|
}
|
|
|
|
TEST(StringRefTest, StartsWith) {
|
|
StringRef Str("hello");
|
|
EXPECT_TRUE(Str.startswith(""));
|
|
EXPECT_TRUE(Str.startswith("he"));
|
|
EXPECT_FALSE(Str.startswith("helloworld"));
|
|
EXPECT_FALSE(Str.startswith("hi"));
|
|
}
|
|
|
|
TEST(StringRefTest, StartsWithLower) {
|
|
StringRef Str("heLLo");
|
|
EXPECT_TRUE(Str.startswith_lower(""));
|
|
EXPECT_TRUE(Str.startswith_lower("he"));
|
|
EXPECT_TRUE(Str.startswith_lower("hell"));
|
|
EXPECT_TRUE(Str.startswith_lower("HELlo"));
|
|
EXPECT_FALSE(Str.startswith_lower("helloworld"));
|
|
EXPECT_FALSE(Str.startswith_lower("hi"));
|
|
}
|
|
|
|
TEST(StringRefTest, ConsumeFront) {
|
|
StringRef Str("hello");
|
|
EXPECT_TRUE(Str.consume_front(""));
|
|
EXPECT_EQ("hello", Str);
|
|
EXPECT_TRUE(Str.consume_front("he"));
|
|
EXPECT_EQ("llo", Str);
|
|
EXPECT_FALSE(Str.consume_front("lloworld"));
|
|
EXPECT_EQ("llo", Str);
|
|
EXPECT_FALSE(Str.consume_front("lol"));
|
|
EXPECT_EQ("llo", Str);
|
|
EXPECT_TRUE(Str.consume_front("llo"));
|
|
EXPECT_EQ("", Str);
|
|
EXPECT_FALSE(Str.consume_front("o"));
|
|
EXPECT_TRUE(Str.consume_front(""));
|
|
}
|
|
|
|
TEST(StringRefTest, EndsWith) {
|
|
StringRef Str("hello");
|
|
EXPECT_TRUE(Str.endswith(""));
|
|
EXPECT_TRUE(Str.endswith("lo"));
|
|
EXPECT_FALSE(Str.endswith("helloworld"));
|
|
EXPECT_FALSE(Str.endswith("worldhello"));
|
|
EXPECT_FALSE(Str.endswith("so"));
|
|
}
|
|
|
|
TEST(StringRefTest, EndsWithLower) {
|
|
StringRef Str("heLLo");
|
|
EXPECT_TRUE(Str.endswith_lower(""));
|
|
EXPECT_TRUE(Str.endswith_lower("lo"));
|
|
EXPECT_TRUE(Str.endswith_lower("LO"));
|
|
EXPECT_TRUE(Str.endswith_lower("ELlo"));
|
|
EXPECT_FALSE(Str.endswith_lower("helloworld"));
|
|
EXPECT_FALSE(Str.endswith_lower("hi"));
|
|
}
|
|
|
|
TEST(StringRefTest, ConsumeBack) {
|
|
StringRef Str("hello");
|
|
EXPECT_TRUE(Str.consume_back(""));
|
|
EXPECT_EQ("hello", Str);
|
|
EXPECT_TRUE(Str.consume_back("lo"));
|
|
EXPECT_EQ("hel", Str);
|
|
EXPECT_FALSE(Str.consume_back("helhel"));
|
|
EXPECT_EQ("hel", Str);
|
|
EXPECT_FALSE(Str.consume_back("hle"));
|
|
EXPECT_EQ("hel", Str);
|
|
EXPECT_TRUE(Str.consume_back("hel"));
|
|
EXPECT_EQ("", Str);
|
|
EXPECT_FALSE(Str.consume_back("h"));
|
|
EXPECT_TRUE(Str.consume_back(""));
|
|
}
|
|
|
|
TEST(StringRefTest, Find) {
|
|
StringRef Str("helloHELLO");
|
|
StringRef LongStr("hellx xello hell ello world foo bar hello HELLO");
|
|
|
|
struct {
|
|
StringRef Str;
|
|
char C;
|
|
std::size_t From;
|
|
std::size_t Pos;
|
|
std::size_t LowerPos;
|
|
} CharExpectations[] = {
|
|
{Str, 'h', 0U, 0U, 0U},
|
|
{Str, 'e', 0U, 1U, 1U},
|
|
{Str, 'l', 0U, 2U, 2U},
|
|
{Str, 'l', 3U, 3U, 3U},
|
|
{Str, 'o', 0U, 4U, 4U},
|
|
{Str, 'L', 0U, 7U, 2U},
|
|
{Str, 'z', 0U, StringRef::npos, StringRef::npos},
|
|
};
|
|
|
|
struct {
|
|
StringRef Str;
|
|
llvm::StringRef S;
|
|
std::size_t From;
|
|
std::size_t Pos;
|
|
std::size_t LowerPos;
|
|
} StrExpectations[] = {
|
|
{Str, "helloword", 0, StringRef::npos, StringRef::npos},
|
|
{Str, "hello", 0, 0U, 0U},
|
|
{Str, "ello", 0, 1U, 1U},
|
|
{Str, "zz", 0, StringRef::npos, StringRef::npos},
|
|
{Str, "ll", 2U, 2U, 2U},
|
|
{Str, "ll", 3U, StringRef::npos, 7U},
|
|
{Str, "LL", 2U, 7U, 2U},
|
|
{Str, "LL", 3U, 7U, 7U},
|
|
{Str, "", 0U, 0U, 0U},
|
|
{LongStr, "hello", 0U, 36U, 36U},
|
|
{LongStr, "foo", 0U, 28U, 28U},
|
|
{LongStr, "hell", 2U, 12U, 12U},
|
|
{LongStr, "HELL", 2U, 42U, 12U},
|
|
{LongStr, "", 0U, 0U, 0U}};
|
|
|
|
for (auto &E : CharExpectations) {
|
|
EXPECT_EQ(E.Pos, E.Str.find(E.C, E.From));
|
|
EXPECT_EQ(E.LowerPos, E.Str.find_lower(E.C, E.From));
|
|
EXPECT_EQ(E.LowerPos, E.Str.find_lower(toupper(E.C), E.From));
|
|
}
|
|
|
|
for (auto &E : StrExpectations) {
|
|
EXPECT_EQ(E.Pos, E.Str.find(E.S, E.From));
|
|
EXPECT_EQ(E.LowerPos, E.Str.find_lower(E.S, E.From));
|
|
EXPECT_EQ(E.LowerPos, E.Str.find_lower(E.S.upper(), E.From));
|
|
}
|
|
|
|
EXPECT_EQ(3U, Str.rfind('l'));
|
|
EXPECT_EQ(StringRef::npos, Str.rfind('z'));
|
|
EXPECT_EQ(StringRef::npos, Str.rfind("helloworld"));
|
|
EXPECT_EQ(0U, Str.rfind("hello"));
|
|
EXPECT_EQ(1U, Str.rfind("ello"));
|
|
EXPECT_EQ(StringRef::npos, Str.rfind("zz"));
|
|
|
|
EXPECT_EQ(8U, Str.rfind_lower('l'));
|
|
EXPECT_EQ(8U, Str.rfind_lower('L'));
|
|
EXPECT_EQ(StringRef::npos, Str.rfind_lower('z'));
|
|
EXPECT_EQ(StringRef::npos, Str.rfind_lower("HELLOWORLD"));
|
|
EXPECT_EQ(5U, Str.rfind("HELLO"));
|
|
EXPECT_EQ(6U, Str.rfind("ELLO"));
|
|
EXPECT_EQ(StringRef::npos, Str.rfind("ZZ"));
|
|
|
|
EXPECT_EQ(2U, Str.find_first_of('l'));
|
|
EXPECT_EQ(1U, Str.find_first_of("el"));
|
|
EXPECT_EQ(StringRef::npos, Str.find_first_of("xyz"));
|
|
|
|
Str = "hello";
|
|
EXPECT_EQ(1U, Str.find_first_not_of('h'));
|
|
EXPECT_EQ(4U, Str.find_first_not_of("hel"));
|
|
EXPECT_EQ(StringRef::npos, Str.find_first_not_of("hello"));
|
|
|
|
EXPECT_EQ(3U, Str.find_last_not_of('o'));
|
|
EXPECT_EQ(1U, Str.find_last_not_of("lo"));
|
|
EXPECT_EQ(StringRef::npos, Str.find_last_not_of("helo"));
|
|
}
|
|
|
|
TEST(StringRefTest, Count) {
|
|
StringRef Str("hello");
|
|
EXPECT_EQ(2U, Str.count('l'));
|
|
EXPECT_EQ(1U, Str.count('o'));
|
|
EXPECT_EQ(0U, Str.count('z'));
|
|
EXPECT_EQ(0U, Str.count("helloworld"));
|
|
EXPECT_EQ(1U, Str.count("hello"));
|
|
EXPECT_EQ(1U, Str.count("ello"));
|
|
EXPECT_EQ(0U, Str.count("zz"));
|
|
}
|
|
|
|
TEST(StringRefTest, EditDistance) {
|
|
StringRef Hello("hello");
|
|
EXPECT_EQ(2U, Hello.edit_distance("hill"));
|
|
|
|
StringRef Industry("industry");
|
|
EXPECT_EQ(6U, Industry.edit_distance("interest"));
|
|
|
|
StringRef Soylent("soylent green is people");
|
|
EXPECT_EQ(19U, Soylent.edit_distance("people soiled our green"));
|
|
EXPECT_EQ(26U, Soylent.edit_distance("people soiled our green",
|
|
/* allow replacements = */ false));
|
|
EXPECT_EQ(9U, Soylent.edit_distance("people soiled our green",
|
|
/* allow replacements = */ true,
|
|
/* max edit distance = */ 8));
|
|
EXPECT_EQ(53U, Soylent.edit_distance("people soiled our green "
|
|
"people soiled our green "
|
|
"people soiled our green "));
|
|
}
|
|
|
|
TEST(StringRefTest, Misc) {
|
|
std::string Storage;
|
|
raw_string_ostream OS(Storage);
|
|
OS << StringRef("hello");
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static const char* BadStrings[] = {
|
|
"" // empty string
|
|
, "18446744073709551617" // value just over max
|
|
, "123456789012345678901" // value way too large
|
|
, "4t23v" // illegal decimal characters
|
|
, "0x123W56" // illegal hex characters
|
|
, "0b2" // illegal bin characters
|
|
, "08" // illegal oct characters
|
|
, "0o8" // illegal oct characters
|
|
, "-123" // negative unsigned value
|
|
, "0x"
|
|
, "0b"
|
|
};
|
|
|
|
|
|
TEST(StringRefTest, getAsUnsignedIntegerBadStrings) {
|
|
unsigned long long U64;
|
|
for (size_t i = 0; i < array_lengthof(BadStrings); ++i) {
|
|
bool IsBadNumber = StringRef(BadStrings[i]).getAsInteger(0, U64);
|
|
ASSERT_TRUE(IsBadNumber);
|
|
}
|
|
}
|
|
|
|
struct ConsumeUnsignedPair {
|
|
const char *Str;
|
|
uint64_t Expected;
|
|
const char *Leftover;
|
|
} ConsumeUnsigned[] = {
|
|
{"0", 0, ""},
|
|
{"255", 255, ""},
|
|
{"256", 256, ""},
|
|
{"65535", 65535, ""},
|
|
{"65536", 65536, ""},
|
|
{"4294967295", 4294967295ULL, ""},
|
|
{"4294967296", 4294967296ULL, ""},
|
|
{"255A376", 255, "A376"},
|
|
{"18446744073709551615", 18446744073709551615ULL, ""},
|
|
{"18446744073709551615ABC", 18446744073709551615ULL, "ABC"},
|
|
{"042", 34, ""},
|
|
{"0x42", 66, ""},
|
|
{"0x42-0x34", 66, "-0x34"},
|
|
{"0b101010", 42, ""},
|
|
{"0429F", 042, "9F"}, // Auto-sensed octal radix, invalid digit
|
|
{"0x42G12", 0x42, "G12"}, // Auto-sensed hex radix, invalid digit
|
|
{"0b10101020101", 42, "20101"}}; // Auto-sensed binary radix, invalid digit.
|
|
|
|
struct ConsumeSignedPair {
|
|
const char *Str;
|
|
int64_t Expected;
|
|
const char *Leftover;
|
|
} ConsumeSigned[] = {
|
|
{"0", 0, ""},
|
|
{"-0", 0, ""},
|
|
{"0-1", 0, "-1"},
|
|
{"-0-1", 0, "-1"},
|
|
{"127", 127, ""},
|
|
{"128", 128, ""},
|
|
{"127-1", 127, "-1"},
|
|
{"128-1", 128, "-1"},
|
|
{"-128", -128, ""},
|
|
{"-129", -129, ""},
|
|
{"-128-1", -128, "-1"},
|
|
{"-129-1", -129, "-1"},
|
|
{"32767", 32767, ""},
|
|
{"32768", 32768, ""},
|
|
{"32767-1", 32767, "-1"},
|
|
{"32768-1", 32768, "-1"},
|
|
{"-32768", -32768, ""},
|
|
{"-32769", -32769, ""},
|
|
{"-32768-1", -32768, "-1"},
|
|
{"-32769-1", -32769, "-1"},
|
|
{"2147483647", 2147483647LL, ""},
|
|
{"2147483648", 2147483648LL, ""},
|
|
{"2147483647-1", 2147483647LL, "-1"},
|
|
{"2147483648-1", 2147483648LL, "-1"},
|
|
{"-2147483648", -2147483648LL, ""},
|
|
{"-2147483649", -2147483649LL, ""},
|
|
{"-2147483648-1", -2147483648LL, "-1"},
|
|
{"-2147483649-1", -2147483649LL, "-1"},
|
|
{"-9223372036854775808", -(9223372036854775807LL) - 1, ""},
|
|
{"-9223372036854775808-1", -(9223372036854775807LL) - 1, "-1"},
|
|
{"042", 34, ""},
|
|
{"042-1", 34, "-1"},
|
|
{"0x42", 66, ""},
|
|
{"0x42-1", 66, "-1"},
|
|
{"0b101010", 42, ""},
|
|
{"0b101010-1", 42, "-1"},
|
|
{"-042", -34, ""},
|
|
{"-042-1", -34, "-1"},
|
|
{"-0x42", -66, ""},
|
|
{"-0x42-1", -66, "-1"},
|
|
{"-0b101010", -42, ""},
|
|
{"-0b101010-1", -42, "-1"}};
|
|
|
|
TEST(StringRefTest, consumeIntegerUnsigned) {
|
|
uint8_t U8;
|
|
uint16_t U16;
|
|
uint32_t U32;
|
|
uint64_t U64;
|
|
|
|
for (size_t i = 0; i < array_lengthof(ConsumeUnsigned); ++i) {
|
|
StringRef Str = ConsumeUnsigned[i].Str;
|
|
bool U8Success = Str.consumeInteger(0, U8);
|
|
if (static_cast<uint8_t>(ConsumeUnsigned[i].Expected) ==
|
|
ConsumeUnsigned[i].Expected) {
|
|
ASSERT_FALSE(U8Success);
|
|
EXPECT_EQ(U8, ConsumeUnsigned[i].Expected);
|
|
EXPECT_EQ(Str, ConsumeUnsigned[i].Leftover);
|
|
} else {
|
|
ASSERT_TRUE(U8Success);
|
|
}
|
|
|
|
Str = ConsumeUnsigned[i].Str;
|
|
bool U16Success = Str.consumeInteger(0, U16);
|
|
if (static_cast<uint16_t>(ConsumeUnsigned[i].Expected) ==
|
|
ConsumeUnsigned[i].Expected) {
|
|
ASSERT_FALSE(U16Success);
|
|
EXPECT_EQ(U16, ConsumeUnsigned[i].Expected);
|
|
EXPECT_EQ(Str, ConsumeUnsigned[i].Leftover);
|
|
} else {
|
|
ASSERT_TRUE(U16Success);
|
|
}
|
|
|
|
Str = ConsumeUnsigned[i].Str;
|
|
bool U32Success = Str.consumeInteger(0, U32);
|
|
if (static_cast<uint32_t>(ConsumeUnsigned[i].Expected) ==
|
|
ConsumeUnsigned[i].Expected) {
|
|
ASSERT_FALSE(U32Success);
|
|
EXPECT_EQ(U32, ConsumeUnsigned[i].Expected);
|
|
EXPECT_EQ(Str, ConsumeUnsigned[i].Leftover);
|
|
} else {
|
|
ASSERT_TRUE(U32Success);
|
|
}
|
|
|
|
Str = ConsumeUnsigned[i].Str;
|
|
bool U64Success = Str.consumeInteger(0, U64);
|
|
if (static_cast<uint64_t>(ConsumeUnsigned[i].Expected) ==
|
|
ConsumeUnsigned[i].Expected) {
|
|
ASSERT_FALSE(U64Success);
|
|
EXPECT_EQ(U64, ConsumeUnsigned[i].Expected);
|
|
EXPECT_EQ(Str, ConsumeUnsigned[i].Leftover);
|
|
} else {
|
|
ASSERT_TRUE(U64Success);
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST(StringRefTest, consumeIntegerSigned) {
|
|
int8_t S8;
|
|
int16_t S16;
|
|
int32_t S32;
|
|
int64_t S64;
|
|
|
|
for (size_t i = 0; i < array_lengthof(ConsumeSigned); ++i) {
|
|
StringRef Str = ConsumeSigned[i].Str;
|
|
bool S8Success = Str.consumeInteger(0, S8);
|
|
if (static_cast<int8_t>(ConsumeSigned[i].Expected) ==
|
|
ConsumeSigned[i].Expected) {
|
|
ASSERT_FALSE(S8Success);
|
|
EXPECT_EQ(S8, ConsumeSigned[i].Expected);
|
|
EXPECT_EQ(Str, ConsumeSigned[i].Leftover);
|
|
} else {
|
|
ASSERT_TRUE(S8Success);
|
|
}
|
|
|
|
Str = ConsumeSigned[i].Str;
|
|
bool S16Success = Str.consumeInteger(0, S16);
|
|
if (static_cast<int16_t>(ConsumeSigned[i].Expected) ==
|
|
ConsumeSigned[i].Expected) {
|
|
ASSERT_FALSE(S16Success);
|
|
EXPECT_EQ(S16, ConsumeSigned[i].Expected);
|
|
EXPECT_EQ(Str, ConsumeSigned[i].Leftover);
|
|
} else {
|
|
ASSERT_TRUE(S16Success);
|
|
}
|
|
|
|
Str = ConsumeSigned[i].Str;
|
|
bool S32Success = Str.consumeInteger(0, S32);
|
|
if (static_cast<int32_t>(ConsumeSigned[i].Expected) ==
|
|
ConsumeSigned[i].Expected) {
|
|
ASSERT_FALSE(S32Success);
|
|
EXPECT_EQ(S32, ConsumeSigned[i].Expected);
|
|
EXPECT_EQ(Str, ConsumeSigned[i].Leftover);
|
|
} else {
|
|
ASSERT_TRUE(S32Success);
|
|
}
|
|
|
|
Str = ConsumeSigned[i].Str;
|
|
bool S64Success = Str.consumeInteger(0, S64);
|
|
if (static_cast<int64_t>(ConsumeSigned[i].Expected) ==
|
|
ConsumeSigned[i].Expected) {
|
|
ASSERT_FALSE(S64Success);
|
|
EXPECT_EQ(S64, ConsumeSigned[i].Expected);
|
|
EXPECT_EQ(Str, ConsumeSigned[i].Leftover);
|
|
} else {
|
|
ASSERT_TRUE(S64Success);
|
|
}
|
|
}
|
|
}
|
|
|
|
struct GetDoubleStrings {
|
|
const char *Str;
|
|
bool AllowInexact;
|
|
bool ShouldFail;
|
|
double D;
|
|
} DoubleStrings[] = {{"0", false, false, 0.0},
|
|
{"0.0", false, false, 0.0},
|
|
{"-0.0", false, false, -0.0},
|
|
{"123.45", false, true, 123.45},
|
|
{"123.45", true, false, 123.45},
|
|
{"1.8e308", true, false, std::numeric_limits<double>::infinity()},
|
|
{"1.8e308", false, true, std::numeric_limits<double>::infinity()},
|
|
{"0x0.0000000000001P-1023", false, true, 0.0},
|
|
{"0x0.0000000000001P-1023", true, false, 0.0},
|
|
};
|
|
|
|
TEST(StringRefTest, getAsDouble) {
|
|
for (const auto &Entry : DoubleStrings) {
|
|
double Result;
|
|
StringRef S(Entry.Str);
|
|
EXPECT_EQ(Entry.ShouldFail, S.getAsDouble(Result, Entry.AllowInexact));
|
|
if (!Entry.ShouldFail) {
|
|
EXPECT_EQ(Result, Entry.D);
|
|
}
|
|
}
|
|
}
|
|
|
|
static const char *join_input[] = { "a", "b", "c" };
|
|
static const char join_result1[] = "a";
|
|
static const char join_result2[] = "a:b:c";
|
|
static const char join_result3[] = "a::b::c";
|
|
|
|
TEST(StringRefTest, joinStrings) {
|
|
std::vector<StringRef> v1;
|
|
std::vector<std::string> v2;
|
|
for (size_t i = 0; i < array_lengthof(join_input); ++i) {
|
|
v1.push_back(join_input[i]);
|
|
v2.push_back(join_input[i]);
|
|
}
|
|
|
|
bool v1_join1 = join(v1.begin(), v1.begin() + 1, ":") == join_result1;
|
|
EXPECT_TRUE(v1_join1);
|
|
bool v1_join2 = join(v1.begin(), v1.end(), ":") == join_result2;
|
|
EXPECT_TRUE(v1_join2);
|
|
bool v1_join3 = join(v1.begin(), v1.end(), "::") == join_result3;
|
|
EXPECT_TRUE(v1_join3);
|
|
|
|
bool v2_join1 = join(v2.begin(), v2.begin() + 1, ":") == join_result1;
|
|
EXPECT_TRUE(v2_join1);
|
|
bool v2_join2 = join(v2.begin(), v2.end(), ":") == join_result2;
|
|
EXPECT_TRUE(v2_join2);
|
|
bool v2_join3 = join(v2.begin(), v2.end(), "::") == join_result3;
|
|
EXPECT_TRUE(v2_join3);
|
|
v2_join3 = join(v2, "::") == join_result3;
|
|
EXPECT_TRUE(v2_join3);
|
|
}
|
|
|
|
|
|
TEST(StringRefTest, AllocatorCopy) {
|
|
BumpPtrAllocator Alloc;
|
|
// First test empty strings. We don't want these to allocate anything on the
|
|
// allocator.
|
|
StringRef StrEmpty = "";
|
|
StringRef StrEmptyc = StrEmpty.copy(Alloc);
|
|
EXPECT_TRUE(StrEmpty.equals(StrEmptyc));
|
|
EXPECT_EQ(StrEmptyc.data(), nullptr);
|
|
EXPECT_EQ(StrEmptyc.size(), 0u);
|
|
EXPECT_EQ(Alloc.getTotalMemory(), 0u);
|
|
|
|
StringRef Str1 = "hello";
|
|
StringRef Str2 = "bye";
|
|
StringRef Str1c = Str1.copy(Alloc);
|
|
StringRef Str2c = Str2.copy(Alloc);
|
|
EXPECT_TRUE(Str1.equals(Str1c));
|
|
EXPECT_NE(Str1.data(), Str1c.data());
|
|
EXPECT_TRUE(Str2.equals(Str2c));
|
|
EXPECT_NE(Str2.data(), Str2c.data());
|
|
}
|
|
|
|
TEST(StringRefTest, Drop) {
|
|
StringRef Test("StringRefTest::Drop");
|
|
|
|
StringRef Dropped = Test.drop_front(5);
|
|
EXPECT_EQ(Dropped, "gRefTest::Drop");
|
|
|
|
Dropped = Test.drop_back(5);
|
|
EXPECT_EQ(Dropped, "StringRefTest:");
|
|
|
|
Dropped = Test.drop_front(0);
|
|
EXPECT_EQ(Dropped, Test);
|
|
|
|
Dropped = Test.drop_back(0);
|
|
EXPECT_EQ(Dropped, Test);
|
|
|
|
Dropped = Test.drop_front(Test.size());
|
|
EXPECT_TRUE(Dropped.empty());
|
|
|
|
Dropped = Test.drop_back(Test.size());
|
|
EXPECT_TRUE(Dropped.empty());
|
|
}
|
|
|
|
TEST(StringRefTest, Take) {
|
|
StringRef Test("StringRefTest::Take");
|
|
|
|
StringRef Taken = Test.take_front(5);
|
|
EXPECT_EQ(Taken, "Strin");
|
|
|
|
Taken = Test.take_back(5);
|
|
EXPECT_EQ(Taken, ":Take");
|
|
|
|
Taken = Test.take_front(Test.size());
|
|
EXPECT_EQ(Taken, Test);
|
|
|
|
Taken = Test.take_back(Test.size());
|
|
EXPECT_EQ(Taken, Test);
|
|
|
|
Taken = Test.take_front(0);
|
|
EXPECT_TRUE(Taken.empty());
|
|
|
|
Taken = Test.take_back(0);
|
|
EXPECT_TRUE(Taken.empty());
|
|
}
|
|
|
|
TEST(StringRefTest, FindIf) {
|
|
StringRef Punct("Test.String");
|
|
StringRef NoPunct("ABCDEFG");
|
|
StringRef Empty;
|
|
|
|
auto IsPunct = [](char c) { return ::ispunct(c); };
|
|
auto IsAlpha = [](char c) { return ::isalpha(c); };
|
|
EXPECT_EQ(4U, Punct.find_if(IsPunct));
|
|
EXPECT_EQ(StringRef::npos, NoPunct.find_if(IsPunct));
|
|
EXPECT_EQ(StringRef::npos, Empty.find_if(IsPunct));
|
|
|
|
EXPECT_EQ(4U, Punct.find_if_not(IsAlpha));
|
|
EXPECT_EQ(StringRef::npos, NoPunct.find_if_not(IsAlpha));
|
|
EXPECT_EQ(StringRef::npos, Empty.find_if_not(IsAlpha));
|
|
}
|
|
|
|
TEST(StringRefTest, TakeWhileUntil) {
|
|
StringRef Test("String With 1 Number");
|
|
|
|
StringRef Taken = Test.take_while([](char c) { return ::isdigit(c); });
|
|
EXPECT_EQ("", Taken);
|
|
|
|
Taken = Test.take_until([](char c) { return ::isdigit(c); });
|
|
EXPECT_EQ("String With ", Taken);
|
|
|
|
Taken = Test.take_while([](char c) { return true; });
|
|
EXPECT_EQ(Test, Taken);
|
|
|
|
Taken = Test.take_until([](char c) { return true; });
|
|
EXPECT_EQ("", Taken);
|
|
|
|
Test = "";
|
|
Taken = Test.take_while([](char c) { return true; });
|
|
EXPECT_EQ("", Taken);
|
|
}
|
|
|
|
TEST(StringRefTest, DropWhileUntil) {
|
|
StringRef Test("String With 1 Number");
|
|
|
|
StringRef Taken = Test.drop_while([](char c) { return ::isdigit(c); });
|
|
EXPECT_EQ(Test, Taken);
|
|
|
|
Taken = Test.drop_until([](char c) { return ::isdigit(c); });
|
|
EXPECT_EQ("1 Number", Taken);
|
|
|
|
Taken = Test.drop_while([](char c) { return true; });
|
|
EXPECT_EQ("", Taken);
|
|
|
|
Taken = Test.drop_until([](char c) { return true; });
|
|
EXPECT_EQ(Test, Taken);
|
|
|
|
StringRef EmptyString = "";
|
|
Taken = EmptyString.drop_while([](char c) { return true; });
|
|
EXPECT_EQ("", Taken);
|
|
}
|
|
|
|
TEST(StringRefTest, StringLiteral) {
|
|
constexpr StringLiteral Strings[] = {"Foo", "Bar"};
|
|
EXPECT_EQ(StringRef("Foo"), Strings[0]);
|
|
EXPECT_EQ(StringRef("Bar"), Strings[1]);
|
|
}
|
|
|
|
} // end anonymous namespace
|