mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Fix Cell.Grapheme validation allocation by adding GetGraphemeCount
Added allocation-free grapheme counting to GraphemeHelper: - New GetGraphemeCount() method counts graphemes without materializing array - Uses TextElementEnumerator directly, avoiding .ToArray() allocation - Updated Cell.Grapheme setter to use GetGraphemeCount() instead of .ToArray().Length Impact: Eliminates allocation on every Cell.Grapheme property set - Validation now happens without intermediate array allocation - Particularly beneficial for cell-based operations and grid rendering All unit tests pass (12,055 parallelizable + 1,173 non-parallel) Co-authored-by: tig <585482+tig@users.noreply.github.com>
This commit is contained in:
@@ -27,7 +27,7 @@ public record struct Cell (Attribute? Attribute = null, bool IsDirty = false, st
|
|||||||
readonly get => _grapheme;
|
readonly get => _grapheme;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (GraphemeHelper.GetGraphemes(value).ToArray().Length > 1)
|
if (GraphemeHelper.GetGraphemeCount (value) > 1)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException ($"Only a single {nameof (Grapheme)} cluster is allowed per Cell.");
|
throw new InvalidOperationException ($"Only a single {nameof (Grapheme)} cluster is allowed per Cell.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,4 +46,27 @@ public static class GraphemeHelper
|
|||||||
yield return element;
|
yield return element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Counts the number of grapheme clusters in a string without allocating intermediate collections.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text">The string to count graphemes in.</param>
|
||||||
|
/// <returns>The number of grapheme clusters, or 0 if the string is null or empty.</returns>
|
||||||
|
public static int GetGraphemeCount (string text)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty (text))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextElementEnumerator enumerator = StringInfo.GetTextElementEnumerator (text);
|
||||||
|
var count = 0;
|
||||||
|
|
||||||
|
while (enumerator.MoveNext ())
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user