From b6d74ea4f7343beb6d6757ca382489ea58133b9b Mon Sep 17 00:00:00 2001 From: Metehan Tuncbilek Date: Thu, 17 Oct 2024 16:00:38 +0300 Subject: [PATCH] fix string according to reviews --- openVulkanoCpp/Data/Containers/String.hpp | 89 ++++++++++++--------- tests/StringTest.cpp | 94 ++++++++++++++++++++++- 2 files changed, 143 insertions(+), 40 deletions(-) diff --git a/openVulkanoCpp/Data/Containers/String.hpp b/openVulkanoCpp/Data/Containers/String.hpp index 2648712..c6e6f03 100644 --- a/openVulkanoCpp/Data/Containers/String.hpp +++ b/openVulkanoCpp/Data/Containers/String.hpp @@ -61,13 +61,20 @@ namespace OpenVulkano template String operator+(const T& other) const { return m_string + other; } String operator+(const String& other) const { return m_string + other.m_string; } +#if defined(_HAS_CXX20) + template int operator<=>(const T& other) const { return m_string <=> other; } +#endif + template bool operator==(const T& other) const { return m_string == other; } template 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; } 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]; } + char& At(size_t index) { 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* Data() { return m_string.data(); } @@ -81,67 +88,77 @@ namespace OpenVulkano char& Back() { return m_string.back(); } void PopBack() { m_string.pop_back(); } void Clear() { m_string.clear(); } - void Shrink() { m_string.shrink_to_fit(); } - String SubString(size_t start, size_t end) const { return m_string.substr(start, end); } - bool StartsWith(const String& 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 Contains(const String& str) const { return m_string.find(str) != std::string::npos; } + void ShrinkToFit() { m_string.shrink_to_fit(); } + String SubString(size_t start, size_t elementCount) const { return m_string.substr(start, elementCount); } + bool StartsWith(const std::string_view& str) const { return m_string.find(str) == 0; } + bool EndsWith(const std::string_view& str) const { return m_string.rfind(str) == m_string.size() - str.size(); } + 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 FindEndIndexOf(const String& str) const { return m_string.rfind(str); } + size_t FindStartIndexOf(const std::string_view& str) const { return m_string.find(str); } + size_t FindEndIndexOf(const std::string_view& str) const { return m_string.rfind(str); } String& Trim() noexcept { - size_t start = m_string.find_first_not_of(" \t\n"); - size_t end = m_string.find_last_not_of(" \t\n"); - m_string = m_string.substr(start, end - start + 1); + size_t start = m_string.find_first_not_of(" \t\n\r"); + if (start == std::string::npos) + { + 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; } - String& TrimFront() + String& TrimFront() noexcept { - size_t start = m_string.find_first_not_of(" \t\n"); - m_string = m_string.substr(start); + size_t start = m_string.find_first_not_of(" \t\n\r"); + if (start == std::string::npos) + { + m_string.clear(); + } + else + { + m_string.erase(0, start); + } return *this; } - String& TrimBack() + String& TrimBack() noexcept { - size_t end = m_string.find_last_not_of(" \t\n"); - m_string = m_string.substr(0, end + 1); + size_t end = m_string.find_last_not_of(" \t\n\r"); + if (end == std::string::npos) + { + m_string.clear(); + } + else + { + m_string.resize(end + 1); + } return *this; } void ToUpper() noexcept { - for (char& c: m_string) - { - if (c >= 'a' && c <= 'z') - { - c -= 32; - } - } + std::transform(m_string.begin(), m_string.end(), m_string.begin(), + [](unsigned char c) { return std::toupper(c); }); } void ToLower() noexcept { - for (char& c: m_string) - { - if (c >= 'A' && c <= 'Z') - { - c += 32; - } - } + std::transform(m_string.begin(), m_string.end(), m_string.begin(), + [](unsigned char c) { return std::tolower(c); }); } - 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[i + 1] -= 32; - } + m_string[0] = std::toupper(m_string[0]); } } diff --git a/tests/StringTest.cpp b/tests/StringTest.cpp index 7f26a87..5b700d0 100644 --- a/tests/StringTest.cpp +++ b/tests/StringTest.cpp @@ -117,10 +117,6 @@ TEST_CASE("String") String str2("Hello World"); str2.ToLower(); 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") @@ -138,4 +134,94 @@ TEST_CASE("String") String str2("42.42"); REQUIRE(str2.FromString() == 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 + } } \ No newline at end of file