remove all uses of std::string in filament
- libbackend (except webgpu) - libfilament - libutils std::string generates a lot of code bloat, we use CString instead. We also update CString to be more compatible with std::string's api.
This commit is contained in:
committed by
Mathias Agopian
parent
1c2fe0ce39
commit
d3ff60af21
@@ -18,53 +18,416 @@
|
||||
|
||||
#include <utils/CString.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
#include <utility>
|
||||
|
||||
using namespace utils;
|
||||
|
||||
TEST(CString, EmptyString) {
|
||||
CString emptyString("");
|
||||
CString const emptyString("");
|
||||
EXPECT_STREQ("", emptyString.c_str_safe());
|
||||
EXPECT_EQ(0, emptyString.length());
|
||||
EXPECT_TRUE(emptyString.empty());
|
||||
}
|
||||
|
||||
TEST(CString, Constructors) {
|
||||
// CString()
|
||||
{
|
||||
CString str;
|
||||
EXPECT_EQ(nullptr, str.c_str());
|
||||
EXPECT_STREQ("", str.c_str_safe());
|
||||
EXPECT_EQ(0, str.length());
|
||||
EXPECT_TRUE(str.empty());
|
||||
}
|
||||
// CString(const char* cstr, size_t length)
|
||||
{
|
||||
CString str("foobar", 3);
|
||||
EXPECT_STREQ("foo", str.c_str());
|
||||
EXPECT_EQ(3, str.length());
|
||||
}
|
||||
// CString(size_t length)
|
||||
{
|
||||
CString str(5);
|
||||
EXPECT_EQ(5, str.length());
|
||||
// The memory is zero-initialized
|
||||
EXPECT_EQ(0, str.c_str()[0]);
|
||||
EXPECT_EQ(0, str.c_str()[4]);
|
||||
}
|
||||
// CString(const char* cstr)
|
||||
{
|
||||
CString str("hello");
|
||||
EXPECT_STREQ("hello", str.c_str());
|
||||
EXPECT_EQ(5, str.length());
|
||||
}
|
||||
// CString(StringLiteral<N>)
|
||||
{
|
||||
CString str("literal"); // this uses the template constructor
|
||||
EXPECT_STREQ("literal", str.c_str());
|
||||
EXPECT_EQ(7, str.length());
|
||||
}
|
||||
// Copy constructor
|
||||
{
|
||||
CString s1("copy me");
|
||||
CString s2(s1);
|
||||
EXPECT_STREQ("copy me", s2.c_str());
|
||||
EXPECT_NE(s1.c_str(), s2.c_str()); // should be a deep copy
|
||||
}
|
||||
// Move constructor
|
||||
{
|
||||
CString s1("move me");
|
||||
const char* original_cstr = s1.c_str();
|
||||
CString s2(std::move(s1));
|
||||
EXPECT_STREQ("move me", s2.c_str());
|
||||
EXPECT_EQ(original_cstr, s2.c_str()); // pointer should be moved
|
||||
EXPECT_EQ(nullptr, s1.c_str()); // original should be empty
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CString, Assignment) {
|
||||
// Copy assignment
|
||||
{
|
||||
CString s1("copy");
|
||||
CString s2;
|
||||
s2 = s1;
|
||||
EXPECT_STREQ("copy", s2.c_str());
|
||||
EXPECT_NE(s1.c_str(), s2.c_str());
|
||||
}
|
||||
// Move assignment
|
||||
{
|
||||
CString s1("move");
|
||||
const char* original_cstr = s1.c_str();
|
||||
CString s2;
|
||||
s2 = std::move(s1);
|
||||
EXPECT_STREQ("move", s2.c_str());
|
||||
EXPECT_EQ(original_cstr, s2.c_str());
|
||||
EXPECT_EQ(nullptr, s1.c_str());
|
||||
}
|
||||
// self-assignment
|
||||
{
|
||||
CString s1("self");
|
||||
const char* original_cstr = s1.c_str();
|
||||
s1 = s1;
|
||||
EXPECT_STREQ("self", s1.c_str());
|
||||
EXPECT_EQ(original_cstr, s1.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CString, Swap) {
|
||||
CString s1("first");
|
||||
CString s2("second");
|
||||
|
||||
const char* p1 = s1.c_str();
|
||||
const char* p2 = s2.c_str();
|
||||
size_t l1 = s1.length();
|
||||
size_t l2 = s2.length();
|
||||
|
||||
s1.swap(s2);
|
||||
|
||||
EXPECT_STREQ("second", s1.c_str());
|
||||
EXPECT_STREQ("first", s2.c_str());
|
||||
EXPECT_EQ(p2, s1.c_str());
|
||||
EXPECT_EQ(p1, s2.c_str());
|
||||
EXPECT_EQ(l2, s1.length());
|
||||
EXPECT_EQ(l1, s2.length());
|
||||
}
|
||||
|
||||
TEST(CString, Concatenation) {
|
||||
// operator+=
|
||||
{
|
||||
CString s("hello");
|
||||
s += CString(" world");
|
||||
EXPECT_STREQ("hello world", s.c_str());
|
||||
}
|
||||
{
|
||||
CString s("hello");
|
||||
s += " world";
|
||||
EXPECT_STREQ("hello world", s.c_str());
|
||||
}
|
||||
{
|
||||
CString s("hello");
|
||||
const char* world = " world";
|
||||
s += world;
|
||||
EXPECT_STREQ("hello world", s.c_str());
|
||||
}
|
||||
{
|
||||
CString s("hello");
|
||||
s += "";
|
||||
EXPECT_STREQ("hello", s.c_str());
|
||||
}
|
||||
{
|
||||
CString s;
|
||||
s += "world";
|
||||
EXPECT_STREQ("world", s.c_str());
|
||||
}
|
||||
|
||||
// operator+
|
||||
{
|
||||
CString s1("hello");
|
||||
CString s2(" world");
|
||||
CString s3 = s1 + s2;
|
||||
EXPECT_STREQ("hello world", s3.c_str());
|
||||
}
|
||||
{
|
||||
CString s1("hello");
|
||||
CString s2 = s1 + " world";
|
||||
EXPECT_STREQ("hello world", s2.c_str());
|
||||
}
|
||||
{
|
||||
CString s1(" world");
|
||||
CString s2 = "hello" + s1;
|
||||
EXPECT_STREQ("hello world", s2.c_str());
|
||||
}
|
||||
{
|
||||
CString s1("hello");
|
||||
const char* world = " world";
|
||||
CString s2 = s1 + world;
|
||||
EXPECT_STREQ("hello world", s2.c_str());
|
||||
}
|
||||
{
|
||||
CString s1(" world");
|
||||
const char* hello = "hello";
|
||||
CString s2 = hello + s1;
|
||||
EXPECT_STREQ("hello world", s2.c_str());
|
||||
}
|
||||
{
|
||||
CString s = CString("a") + CString("b") + "c" + "d";
|
||||
EXPECT_STREQ("abcd", s.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CString, Comparison) {
|
||||
CString s1("abc");
|
||||
CString s2("abc");
|
||||
CString s3("def");
|
||||
CString s4("ab");
|
||||
|
||||
EXPECT_TRUE(s1 == s2);
|
||||
EXPECT_FALSE(s1 == s3);
|
||||
|
||||
EXPECT_TRUE(s1 != s3);
|
||||
EXPECT_FALSE(s1 != s2);
|
||||
|
||||
EXPECT_TRUE(s1 < s3);
|
||||
EXPECT_FALSE(s3 < s1);
|
||||
|
||||
EXPECT_TRUE(s3 > s1);
|
||||
EXPECT_FALSE(s1 > s3);
|
||||
|
||||
EXPECT_TRUE(s1 <= s2);
|
||||
EXPECT_TRUE(s1 <= s3);
|
||||
EXPECT_FALSE(s3 <= s1);
|
||||
|
||||
EXPECT_TRUE(s2 >= s1);
|
||||
EXPECT_TRUE(s3 >= s1);
|
||||
EXPECT_FALSE(s1 >= s3);
|
||||
|
||||
EXPECT_TRUE(s4 < s1);
|
||||
EXPECT_TRUE(s1 > s4);
|
||||
}
|
||||
|
||||
TEST(CString, ElementAccess) {
|
||||
CString str("01234");
|
||||
const CString cstr("const");
|
||||
|
||||
EXPECT_EQ('0', str.front());
|
||||
EXPECT_EQ('4', str.back());
|
||||
EXPECT_EQ('c', cstr.front());
|
||||
EXPECT_EQ('t', cstr.back());
|
||||
|
||||
EXPECT_EQ('2', str[2]);
|
||||
EXPECT_EQ('n', cstr[2]);
|
||||
|
||||
str[0] = 'A';
|
||||
EXPECT_STREQ("A1234", str.c_str());
|
||||
|
||||
EXPECT_EQ('3', str.at(3));
|
||||
EXPECT_EQ('t', cstr.at(4));
|
||||
|
||||
// iterators
|
||||
std::string s(str.begin(), str.end());
|
||||
EXPECT_EQ("A1234", s);
|
||||
|
||||
EXPECT_TRUE(std::equal(cstr.begin(), cstr.end(), "const"));
|
||||
}
|
||||
|
||||
TEST(CString, Append) {
|
||||
// Append CString
|
||||
{
|
||||
CString str("foo");
|
||||
str.append(CString("bar"));
|
||||
EXPECT_STREQ("foobar", str.c_str());
|
||||
}
|
||||
// Append string literal
|
||||
{
|
||||
CString str("foo");
|
||||
str.append("bar");
|
||||
EXPECT_STREQ("foobar", str.c_str());
|
||||
}
|
||||
// Append const char*
|
||||
{
|
||||
CString str("foo");
|
||||
const char* bar = "bar";
|
||||
str.append(bar);
|
||||
EXPECT_STREQ("foobar", str.c_str());
|
||||
}
|
||||
// Append nullptr
|
||||
{
|
||||
CString str("foo");
|
||||
const char* bar = nullptr;
|
||||
str.append(bar);
|
||||
EXPECT_STREQ("foo", str.c_str());
|
||||
}
|
||||
// Append to empty
|
||||
{
|
||||
CString str;
|
||||
str.append("foo");
|
||||
EXPECT_STREQ("foo", str.c_str());
|
||||
}
|
||||
{
|
||||
CString str;
|
||||
str.append(CString("foo"));
|
||||
EXPECT_STREQ("foo", str.c_str());
|
||||
}
|
||||
{
|
||||
CString str;
|
||||
const char* foo = "foo";
|
||||
str.append(foo);
|
||||
EXPECT_STREQ("foo", str.c_str());
|
||||
}
|
||||
// Append empty
|
||||
{
|
||||
CString str("foo");
|
||||
str.append("");
|
||||
EXPECT_STREQ("foo", str.c_str());
|
||||
}
|
||||
{
|
||||
CString str("foo");
|
||||
str.append(CString(""));
|
||||
EXPECT_STREQ("foo", str.c_str());
|
||||
}
|
||||
{
|
||||
CString str("foo");
|
||||
const char* empty = "";
|
||||
str.append(empty);
|
||||
EXPECT_STREQ("foo", str.c_str());
|
||||
}
|
||||
// Chaining
|
||||
{
|
||||
CString str;
|
||||
str.append("foo").append("bar").append(CString("baz"));
|
||||
EXPECT_STREQ("foobarbaz", str.c_str());
|
||||
}
|
||||
// r-value appends
|
||||
{
|
||||
CString str = CString("foo").append("bar");
|
||||
EXPECT_STREQ("foobar", str.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CString, Insert) {
|
||||
// with CString
|
||||
{
|
||||
CString str("foobaz");
|
||||
str.insert(3, CString("bar"));
|
||||
EXPECT_STREQ("foobarbaz", str.c_str());
|
||||
}
|
||||
// with string literal
|
||||
{
|
||||
CString str("world");
|
||||
str.insert(0, "hello ");
|
||||
EXPECT_STREQ("hello world", str.c_str());
|
||||
}
|
||||
// with const char*
|
||||
{
|
||||
CString str("foo");
|
||||
const char* bar = "bar";
|
||||
str.insert(3, bar);
|
||||
EXPECT_STREQ("foobar", str.c_str());
|
||||
}
|
||||
// with nullptr
|
||||
{
|
||||
CString str("foo");
|
||||
const char* bar = nullptr;
|
||||
str.insert(1, bar);
|
||||
EXPECT_STREQ("foo", str.c_str());
|
||||
}
|
||||
// r-value insert
|
||||
{
|
||||
const char* bar = "bar";
|
||||
CString str = CString("foo").insert(3, bar);
|
||||
EXPECT_STREQ("foobar", str.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CString, Replace) {
|
||||
{
|
||||
CString str("foo bar baz");
|
||||
str.replace(0, 0, CString("lkj"));
|
||||
EXPECT_STREQ("lkjfoo bar baz", str.c_str());
|
||||
}
|
||||
// with CString
|
||||
{
|
||||
CString str("foo bar baz");
|
||||
str.replace(4, 3, CString("dpa"));
|
||||
EXPECT_STREQ("foo dpa baz", str.c_str());
|
||||
}
|
||||
// with string literal
|
||||
{
|
||||
CString str("foo bar baz");
|
||||
str.replace(4, 3, CString(""));
|
||||
str.replace(4, 3, "dpa");
|
||||
EXPECT_STREQ("foo dpa baz", str.c_str());
|
||||
}
|
||||
// with const char*
|
||||
{
|
||||
CString str("foo bar baz");
|
||||
const char* dpa = "dpa";
|
||||
str.replace(4, 3, dpa);
|
||||
EXPECT_STREQ("foo dpa baz", str.c_str());
|
||||
}
|
||||
// with nullptr
|
||||
{
|
||||
CString str("foo bar baz");
|
||||
const char* dpa = nullptr;
|
||||
str.replace(4, 3, dpa);
|
||||
EXPECT_STREQ("foo baz", str.c_str());
|
||||
}
|
||||
// with empty string
|
||||
{
|
||||
CString str("foo bar baz");
|
||||
str.replace(4, 3, CString("a"));
|
||||
EXPECT_STREQ("foo a baz", str.c_str());
|
||||
str.replace(4, 3, "");
|
||||
EXPECT_STREQ("foo baz", str.c_str());
|
||||
}
|
||||
// replace that grows the string
|
||||
{
|
||||
CString str("foo bar baz");
|
||||
str.replace(4, 3, CString("abcdef"));
|
||||
str.replace(4, 3, "abcdef");
|
||||
EXPECT_STREQ("foo abcdef baz", str.c_str());
|
||||
}
|
||||
// replace that shrinks the string
|
||||
{
|
||||
CString str("foo bar baz");
|
||||
str.replace(0, 3, CString("abcdef"));
|
||||
EXPECT_STREQ("abcdef bar baz", str.c_str());
|
||||
str.replace(4, 3, "a");
|
||||
EXPECT_STREQ("foo a baz", str.c_str());
|
||||
}
|
||||
// replace at the beginning
|
||||
{
|
||||
CString str("foo bar baz");
|
||||
str.replace(8, 3, CString("abcdef"));
|
||||
EXPECT_STREQ("foo bar abcdef", str.c_str());
|
||||
str.replace(0, 3, "lkj");
|
||||
EXPECT_STREQ("lkj bar baz", str.c_str());
|
||||
}
|
||||
// replace at the end
|
||||
{
|
||||
CString str("foo bar baz");
|
||||
str.replace(0, 11, CString("abcdef"));
|
||||
EXPECT_STREQ("abcdef", str.c_str());
|
||||
str.replace(8, 3, "lkj");
|
||||
EXPECT_STREQ("foo bar lkj", str.c_str());
|
||||
}
|
||||
// replace all
|
||||
{
|
||||
CString str("foo bar baz");
|
||||
str.replace(0, 11, "lkj");
|
||||
EXPECT_STREQ("lkj", str.c_str());
|
||||
}
|
||||
// r-value replace
|
||||
{
|
||||
const char* dpa = "dpa";
|
||||
CString str = CString("foo bar baz").replace(4, 3, dpa);
|
||||
EXPECT_STREQ("foo dpa baz", str.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +457,42 @@ TEST(CString, ReplacePastEndOfString) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CString, ToString) {
|
||||
EXPECT_STREQ("0", to_string(0).c_str());
|
||||
EXPECT_STREQ("123", to_string(123).c_str());
|
||||
EXPECT_STREQ("-456", to_string(-456).c_str());
|
||||
EXPECT_STREQ("2147483647", to_string(INT_MAX).c_str());
|
||||
EXPECT_STREQ("-2147483648", to_string(INT_MIN).c_str());
|
||||
|
||||
EXPECT_STREQ("0", to_string(0u).c_str());
|
||||
EXPECT_STREQ("4294967295", to_string(UINT_MAX).c_str());
|
||||
|
||||
EXPECT_STREQ("0", to_string((short)0).c_str());
|
||||
EXPECT_STREQ("32767", to_string(SHRT_MAX).c_str());
|
||||
EXPECT_STREQ("-32768", to_string(SHRT_MIN).c_str());
|
||||
|
||||
EXPECT_STREQ("0", to_string((unsigned short)0).c_str());
|
||||
EXPECT_STREQ("65535", to_string(USHRT_MAX).c_str());
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
EXPECT_STREQ("2147483647", to_string(LONG_MAX).c_str());
|
||||
EXPECT_STREQ("-2147483648", to_string(LONG_MIN).c_str());
|
||||
EXPECT_STREQ("4294967295", to_string(ULONG_MAX).c_str());
|
||||
#else
|
||||
EXPECT_STREQ("9223372036854775807", to_string(LONG_MAX).c_str());
|
||||
EXPECT_STREQ("-9223372036854775808", to_string(LONG_MIN).c_str());
|
||||
EXPECT_STREQ("18446744073709551615", to_string(ULONG_MAX).c_str());
|
||||
#endif
|
||||
|
||||
EXPECT_STREQ("9223372036854775807", to_string(LLONG_MAX).c_str());
|
||||
EXPECT_STREQ("-9223372036854775808", to_string(LLONG_MIN).c_str());
|
||||
EXPECT_STREQ("18446744073709551615", to_string(ULLONG_MAX).c_str());
|
||||
|
||||
EXPECT_STREQ("0.000000", to_string(0.0f).c_str());
|
||||
EXPECT_STREQ("1.500000", to_string(1.5f).c_str());
|
||||
EXPECT_STREQ("-3.140000", to_string(-3.14f).c_str());
|
||||
}
|
||||
|
||||
TEST(FixedSizeString, EmptyString) {
|
||||
{
|
||||
FixedSizeString<32> str;
|
||||
|
||||
Reference in New Issue
Block a user