fix string according to reviews
This commit is contained in:
@@ -61,13 +61,20 @@ namespace OpenVulkano
|
|||||||
template<typename T> String operator+(const T& other) const { return m_string + other; }
|
template<typename T> String operator+(const T& other) const { return m_string + other; }
|
||||||
String operator+(const String& other) const { return m_string + other.m_string; }
|
String operator+(const String& other) const { return m_string + other.m_string; }
|
||||||
|
|
||||||
|
#if defined(_HAS_CXX20)
|
||||||
|
template<typename T> int operator<=>(const T& other) const { return m_string <=> other; }
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename T> bool operator==(const T& other) const { return m_string == other; }
|
template<typename T> bool operator==(const T& other) const { return m_string == other; }
|
||||||
template<typename T> bool operator!=(const T& other) const { return m_string != other; }
|
template<typename T> bool operator!=(const T& other) const { return m_string != other; }
|
||||||
|
explicit operator bool() const { return !m_string.empty(); }
|
||||||
|
|
||||||
operator std::string() const { return m_string; }
|
operator std::string() const { return m_string; }
|
||||||
explicit operator std::string_view() const { return m_string; }
|
explicit operator std::string_view() const { return m_string; }
|
||||||
|
|
||||||
|
char& operator[](size_t index) noexcept { return m_string[index]; }
|
||||||
const char& operator[](size_t index) const noexcept { return m_string[index]; }
|
const char& operator[](size_t index) const noexcept { return m_string[index]; }
|
||||||
|
char& At(size_t index) { return m_string.at(index); }
|
||||||
const char& At(size_t index) const { return m_string.at(index); }
|
const char& At(size_t index) const { return m_string.at(index); }
|
||||||
const char* CharString() const { return m_string.c_str(); }
|
const char* CharString() const { return m_string.c_str(); }
|
||||||
const char* Data() { return m_string.data(); }
|
const char* Data() { return m_string.data(); }
|
||||||
@@ -81,67 +88,77 @@ namespace OpenVulkano
|
|||||||
char& Back() { return m_string.back(); }
|
char& Back() { return m_string.back(); }
|
||||||
void PopBack() { m_string.pop_back(); }
|
void PopBack() { m_string.pop_back(); }
|
||||||
void Clear() { m_string.clear(); }
|
void Clear() { m_string.clear(); }
|
||||||
void Shrink() { m_string.shrink_to_fit(); }
|
void ShrinkToFit() { m_string.shrink_to_fit(); }
|
||||||
String SubString(size_t start, size_t end) const { return m_string.substr(start, end); }
|
String SubString(size_t start, size_t elementCount) const { return m_string.substr(start, elementCount); }
|
||||||
bool StartsWith(const String& str) const { return m_string.find(str) == 0; }
|
bool StartsWith(const std::string_view& str) const { return m_string.find(str) == 0; }
|
||||||
bool EndsWith(const String& str) const { return m_string.rfind(str) == m_string.size() - str.Size(); }
|
bool EndsWith(const std::string_view& str) const { return m_string.rfind(str) == m_string.size() - str.size(); }
|
||||||
bool Contains(const String& str) const { return m_string.find(str) != std::string::npos; }
|
bool Contains(const std::string_view& str) const { return m_string.find(str) != std::string::npos; }
|
||||||
|
|
||||||
size_t FindStartIndexOf(const String& str) const { return m_string.find(str); }
|
size_t FindStartIndexOf(const std::string_view& str) const { return m_string.find(str); }
|
||||||
size_t FindEndIndexOf(const String& str) const { return m_string.rfind(str); }
|
size_t FindEndIndexOf(const std::string_view& str) const { return m_string.rfind(str); }
|
||||||
|
|
||||||
String& Trim() noexcept
|
String& Trim() noexcept
|
||||||
{
|
{
|
||||||
size_t start = m_string.find_first_not_of(" \t\n");
|
size_t start = m_string.find_first_not_of(" \t\n\r");
|
||||||
size_t end = m_string.find_last_not_of(" \t\n");
|
if (start == std::string::npos)
|
||||||
m_string = m_string.substr(start, end - start + 1);
|
{
|
||||||
|
m_string.clear();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t end = m_string.find_last_not_of(" \t\n\r");
|
||||||
|
|
||||||
|
m_string.erase(0, start);
|
||||||
|
m_string.resize(end - start + 1);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
String& TrimFront()
|
String& TrimFront() noexcept
|
||||||
{
|
{
|
||||||
size_t start = m_string.find_first_not_of(" \t\n");
|
size_t start = m_string.find_first_not_of(" \t\n\r");
|
||||||
m_string = m_string.substr(start);
|
if (start == std::string::npos)
|
||||||
|
{
|
||||||
|
m_string.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_string.erase(0, start);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
String& TrimBack()
|
String& TrimBack() noexcept
|
||||||
{
|
{
|
||||||
size_t end = m_string.find_last_not_of(" \t\n");
|
size_t end = m_string.find_last_not_of(" \t\n\r");
|
||||||
m_string = m_string.substr(0, end + 1);
|
if (end == std::string::npos)
|
||||||
|
{
|
||||||
|
m_string.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_string.resize(end + 1);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToUpper() noexcept
|
void ToUpper() noexcept
|
||||||
{
|
{
|
||||||
for (char& c: m_string)
|
std::transform(m_string.begin(), m_string.end(), m_string.begin(),
|
||||||
{
|
[](unsigned char c) { return std::toupper(c); });
|
||||||
if (c >= 'a' && c <= 'z')
|
|
||||||
{
|
|
||||||
c -= 32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToLower() noexcept
|
void ToLower() noexcept
|
||||||
{
|
{
|
||||||
for (char& c: m_string)
|
std::transform(m_string.begin(), m_string.end(), m_string.begin(),
|
||||||
{
|
[](unsigned char c) { return std::tolower(c); });
|
||||||
if (c >= 'A' && c <= 'Z')
|
|
||||||
{
|
|
||||||
c += 32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FirstLettersUpper()
|
void Capitalize() noexcept
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < m_string.size(); ++i)
|
if (!m_string.empty())
|
||||||
{
|
{
|
||||||
if (m_string[i] == ' ')
|
m_string[0] = std::toupper(m_string[0]);
|
||||||
{
|
|
||||||
m_string[i + 1] -= 32;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,10 +117,6 @@ TEST_CASE("String")
|
|||||||
String str2("Hello World");
|
String str2("Hello World");
|
||||||
str2.ToLower();
|
str2.ToLower();
|
||||||
REQUIRE(str2 == "hello world");
|
REQUIRE(str2 == "hello world");
|
||||||
|
|
||||||
String str3("Georg will save us all from our doom");
|
|
||||||
str3.FirstLettersUpper();
|
|
||||||
REQUIRE(str3 == "Georg Will Save Us All From Our Doom");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Substring")
|
SECTION("Substring")
|
||||||
@@ -138,4 +134,94 @@ TEST_CASE("String")
|
|||||||
String str2("42.42");
|
String str2("42.42");
|
||||||
REQUIRE(str2.FromString<float>() == 42.42f);
|
REQUIRE(str2.FromString<float>() == 42.42f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("StartsWith")
|
||||||
|
{
|
||||||
|
String str1("Hello World");
|
||||||
|
REQUIRE(str1.StartsWith("Hello"));
|
||||||
|
REQUIRE(!str1.StartsWith("World"));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("EndsWith")
|
||||||
|
{
|
||||||
|
String str1("Hello World");
|
||||||
|
REQUIRE(str1.EndsWith("World"));
|
||||||
|
REQUIRE(!str1.EndsWith("Hello"));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Contains")
|
||||||
|
{
|
||||||
|
String str1("Hello World");
|
||||||
|
REQUIRE(str1.Contains("Hello"));
|
||||||
|
REQUIRE(str1.Contains("World"));
|
||||||
|
REQUIRE(!str1.Contains("Georg"));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("FindEndIndexOf")
|
||||||
|
{
|
||||||
|
String str1("Georg will save us all from our doom");
|
||||||
|
REQUIRE(str1.FindEndIndexOf("save") == 11);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("TrimFront")
|
||||||
|
{
|
||||||
|
String str1(" Hello World");
|
||||||
|
REQUIRE(str1.TrimFront() == "Hello World");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("TrimBack")
|
||||||
|
{
|
||||||
|
String str1("Hello World ");
|
||||||
|
REQUIRE(str1.TrimBack() == "Hello World");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Empty")
|
||||||
|
{
|
||||||
|
String str1;
|
||||||
|
REQUIRE(str1.Empty());
|
||||||
|
REQUIRE(!str1);
|
||||||
|
|
||||||
|
String str2("Hello World");
|
||||||
|
REQUIRE(!str2.Empty());
|
||||||
|
REQUIRE(!!str2);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Size")
|
||||||
|
{
|
||||||
|
String str1("Hello World");
|
||||||
|
REQUIRE(str1.Size() == 11);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Capacity")
|
||||||
|
{
|
||||||
|
String str1("Hello World");
|
||||||
|
REQUIRE(str1.Capacity() >= 11);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("CharCount")
|
||||||
|
{
|
||||||
|
String str1("Hello World");
|
||||||
|
REQUIRE(str1.CharCount() == 11);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("PopBack")
|
||||||
|
{
|
||||||
|
String str1("Hello World");
|
||||||
|
str1.PopBack();
|
||||||
|
REQUIRE(str1 == "Hello Worl");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Clear")
|
||||||
|
{
|
||||||
|
String str1("Hello World");
|
||||||
|
str1.Clear();
|
||||||
|
REQUIRE(str1.Empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("ShrinkToFit")
|
||||||
|
{
|
||||||
|
String str1("Hello World");
|
||||||
|
str1.ShrinkToFit();
|
||||||
|
REQUIRE(str1.Capacity() == 15); // 11 + 4 null terminators due to sso
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user