mirror of
https://github.com/AlexMacocian/SystemExtensions.git
synced 2026-07-16 06:29:29 +00:00
Blittable strings generator implementation
Improvements to fixed array generator
This commit is contained in:
@@ -56,7 +56,7 @@ public class FixedArrayGenerator : IIncrementalGenerator
|
||||
compilation.Assembly.GetAttributes().Where(a => a.AttributeClass != null &&
|
||||
(a.AttributeClass.Name == AttributeName || a.AttributeClass.Name == AttributeShortName));
|
||||
|
||||
foreach(var attr in assemblyAttributes)
|
||||
foreach (var attr in assemblyAttributes)
|
||||
{
|
||||
// Extract the type argument (T) from GenerateFixedArrayAttribute<T>
|
||||
var namedTypeSymbol = attr.AttributeClass as INamedTypeSymbol;
|
||||
@@ -96,47 +96,69 @@ public class FixedArrayGenerator : IIncrementalGenerator
|
||||
builder.AppendLine($"using {UsingSystem};");
|
||||
builder.AppendLine($"using {UsingSystemRuntimeInterop};");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine($"namespace {AttributeNamespace}");
|
||||
builder.AppendLine($"namespace {AttributeNamespace};");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("[StructLayout(LayoutKind.Sequential, Pack = 1)]");
|
||||
builder.AppendLine($"public unsafe struct {structName}");
|
||||
builder.AppendLine("{");
|
||||
builder.AppendLine(" [StructLayout(LayoutKind.Sequential, Pack = 1)]");
|
||||
builder.AppendLine($" public unsafe struct {structName}");
|
||||
builder.AppendLine($" private const int Size = {size};");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine($" private fixed {targetType} elements[Size];");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine(" public int Length => Size;");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine($" public ref {targetType} this[int index]");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine($" private const int Size = {size};");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine($" private fixed {targetType} elements[Size];");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine(" public int Length => Size;");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine($" public ref {targetType} this[int index]");
|
||||
builder.AppendLine(" get");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine(" get");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine(" if (index >= Size) throw new IndexOutOfRangeException();");
|
||||
builder.AppendLine($" fixed ({targetType}* ptr = this.elements)");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine(" return ref ptr[index];");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine(" if ((uint)index >= Size) throw new IndexOutOfRangeException();");
|
||||
builder.AppendLine($" return ref this.elements[index];");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine($" public Span<{targetType}> AsSpan()");
|
||||
builder.AppendLine($" public Span<{targetType}> AsSpan()");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine($" fixed ({targetType}* ptr = this.elements)");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine($" fixed ({targetType}* ptr = this.elements)");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine($" return new Span<{targetType}>(ptr, Size);");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine($" return MemoryMarshal.CreateSpan(ref *ptr, Size);");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine($" public static {structName} From{capitalizedType}Array({targetType}[] array)");
|
||||
builder.AppendLine($" public readonly ReadOnlySpan<{targetType}> AsReadOnlySpan()");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine($" fixed ({targetType}* ptr = this.elements)");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine($" var arr = default({structName});");
|
||||
builder.AppendLine(" array.AsSpan().CopyTo(arr.AsSpan());");
|
||||
builder.AppendLine(" return arr;");
|
||||
builder.AppendLine($" return new ReadOnlySpan<{targetType}>(ptr, Size);");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine($" public void Set(ReadOnlySpan<{targetType}> value)");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine($" fixed ({targetType}* ptr = this.elements)");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine($" var span = MemoryMarshal.CreateSpan(ref *ptr, Size);");
|
||||
builder.AppendLine(" span.Clear();");
|
||||
builder.AppendLine(" value[..Math.Min(value.Length, Size)].CopyTo(span);");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine($" public void Clear()");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine($" fixed ({targetType}* ptr = this.elements)");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine($" MemoryMarshal.CreateSpan(ref *ptr, Size).Clear();");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine();
|
||||
builder.AppendLine($" public static {structName} From{capitalizedType}Array({targetType}[] array)");
|
||||
builder.AppendLine(" {");
|
||||
builder.AppendLine($" var arr = default({structName});");
|
||||
builder.AppendLine(" arr.Set(array);");
|
||||
builder.AppendLine(" return arr;");
|
||||
builder.AppendLine(" }");
|
||||
builder.AppendLine("}");
|
||||
|
||||
sourceProductionContext.AddSource($"{structName}.g.cs", builder.ToString());
|
||||
}
|
||||
}
|
||||
#nullable disable
|
||||
#nullable disable
|
||||
Reference in New Issue
Block a user