diff --git a/include/Nazara/Core/StringExt.hpp b/include/Nazara/Core/StringExt.hpp index 0f52e5a73..3a13448f6 100644 --- a/include/Nazara/Core/StringExt.hpp +++ b/include/Nazara/Core/StringExt.hpp @@ -94,6 +94,9 @@ namespace Nz NAZARA_CORE_API std::string_view TrimLeft(std::string_view str, char32_t c, CaseIndependent, UnicodeAware); NAZARA_CORE_API std::string_view TrimLeft(std::string_view str, Unicode::Category category, UnicodeAware); + inline std::string_view TrimLeftCount(std::string_view str, std::size_t n); + NAZARA_CORE_API std::string_view TrimLeftCount(std::string_view str, std::size_t n, UnicodeAware); + NAZARA_CORE_API std::string_view TrimRight(std::string_view str); inline std::string_view TrimRight(std::string_view str, char c); inline std::string_view TrimRight(std::string_view str, char c, CaseIndependent); @@ -102,6 +105,10 @@ namespace Nz NAZARA_CORE_API std::string_view TrimRight(std::string_view str, char32_t c, UnicodeAware); NAZARA_CORE_API std::string_view TrimRight(std::string_view str, char32_t c, CaseIndependent, UnicodeAware); NAZARA_CORE_API std::string_view TrimRight(std::string_view str, Unicode::Category category, UnicodeAware); + + inline std::string_view TrimRightCount(std::string_view str, std::size_t n); + NAZARA_CORE_API std::string_view TrimRightCount(std::string_view str, std::size_t n, UnicodeAware); + } #include diff --git a/include/Nazara/Core/StringExt.inl b/include/Nazara/Core/StringExt.inl index f989411d7..0f734a1b5 100644 --- a/include/Nazara/Core/StringExt.inl +++ b/include/Nazara/Core/StringExt.inl @@ -301,6 +301,11 @@ namespace Nz return str; } + inline std::string_view TrimLeftCount(std::string_view str, std::size_t n) + { + return str.substr(std::min(n, str.size())); + } + inline std::string_view TrimRight(std::string_view str, char c) { while (!str.empty() && str.back() == c) @@ -326,6 +331,11 @@ namespace Nz return str; } + + inline std::string_view TrimRightCount(std::string_view str, std::size_t n) + { + return str.substr(0, (str.size() > n) ? str.size() - n : 0); + } } #include diff --git a/src/Nazara/Core/StringExt.cpp b/src/Nazara/Core/StringExt.cpp index 768a75efa..29013b953 100644 --- a/src/Nazara/Core/StringExt.cpp +++ b/src/Nazara/Core/StringExt.cpp @@ -645,6 +645,20 @@ namespace Nz return std::string_view(it.base(), end.base() - it.base()); } + std::string_view TrimLeftCount(std::string_view str, std::size_t n, UnicodeAware) + { + utf8::unchecked::iterator it(str.data()); + utf8::unchecked::iterator end(str.data() + str.size()); + + while (it != end && n > 0) + { + ++it; + --n; + } + + return std::string_view(it.base(), end.base() - it.base()); + } + std::string_view TrimRight(std::string_view str) { NAZARA_USE_ANONYMOUS_NAMESPACE @@ -742,4 +756,22 @@ namespace Nz return std::string_view(start.base(), it.base() - start.base()); } + + std::string_view TrimRightCount(std::string_view str, std::size_t n, UnicodeAware) + { + if (str.empty()) + return str; + + const char* begin = str.data(); + const char* ptr = begin + str.size(); + for (std::size_t i = 0; i < n; ++i) + { + if (ptr == begin) + return {}; + + utf8::prior(ptr, begin); + } + + return std::string_view(begin, ptr - begin); + } } diff --git a/tests/UnitTests/Engine/Core/StringExtTest.cpp b/tests/UnitTests/Engine/Core/StringExtTest.cpp index ce22437b0..e922cb05d 100644 --- a/tests/UnitTests/Engine/Core/StringExtTest.cpp +++ b/tests/UnitTests/Engine/Core/StringExtTest.cpp @@ -123,6 +123,42 @@ SCENARIO("String", "[CORE][STRING]") CHECK(Nz::Substring(str, 1, 10, Nz::UnicodeAware{}) == "\u00E9\u00E7\u0153\u00C2\u5B98"); } + WHEN("Trimming N characters by the left") + { + std::string_view str = "Nazara Engine"; + CHECK(Nz::TrimLeftCount(str, 0) == str); + CHECK(Nz::TrimLeftCount(str, 1) == "azara Engine"); + CHECK(Nz::TrimLeftCount(str, 7) == "Engine"); + CHECK(Nz::TrimLeftCount(str, 20) == ""); + } + + WHEN("Trimming N characters by the left - UTF-8 version") + { + std::string_view str = "\u00E0\u00E9\u00E7\u0153\u00C2\u5B98"; + CHECK(Nz::TrimLeftCount(str, 0, Nz::UnicodeAware{}) == str); + CHECK(Nz::TrimLeftCount(str, 1, Nz::UnicodeAware{}) == "\u00E9\u00E7\u0153\u00C2\u5B98"); + CHECK(Nz::TrimLeftCount(str, 5, Nz::UnicodeAware{}) == "\u5B98"); + CHECK(Nz::TrimLeftCount(str, 20, Nz::UnicodeAware{}) == ""); + } + + WHEN("Trimming N characters by the right") + { + std::string_view str = "Nazara Engine"; + CHECK(Nz::TrimRightCount(str, 0) == str); + CHECK(Nz::TrimRightCount(str, 1) == "Nazara Engin"); + CHECK(Nz::TrimRightCount(str, 7) == "Nazara"); + CHECK(Nz::TrimRightCount(str, 20) == ""); + } + + WHEN("Trimming N characters by the right - UTF-8 version") + { + std::string_view str = "\u00E0\u00E9\u00E7\u0153\u00C2\u5B98"; + CHECK(Nz::TrimRightCount(str, 0, Nz::UnicodeAware{}) == str); + CHECK(Nz::TrimRightCount(str, 1, Nz::UnicodeAware{}) == "\u00E0\u00E9\u00E7\u0153\u00C2"); + CHECK(Nz::TrimRightCount(str, 5, Nz::UnicodeAware{}) == "\u00E0"); + CHECK(Nz::TrimRightCount(str, 20, Nz::UnicodeAware{}) == ""); + } + WHEN("Checking if string starts with") { CHECK(Nz::StartsWith("Nazara Engine", ""));