RSCG – LinqGen.Generator
No-alloc for Linq operations
This is how you can use LinqGen.Generator .
The code that you start with is
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="LinqGen" Version="0.3.1" />
<PackageReference Include="LinqGen.Generator" Version="0.3.1" />
</ItemGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
</Project>
The code that you will use is
using Cathei.LinqGen;
int[] a= [1,2,3];
var s = a
.Select(x => x * x)
.Where(it => it < 8)
.Sum()
;
var result = a.Gen()
.Select(x => x * x)
.Where(it => it < 8)
.Sum();
Console.WriteLine(s == result);
The code that is generated is
// DO NOT EDIT
// Generated by LinqGen.Generator
#nullable disable
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Cathei.LinqGen;
using Cathei.LinqGen.Hidden;
namespace Cathei.LinqGen.Hidden
{
// Non-exported Enumerable should consider anonymous type, thus it will be internal
internal struct Gen_wRtaM3 : IInternalStub<int>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Gen_wRtaM3(int[] source_wRtaM3) : this()
{
this.source_wRtaM3 = source_wRtaM3;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Count() => this.source_wRtaM3.Length;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Select_6q5z23 Select(Func<int, int> selector_6q5z23) => new Select_6q5z23(this, selector_6q5z23);
[EditorBrowsable(EditorBrowsableState.Never)]
internal int[] source_wRtaM3;
}
}
namespace Cathei.LinqGen
{
// Extension class needs to be internal to prevent ambiguous resolution
internal static partial class LinqGenExtensions_Gen_wRtaM3
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Gen_wRtaM3 Gen(this int[] source_wRtaM3) => new Gen_wRtaM3(source_wRtaM3);
}
}
// DO NOT EDIT
// Generated by LinqGen.Generator
#nullable disable
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Cathei.LinqGen;
using Cathei.LinqGen.Hidden;
namespace Cathei.LinqGen.Hidden
{
// Non-exported Enumerable should consider anonymous type, thus it will be internal
internal struct Select_6q5z23 : IInternalStub<int>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Select_6q5z23(in Gen_wRtaM3 source, Func<int, int> selector_6q5z23) : this()
{
this.source_wRtaM3 = source.source_wRtaM3;
this.selector_6q5z23 = selector_6q5z23;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Count() => this.source_wRtaM3.Length;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Where_kc5pa1 Where(Func<int, bool> predicate_kc5pa1) => new Where_kc5pa1(this, predicate_kc5pa1);
[EditorBrowsable(EditorBrowsableState.Never)]
internal int[] source_wRtaM3;
[EditorBrowsable(EditorBrowsableState.Never)]
internal Func<int, int> selector_6q5z23;
}
}
namespace Cathei.LinqGen
{
}
// DO NOT EDIT
// Generated by LinqGen.Generator
#nullable disable
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Cathei.LinqGen;
using Cathei.LinqGen.Hidden;
namespace Cathei.LinqGen.Hidden
{
// Non-exported Enumerable should consider anonymous type, thus it will be internal
internal struct Select_KZ5014 : IInternalStub<int>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Select_KZ5014(in Where_04jjO source, Func<int, int> selector_KZ5014) : this()
{
this.source_wRtaM3 = source.source_wRtaM3;
this.predicate_04jjO = source.predicate_04jjO;
this.selector_KZ5014 = selector_KZ5014;
}
[EditorBrowsable(EditorBrowsableState.Never)]
internal int[] source_wRtaM3;
[EditorBrowsable(EditorBrowsableState.Never)]
internal Func<int, bool> predicate_04jjO;
[EditorBrowsable(EditorBrowsableState.Never)]
internal Func<int, int> selector_KZ5014;
}
}
namespace Cathei.LinqGen
{
// Extension class needs to be internal to prevent ambiguous resolution
internal static partial class LinqGenExtensions_Select_KZ5014
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Sum(this Select_KZ5014 source)
{
int index_wRtaM3 = default;
index_wRtaM3 = -1;
int result_5a0zT4 = default;
while (true)
{
if ((uint)++index_wRtaM3 >= (uint)source.source_wRtaM3.Length)
break;
var current_wRtaM3 = source.source_wRtaM3[index_wRtaM3];
if (!source.predicate_04jjO.Invoke(current_wRtaM3))
continue;
var current_KZ5014 = source.selector_KZ5014.Invoke(current_wRtaM3);
result_5a0zT4 += current_KZ5014;
}
return result_5a0zT4;
}
}
}
// DO NOT EDIT
// Generated by LinqGen.Generator
#nullable disable
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Cathei.LinqGen;
using Cathei.LinqGen.Hidden;
namespace Cathei.LinqGen.Hidden
{
// Non-exported Enumerable should consider anonymous type, thus it will be internal
internal struct Where_kc5pa1 : IInternalStub<int>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Where_kc5pa1(in Select_6q5z23 source, Func<int, bool> predicate_kc5pa1) : this()
{
this.source_wRtaM3 = source.source_wRtaM3;
this.selector_6q5z23 = source.selector_6q5z23;
this.predicate_kc5pa1 = predicate_kc5pa1;
}
[EditorBrowsable(EditorBrowsableState.Never)]
internal int[] source_wRtaM3;
[EditorBrowsable(EditorBrowsableState.Never)]
internal Func<int, int> selector_6q5z23;
[EditorBrowsable(EditorBrowsableState.Never)]
internal Func<int, bool> predicate_kc5pa1;
}
}
namespace Cathei.LinqGen
{
// Extension class needs to be internal to prevent ambiguous resolution
internal static partial class LinqGenExtensions_Where_kc5pa1
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Sum(this Where_kc5pa1 source)
{
int index_wRtaM3 = default;
index_wRtaM3 = -1;
int result_x5AfL3 = default;
while (true)
{
if ((uint)++index_wRtaM3 >= (uint)source.source_wRtaM3.Length)
break;
var current_wRtaM3 = source.source_wRtaM3[index_wRtaM3];
var current_6q5z23 = source.selector_6q5z23.Invoke(current_wRtaM3);
if (!source.predicate_kc5pa1.Invoke(current_6q5z23))
continue;
result_x5AfL3 += current_6q5z23;
}
return result_x5AfL3;
}
}
}
// DO NOT EDIT
// Generated by LinqGen.Generator
#nullable disable
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Cathei.LinqGen;
using Cathei.LinqGen.Hidden;
namespace Cathei.LinqGen.Hidden
{
// Non-exported Enumerable should consider anonymous type, thus it will be internal
internal struct Where_04jjO : IInternalStub<int>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Where_04jjO(in Gen_wRtaM3 source, Func<int, bool> predicate_04jjO) : this()
{
this.source_wRtaM3 = source.source_wRtaM3;
this.predicate_04jjO = predicate_04jjO;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Select_KZ5014 Select(Func<int, int> selector_KZ5014) => new Select_KZ5014(this, selector_KZ5014);
[EditorBrowsable(EditorBrowsableState.Never)]
internal int[] source_wRtaM3;
[EditorBrowsable(EditorBrowsableState.Never)]
internal Func<int, bool> predicate_04jjO;
}
}
namespace Cathei.LinqGen
{
}
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/LinqGen.Generator