From c26416c67f48ab7d81e6781c68163e663daf4c3d Mon Sep 17 00:00:00 2001 From: rameel Date: Thu, 11 Jul 2024 22:49:42 +0500 Subject: [PATCH 1/3] Add AccelerateBuildsInVisualStudio msbuild property --- Directory.Build.props | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 Directory.Build.props diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..ed14ea7 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,5 @@ + + + true + + From fa1c4a797ec1de719500d12c34b94fcfeccb43c0 Mon Sep 17 00:00:00 2001 From: rameel Date: Thu, 11 Jul 2024 22:57:14 +0500 Subject: [PATCH 2/3] Add `Trim` overload methods to `StringView` class --- .../Text/StringViewTests.cs | 107 +++++++ Ramstack.Structures/Text/StringView.cs | 266 ++++++++++++++++-- 2 files changed, 356 insertions(+), 17 deletions(-) diff --git a/Ramstack.Structures.Tests/Text/StringViewTests.cs b/Ramstack.Structures.Tests/Text/StringViewTests.cs index b10b5a1..e9d5232 100644 --- a/Ramstack.Structures.Tests/Text/StringViewTests.cs +++ b/Ramstack.Structures.Tests/Text/StringViewTests.cs @@ -60,6 +60,41 @@ public void TrimStart(string value, int index, int length) Is.EqualTo(value.AsSpan(index, length).TrimStart().ToString())); } + [TestCase("", '-')] + [TestCase("--------", '-')] + [TestCase("--++value", '-')] + [TestCase("--++value", '+')] + [TestCase(" value", '-')] + [TestCase(" value", ' ')] + [TestCase("value", '-')] + public void TrimStart_TrimChar(string value, char trimChar) + { + Assert.That( + value.AsView().TrimStart(trimChar).ToString(), + Is.EqualTo(value.TrimStart(trimChar))); + } + + [TestCase("", "-+")] + [TestCase("--++--++-", "-+")] + [TestCase("--++value", "-+")] + [TestCase("--++value", "?=")] + [TestCase(" value", "-+")] + [TestCase(" value", "-+")] + [TestCase(" value", "")] + [TestCase(" value", null)] + [TestCase("value", "+-")] + [TestCase("value", null)] + public void TrimStart_TrimChars(string value, string? trimChars) + { + Assert.That( + value.AsView().TrimStart(trimChars?.ToCharArray()).ToString(), + Is.EqualTo(value.TrimStart(trimChars?.ToCharArray()))); + + Assert.That( + value.AsView().TrimStart(trimChars.AsSpan()).ToString(), + Is.EqualTo(value.TrimStart(trimChars?.ToCharArray()))); + } + [TestCase("", 0, 0)] [TestCase(" ", 0, 4)] [TestCase(" ", 1, 3)] @@ -76,6 +111,42 @@ public void TrimEnd(string value, int index, int length) Is.EqualTo(value.AsSpan(index, length).TrimEnd().ToString())); } + [TestCase("", '-')] + [TestCase("---------", '-')] + [TestCase("value--++", '-')] + [TestCase("value--++", '-')] + [TestCase("value--++", '+')] + [TestCase("value ", '-')] + [TestCase("value ", ' ')] + [TestCase("value", '-')] + public void TrimEnd_TrimChar(string value, char trimChar) + { + Assert.That( + value.AsView().TrimEnd(trimChar).ToString(), + Is.EqualTo(value.TrimEnd(trimChar))); + } + + [TestCase("", "-+")] + [TestCase("++--++--+", "-+")] + [TestCase("value++--", "-+")] + [TestCase("value++--", "?=")] + [TestCase("value ", "-+")] + [TestCase("value ", "-+")] + [TestCase("value ", "")] + [TestCase("value ", null)] + [TestCase("value", "+-")] + [TestCase("value", null)] + public void TrimEnd_TrimChars(string value, string? trimChars) + { + Assert.That( + value.AsView().TrimEnd(trimChars?.ToCharArray()).ToString(), + Is.EqualTo(value.TrimEnd(trimChars?.ToCharArray()))); + + Assert.That( + value.AsView().TrimEnd(trimChars.AsSpan()).ToString(), + Is.EqualTo(value.TrimEnd(trimChars?.ToCharArray()))); + } + [TestCase("", 0, 0)] [TestCase(" ", 0, 4)] [TestCase(" ", 1, 3)] @@ -96,6 +167,42 @@ public void Trim(string value, int index, int length) Is.EqualTo(value.AsSpan(index, length).Trim().ToString())); } + [TestCase("", '-')] + [TestCase("---------", '-')] + [TestCase("++--value--++", '-')] + [TestCase("++--value--++", '-')] + [TestCase("++--value--++", '+')] + [TestCase(" value ", '-')] + [TestCase(" value ", ' ')] + [TestCase("value", '-')] + public void Trim_TrimChar(string value, char trimChar) + { + Assert.That( + value.AsView().Trim(trimChar).ToString(), + Is.EqualTo(value.Trim(trimChar))); + } + + [TestCase("", "-+")] + [TestCase("++--++--+", "-+")] + [TestCase("--++value++--", "-+")] + [TestCase("--++value++--", "?=")] + [TestCase(" value ", "-+")] + [TestCase(" value ", "-+")] + [TestCase(" value ", "")] + [TestCase(" value ", null)] + [TestCase("value", "+-")] + [TestCase("value", null)] + public void Trim_TrimChars(string value, string? trimChars) + { + Assert.That( + value.AsView().Trim(trimChars?.ToCharArray()).ToString(), + Is.EqualTo(value.Trim(trimChars?.ToCharArray()))); + + Assert.That( + value.AsView().Trim(trimChars.AsSpan()).ToString(), + Is.EqualTo(value.Trim(trimChars?.ToCharArray()))); + } + [TestCase("value", 0, 0)] [TestCase("value", 0, 5)] [TestCase("value", 1, 4)] diff --git a/Ramstack.Structures/Text/StringView.cs b/Ramstack.Structures/Text/StringView.cs index 184e38b..93a714c 100644 --- a/Ramstack.Structures/Text/StringView.cs +++ b/Ramstack.Structures/Text/StringView.cs @@ -238,61 +238,293 @@ public bool EndsWith(ReadOnlySpan value, StringComparison comparisonType = AsSpan().EndsWith(value, comparisonType); /// - /// Removes all the leading white-space characters from the current instance. + /// Removes all leading whitespace characters from the current instance. /// /// - /// The that remains after all white-space characters are removed from the start of the current instance. + /// The trimmed . /// public StringView TrimStart() { var start = _index; var final = _index + _length; + var value = _value; + + if (value != null) + for (; start < final; start++) + if (!char.IsWhiteSpace(value.GetRawStringData(start))) + break; + + return new StringView(value!, start, final - start, dummy: 0); + } + + /// + /// Removes all leading occurrences of a specified character from the current instance. + /// + /// The specified character to look for and remove. + /// + /// The trimmed . + /// + public StringView TrimStart(char trimChar) + { + var start = _index; + var final = _index + _length; + var value = _value; + + if (value != null) + for (; start < final; start++) + if (value.GetRawStringData(start) != trimChar) + break; + + return new StringView(value!, start, final - start, dummy: 0); + } + + /// + /// Removes all leading occurrences of a set of characters specified in an array from the current instance. + /// + /// + /// If is null or an empty array, whitespace characters are removed instead. + /// + /// An array which contains a set of characters to remove. + /// + /// The trimmed . + /// + public StringView TrimStart(params char[]? trimChars) => + TrimStart(trimChars.AsSpan()); + + /// + /// Removes all leading occurrences of a set of characters specified in a read-only span from the current instance. + /// + /// + /// If is empty, whitespace characters are removed instead. + /// + /// A read-only span which contains s set of characters to remove. + /// + /// The trimmed . + /// + public StringView TrimStart(ReadOnlySpan trimChars) + { + if (trimChars.Length == 0) + return TrimStart(); + + var start = _index; + var final = _index + _length; + var value = _value; + + if (value != null) + { + for (; start < final; start++) + { + for (var i = 0; i < trimChars.Length; i++) + if (value.GetRawStringData(start) == trimChars[i]) + goto MATCHED; - for (; start < final; start++) - if (!char.IsWhiteSpace(_value!.GetRawStringData(start))) break; + MATCHED: ; + } + } - return new StringView(_value!, start, final - start, dummy: 0); + return new StringView(value!, start, final - start, dummy: 0); } /// - /// Removes all the trailing white-space characters from the current instance. + /// Removes all trailing whitespace characters from the current instance. /// /// - /// The that remains after all white-space characters are removed from the end of the current instance. + /// The trimmed . /// public StringView TrimEnd() { var start = _index; var final = _index + _length - 1; + var value = _value; + + if (value != null) + for (; final >= start; final--) + if (!char.IsWhiteSpace(value.GetRawStringData(final))) + break; + + return new StringView(value!, start, final + 1 - start, dummy: 0); + } + + /// + /// Removes all trailing occurrences of a specified character from the current instance. + /// + /// The specified character to look for and remove. + /// + /// The trimmed . + /// + public StringView TrimEnd(char trimChar) + { + var start = _index; + var final = _index + _length - 1; + var value = _value; + + if (value != null) + for (; final >= start; final--) + if (value.GetRawStringData(final) != trimChar) + break; + + return new StringView(value!, start, final + 1 - start, dummy: 0); + } + + /// + /// Removes all trailing occurrences of a set of characters specified in an array from the current instance. + /// + /// + /// If is null or an empty array, whitespace characters are removed instead. + /// + /// An array which contains a set of characters to remove. + /// + /// The trimmed . + /// + public StringView TrimEnd(params char[]? trimChars) => + TrimEnd(trimChars.AsSpan()); + + /// + /// Removes all leading occurrences of a set of characters specified in a read-only span from the current instance. + /// + /// + /// If is empty, whitespace characters are removed instead. + /// + /// A read-only span which contains a set of characters to remove. + /// + /// The trimmed . + /// + public StringView TrimEnd(ReadOnlySpan trimChars) + { + if (trimChars.Length == 0) + return TrimEnd(); + + var start = _index; + var final = _index + _length - 1; + var value = _value; + + if (value != null) + { + for (; final >= start; final--) + { + for (var i = 0; i < trimChars.Length; i++) + if (value.GetRawStringData(final) == trimChars[i]) + goto MATCHED; - for (; final >= start; final--) - if (!char.IsWhiteSpace(_value!.GetRawStringData(final))) break; + MATCHED: ; + } + } - return new StringView(_value!, start, final + 1 - start, dummy: 0); + return new StringView(value!, start, final + 1 - start, dummy: 0); } /// - /// Removes all leading and trailing white-space characters from the current instance. + /// Removes all leading and trailing whitespace characters from the current instance. /// /// - /// The that remains after all white-space characters are removed from the start and end of the current instance. + /// The trimmed . /// public StringView Trim() { var start = _index; var final = _index + _length - 1; + var value = _value; + + if (value != null) + { + for (; start <= final; start++) + if (!char.IsWhiteSpace(value.GetRawStringData(start))) + break; + + for (; final > start; final--) + if (!char.IsWhiteSpace(value.GetRawStringData(final))) + break; + } + + return new StringView(value!, start, final + 1 - start, dummy: 0); + } + + /// + /// Removes all leading and trailing occurrences of a specified character from the current instance. + /// + /// The specified character to look for and remove. + /// + /// The trimmed . + /// + public StringView Trim(char trimChar) + { + var start = _index; + var final = _index + _length - 1; + var value = _value; + + if (value != null) + { + for (; start <= final; start++) + if (value.GetRawStringData(start) != trimChar) + break; + + for (; final > start; final--) + if (value.GetRawStringData(final) != trimChar) + break; + } + + return new StringView(value!, start, final + 1 - start, dummy: 0); + } + + /// + /// Removes all leading and trailing occurrences of a set of characters specified in an array from the current instance. + /// + /// + /// If is null or an empty array, whitespace characters are removed instead. + /// + /// An array which contains a set of characters to remove. + /// + /// The trimmed . + /// + public StringView Trim(params char[]? trimChars) => + Trim(trimChars.AsSpan()); + + /// + /// Removes all leading and trailing occurrences of a set of characters specified in a read-only span from the current instance. + /// + /// + /// If is empty, whitespace characters are removed instead. + /// + /// A read-only span which contains a set of characters to remove. + /// + /// The trimmed . + /// + public StringView Trim(ReadOnlySpan trimChars) + { + if (trimChars.Length == 0) + return Trim(); + + var start = _index; + var final = _index + _length - 1; + var value = _value; + + if (value != null) + { + for (; start <= final; start++) + { + + for (var i = 0; i < trimChars.Length; i++) + if (value.GetRawStringData(start) == trimChars[i]) + goto MATCHED; - for (; start <= final; start++) - if (!char.IsWhiteSpace(_value!.GetRawStringData(start))) break; + MATCHED: ; + } + + for (; final > start; final--) + { + for (var i = 0; i < trimChars.Length; i++) + if (value.GetRawStringData(final) == trimChars[i]) + goto MATCHED; - for (; start <= final; final--) - if (!char.IsWhiteSpace(_value!.GetRawStringData(final))) break; + MATCHED: ; + } + } - return new StringView(_value!, start, final + 1 - start, dummy: 0); + return new StringView(value!, start, final + 1 - start, dummy: 0); } /// From 1d482426fc47661677172a8773c3d98a62bbd438 Mon Sep 17 00:00:00 2001 From: rameel Date: Thu, 11 Jul 2024 23:34:44 +0500 Subject: [PATCH 3/3] Update README --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index f961945..e499e10 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Ramstack.Structures is a .NET library providing various data structures and utilities. +[![.NET](https://github.com/rameel/ramstack.structures/actions/workflows/test.yml/badge.svg)](https://github.com/rameel/ramstack.structures/actions/workflows/test.yml) + ## Installation To install the `Ramstack.Structures` [NuGet package](https://www.nuget.org/packages/Ramstack.Structures) to your project, use the following command: @@ -43,6 +45,16 @@ foreach (ref readonly HeavyStruct s in view) ... } ``` +## Changelog + +### 1.2.0 +- Add `Trim` overloads to `StringView` class + +## Supported versions + +| | Version | +|------|---------| +| .NET | 6, 7, 8 | ## Contributions