diff --git a/Directory.Build.props b/Directory.Build.props index ce2d72bbe..524dd9410 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -3,10 +3,11 @@ Antao Almada - Copyright 2019-2021 Antao Almada + Copyright 2019-2023 Antao Almada latest strict enable + enable diff --git a/NetFabric.Hyperlinq.Abstractions/ActionWrapper.cs b/NetFabric.Hyperlinq.Abstractions/ActionWrapper.cs new file mode 100644 index 000000000..9d9851463 --- /dev/null +++ b/NetFabric.Hyperlinq.Abstractions/ActionWrapper.cs @@ -0,0 +1,267 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace NetFabric.Hyperlinq; + +/// +/// Represents a read-only struct that wraps an delegate +/// and implements the interface to provide a way to invoke the action. +/// +/// The type of the argument to be passed to the action when invoked. +/// +/// Initializes a new instance of the struct with the specified action. +/// +/// The delegate to be wrapped. +/// Thrown if is null. +[StructLayout(LayoutKind.Auto)] +public readonly struct ActionWrapper(Action action) + : IAction +{ + readonly Action action + = action ?? Throw.ArgumentNullException>(nameof(action)); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IAction.Invoke(ref readonly T arg) + => action(arg); + + public static implicit operator ActionWrapper(Action action) + => new(action); +} + +/// +/// Represents a read-only struct that wraps an delegate +/// and implements the interface to provide a way to invoke the action. +/// +/// The type of the first argument to be passed to the action when invoked. +/// The type of the second argument to be passed to the action when invoked. +/// +/// Initializes a new instance of the struct with the specified action. +/// +/// The delegate to be wrapped. +/// Thrown if is null. +[StructLayout(LayoutKind.Auto)] +public readonly struct ActionWrapper(Action action) + : IAction +{ + readonly Action action + = action ?? Throw.ArgumentNullException>(nameof(action)); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IAction.Invoke(ref readonly T1 arg1, ref readonly T2 arg2) + => action(arg1, arg2); + + public static implicit operator ActionWrapper(Action action) + => new(action); +} + +/// +/// Represents a read-only struct that wraps an delegate +/// and implements the interface to provide a way to invoke the action. +/// +/// The type of the first argument to be passed to the action when invoked. +/// The type of the second argument to be passed to the action when invoked. +/// The type of the third argument to be passed to the action when invoked. +/// +/// Initializes a new instance of the struct with the specified action. +/// +/// The delegate to be wrapped. +/// Thrown if is null. +[StructLayout(LayoutKind.Auto)] +public readonly struct ActionWrapper(Action action) + : IAction +{ + readonly Action action + = action ?? Throw.ArgumentNullException>(nameof(action)); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IAction.Invoke(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3) + => action(arg1, arg2, arg3); + + public static implicit operator ActionWrapper(Action action) + => new(action); +} + +/// +/// Represents a read-only struct that wraps an delegate +/// and implements the interface to provide a way to invoke the action. +/// +/// The type of the first argument to be passed to the action when invoked. +/// The type of the second argument to be passed to the action when invoked. +/// The type of the third argument to be passed to the action when invoked. +/// The type of the fourth argument to be passed to the action when invoked. +/// +/// Initializes a new instance of the struct with the specified action. +/// +/// The delegate to be wrapped. +/// Thrown if is null. +[StructLayout(LayoutKind.Auto)] +public readonly struct ActionWrapper(Action action) + : IAction +{ + readonly Action action + = action ?? Throw.ArgumentNullException>(nameof(action)); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IAction.Invoke(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4) + => action(arg1, arg2, arg3, arg4); + + public static implicit operator ActionWrapper(Action action) + => new(action); +} + +/// +/// Represents a read-only struct that wraps an delegate +/// and implements the interface to provide a way to invoke the action. +/// +/// The type of the first argument to be passed to the action when invoked. +/// The type of the second argument to be passed to the action when invoked. +/// The type of the third argument to be passed to the action when invoked. +/// The type of the fourth argument to be passed to the action when invoked. +/// The type of the fifth argument to be passed to the action when invoked. +/// +/// Initializes a new instance of the struct with the specified action. +/// +/// The delegate to be wrapped. +/// Thrown if is null. +[StructLayout(LayoutKind.Auto)] +public readonly struct ActionWrapper(Action action) + : IAction +{ + readonly Action action + = action ?? Throw.ArgumentNullException>(nameof(action)); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IAction.Invoke(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5) + => action(arg1, arg2, arg3, arg4, arg5); + + public static implicit operator ActionWrapper(Action action) + => new(action); +} + +/// +/// Represents a read-only struct that wraps an delegate +/// and implements the interface to provide a way to invoke the action. +/// +/// The type of the first argument to be passed to the action when invoked. +/// The type of the second argument to be passed to the action when invoked. +/// The type of the third argument to be passed to the action when invoked. +/// The type of the fourth argument to be passed to the action when invoked. +/// The type of the fifth argument to be passed to the action when invoked. +/// The type of the sixth argument to be passed to the action when invoked. +/// +/// Initializes a new instance of the struct with the specified action. +/// +/// The delegate to be wrapped. +/// Thrown if is null. +[StructLayout(LayoutKind.Auto)] +public readonly struct ActionWrapper(Action action) + : IAction +{ + readonly Action action + = action ?? Throw.ArgumentNullException>(nameof(action)); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IAction.Invoke(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6) + => action(arg1, arg2, arg3, arg4, arg5, arg6); + + public static implicit operator ActionWrapper(Action action) + => new(action); +} + +/// +/// Represents a read-only struct that wraps an delegate +/// and implements the interface to provide a way to invoke the action. +/// +/// The type of the first argument to be passed to the action when invoked. +/// The type of the second argument to be passed to the action when invoked. +/// The type of the third argument to be passed to the action when invoked. +/// The type of the fourth argument to be passed to the action when invoked. +/// The type of the fifth argument to be passed to the action when invoked. +/// The type of the sixth argument to be passed to the action when invoked. +/// The type of the seventh argument to be passed to the action when invoked. +/// +/// Initializes a new instance of the struct with the specified action. +/// +/// The delegate to be wrapped. +/// Thrown if is null. +[StructLayout(LayoutKind.Auto)] +public readonly struct ActionWrapper(Action action) + : IAction +{ + readonly Action action + = action ?? Throw.ArgumentNullException>(nameof(action)); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IAction.Invoke(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6, ref readonly T7 arg7) + => action(arg1, arg2, arg3, arg4, arg5, arg6, arg7); + + public static implicit operator ActionWrapper(Action action) + => new(action); +} + +/// +/// Represents a read-only struct that wraps an delegate +/// and implements the interface to provide a way to invoke the action. +/// +/// The type of the first argument to be passed to the action when invoked. +/// The type of the second argument to be passed to the action when invoked. +/// The type of the third argument to be passed to the action when invoked. +/// The type of the fourth argument to be passed to the action when invoked. +/// The type of the fifth argument to be passed to the action when invoked. +/// The type of the sixth argument to be passed to the action when invoked. +/// The type of the seventh argument to be passed to the action when invoked. +/// The type of the eighth argument to be passed to the action when invoked. +/// +/// Initializes a new instance of the struct with the specified action. +/// +/// The delegate to be wrapped. +/// Thrown if is null. +[StructLayout(LayoutKind.Auto)] +public readonly struct ActionWrapper(Action action) + : IAction +{ + readonly Action action + = action ?? Throw.ArgumentNullException>(nameof(action)); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IAction.Invoke(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6, ref readonly T7 arg7, ref readonly T8 arg8) + => action(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + + public static implicit operator ActionWrapper(Action action) + => new(action); +} + +/// +/// Represents a read-only struct that wraps an delegate +/// and implements the interface to provide a way to invoke the action. +/// +/// The type of the first argument to be passed to the action when invoked. +/// The type of the second argument to be passed to the action when invoked. +/// The type of the third argument to be passed to the action when invoked. +/// The type of the fourth argument to be passed to the action when invoked. +/// The type of the fifth argument to be passed to the action when invoked. +/// The type of the sixth argument to be passed to the action when invoked. +/// The type of the seventh argument to be passed to the action when invoked. +/// The type of the eighth argument to be passed to the action when invoked. +/// The type of the ninth argument to be passed to the action when invoked. +/// +/// Initializes a new instance of the struct with the specified action. +/// +/// The delegate to be wrapped. +/// Thrown if is null. +[StructLayout(LayoutKind.Auto)] +public readonly struct ActionWrapper(Action action) + : IAction +{ + readonly Action action + = action ?? Throw.ArgumentNullException>(nameof(action)); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IAction.Invoke(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6, ref readonly T7 arg7, ref readonly T8 arg8, ref readonly T9 arg9) + => action(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + + public static implicit operator ActionWrapper(Action action) + => new(action); +} + + diff --git a/NetFabric.Hyperlinq.Abstractions/AsyncFunctionWrapper.cs b/NetFabric.Hyperlinq.Abstractions/AsyncFunctionWrapper.cs index 866062a99..ab9c86445 100644 --- a/NetFabric.Hyperlinq.Abstractions/AsyncFunctionWrapper.cs +++ b/NetFabric.Hyperlinq.Abstractions/AsyncFunctionWrapper.cs @@ -1,151 +1,139 @@ -using System; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Threading.Tasks; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; -namespace NetFabric.Hyperlinq -{ - public readonly struct AsyncFunctionWrapper - : IAsyncFunction - { - readonly Func> function; - - public AsyncFunctionWrapper(Func> function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ValueTask InvokeAsync(T arg, CancellationToken cancellationToken) - => function(arg, cancellationToken); - - public static implicit operator AsyncFunctionWrapper(Func> func) - => new(func); - } - - public readonly struct AsyncFunctionWrapper - : IAsyncFunction - { - readonly Func> function; - - public AsyncFunctionWrapper(Func> function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ValueTask InvokeAsync(T1 arg1, T2 arg2, CancellationToken cancellationToken) - => function(arg1, arg2, cancellationToken); - - public static implicit operator AsyncFunctionWrapper(Func> func) - => new(func); - } - - public readonly struct AsyncFunctionWrapper - : IAsyncFunction - { - readonly Func> function; +namespace NetFabric.Hyperlinq; - public AsyncFunctionWrapper(Func> function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); +[StructLayout(LayoutKind.Auto)] +public readonly struct AsyncFunctionWrapper(Func> function) + : IAsyncFunction +{ + readonly Func> function + = function ?? throw new ArgumentNullException(nameof(function)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ValueTask InvokeAsync(T1 arg1, T2 arg2, T3 arg3, CancellationToken cancellationToken) - => function(arg1, arg2, arg3, cancellationToken); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask InvokeAsync(ref readonly T arg, CancellationToken cancellationToken) + => function(arg, cancellationToken); - public static implicit operator AsyncFunctionWrapper(Func> func) - => new(func); - } + public static implicit operator AsyncFunctionWrapper(Func> func) + => new(func); +} - public readonly struct AsyncFunctionWrapper - : IAsyncFunction - { - readonly Func> function; +[StructLayout(LayoutKind.Auto)] +public readonly struct AsyncFunctionWrapper(Func> function) + : IAsyncFunction +{ + readonly Func> function + = function ?? throw new ArgumentNullException(nameof(function)); - public AsyncFunctionWrapper(Func> function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, CancellationToken cancellationToken) + => function(arg1, arg2, cancellationToken); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ValueTask InvokeAsync(T1 arg1, T2 arg2, T3 arg3, T4 arg4, CancellationToken cancellationToken) - => function(arg1, arg2, arg3, arg4, cancellationToken); + public static implicit operator AsyncFunctionWrapper(Func> func) + => new(func); +} - public static implicit operator AsyncFunctionWrapper(Func> func) - => new(func); - } +[StructLayout(LayoutKind.Auto)] +public readonly struct AsyncFunctionWrapper(Func> function) + : IAsyncFunction +{ + readonly Func> function + = function ?? throw new ArgumentNullException(nameof(function)); - public readonly struct AsyncFunctionWrapper - : IAsyncFunction - { - readonly Func> function; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, CancellationToken cancellationToken) + => function(arg1, arg2, arg3, cancellationToken); - public AsyncFunctionWrapper(Func> function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); + public static implicit operator AsyncFunctionWrapper(Func> func) + => new(func); +} - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ValueTask InvokeAsync(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, CancellationToken cancellationToken) - => function(arg1, arg2, arg3, arg4, arg5, cancellationToken); +[StructLayout(LayoutKind.Auto)] +public readonly struct AsyncFunctionWrapper(Func> function) + : IAsyncFunction +{ + readonly Func> function + = function ?? throw new ArgumentNullException(nameof(function)); - public static implicit operator AsyncFunctionWrapper(Func> func) - => new(func); - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, CancellationToken cancellationToken) + => function(arg1, arg2, arg3, arg4, cancellationToken); - public readonly struct AsyncFunctionWrapper - : IAsyncFunction - { - readonly Func> function; + public static implicit operator AsyncFunctionWrapper(Func> func) + => new(func); +} - public AsyncFunctionWrapper(Func> function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); +[StructLayout(LayoutKind.Auto)] +public readonly struct AsyncFunctionWrapper(Func> function) + : IAsyncFunction +{ + readonly Func> function + = function ?? throw new ArgumentNullException(nameof(function)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ValueTask InvokeAsync(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, CancellationToken cancellationToken) - => function(arg1, arg2, arg3, arg4, arg5, arg6, cancellationToken); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, CancellationToken cancellationToken) + => function(arg1, arg2, arg3, arg4, arg5, cancellationToken); - public static implicit operator AsyncFunctionWrapper(Func> func) - => new(func); - } + public static implicit operator AsyncFunctionWrapper(Func> func) + => new(func); +} - public readonly struct AsyncFunctionWrapper - : IAsyncFunction - { - readonly Func> function; +[StructLayout(LayoutKind.Auto)] +public readonly struct AsyncFunctionWrapper(Func> function) + : IAsyncFunction +{ + readonly Func> function + = function ?? throw new ArgumentNullException(nameof(function)); - public AsyncFunctionWrapper(Func> function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6, CancellationToken cancellationToken) + => function(arg1, arg2, arg3, arg4, arg5, arg6, cancellationToken); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ValueTask InvokeAsync(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, CancellationToken cancellationToken) - => function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, cancellationToken); + public static implicit operator AsyncFunctionWrapper(Func> func) + => new(func); +} - public static implicit operator AsyncFunctionWrapper(Func> func) - => new(func); - } +[StructLayout(LayoutKind.Auto)] +public readonly struct AsyncFunctionWrapper(Func> function) + : IAsyncFunction +{ + readonly Func> function + = function ?? throw new ArgumentNullException(nameof(function)); - public readonly struct AsyncFunctionWrapper - : IAsyncFunction - { - readonly Func> function; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6, ref readonly T7 arg7, CancellationToken cancellationToken) + => function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, cancellationToken); - public AsyncFunctionWrapper(Func> function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); + public static implicit operator AsyncFunctionWrapper(Func> func) + => new(func); +} - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ValueTask InvokeAsync(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, CancellationToken cancellationToken) - => function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, cancellationToken); +[StructLayout(LayoutKind.Auto)] +public readonly struct AsyncFunctionWrapper(Func> function) + : IAsyncFunction +{ + readonly Func> function + = function ?? throw new ArgumentNullException(nameof(function)); - public static implicit operator AsyncFunctionWrapper(Func> func) - => new(func); - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6, ref readonly T7 arg7, ref readonly T8 arg8, CancellationToken cancellationToken) + => function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, cancellationToken); - public readonly struct AsyncFunctionWrapper - : IAsyncFunction - { - readonly Func> function; + public static implicit operator AsyncFunctionWrapper(Func> func) + => new(func); +} - public AsyncFunctionWrapper(Func> function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); +[StructLayout(LayoutKind.Auto)] +public readonly struct AsyncFunctionWrapper(Func> function) + : IAsyncFunction +{ + readonly Func> function + = function ?? throw new ArgumentNullException(nameof(function)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ValueTask InvokeAsync(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, CancellationToken cancellationToken) - => function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, cancellationToken); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6, ref readonly T7 arg7, ref readonly T8 arg8, ref readonly T9 arg9, CancellationToken cancellationToken) + => function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, cancellationToken); - public static implicit operator AsyncFunctionWrapper(Func> func) - => new(func); - } -} + public static implicit operator AsyncFunctionWrapper(Func> func) + => new(func); +} \ No newline at end of file diff --git a/NetFabric.Hyperlinq.Abstractions/AsyncValueEnumerable.cs b/NetFabric.Hyperlinq.Abstractions/AsyncValueEnumerable.cs index 528d61c1e..632693f18 100644 --- a/NetFabric.Hyperlinq.Abstractions/AsyncValueEnumerable.cs +++ b/NetFabric.Hyperlinq.Abstractions/AsyncValueEnumerable.cs @@ -1,12 +1,8 @@ -using System.Collections.Generic; -using System.Threading; +namespace NetFabric.Hyperlinq; -namespace NetFabric.Hyperlinq +public interface IAsyncValueEnumerable + : IAsyncEnumerable + where TEnumerator : struct, IAsyncEnumerator { - public interface IAsyncValueEnumerable - : IAsyncEnumerable - where TEnumerator : struct, IAsyncEnumerator - { - new TEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default); - } + new TEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/NetFabric.Hyperlinq.Abstractions/FunctionIn.cs b/NetFabric.Hyperlinq.Abstractions/FunctionIn.cs deleted file mode 100644 index b10e4d3c8..000000000 --- a/NetFabric.Hyperlinq.Abstractions/FunctionIn.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace NetFabric.Hyperlinq -{ - public delegate TResult FunctionIn(in T arg); - - public delegate TResult FunctionIn(in T1 arg, T2 arg2); -} diff --git a/NetFabric.Hyperlinq.Abstractions/FunctionInWrapper.cs b/NetFabric.Hyperlinq.Abstractions/FunctionInWrapper.cs deleted file mode 100644 index e91f77875..000000000 --- a/NetFabric.Hyperlinq.Abstractions/FunctionInWrapper.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Runtime.CompilerServices; - -namespace NetFabric.Hyperlinq -{ - public readonly struct FunctionInWrapper - : IFunctionIn - { - readonly FunctionIn function; - - public FunctionInWrapper(FunctionIn function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public TResult Invoke(in T arg) - => function(arg); - - public static implicit operator FunctionInWrapper(FunctionIn func) - => new(func); - } - - public readonly struct FunctionInWrapper - : IFunctionIn - { - readonly FunctionIn function; - - public FunctionInWrapper(FunctionIn function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public TResult Invoke(in T1 arg1, T2 arg2) - => function(arg1, arg2); - - public static implicit operator FunctionInWrapper(FunctionIn func) - => new(func); - } -} diff --git a/NetFabric.Hyperlinq.Abstractions/FunctionWrapper.cs b/NetFabric.Hyperlinq.Abstractions/FunctionWrapper.cs index 7cd133f9f..2960455ba 100644 --- a/NetFabric.Hyperlinq.Abstractions/FunctionWrapper.cs +++ b/NetFabric.Hyperlinq.Abstractions/FunctionWrapper.cs @@ -1,165 +1,154 @@ -using System; -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; -namespace NetFabric.Hyperlinq -{ - public readonly struct FunctionWrapper - : IFunction - { - readonly Func function; - - public FunctionWrapper(Func function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public TResult Invoke() - => function(); - - public static implicit operator FunctionWrapper(Func func) - => new(func); - } - - public readonly struct FunctionWrapper - : IFunction - { - readonly Func function; - - public FunctionWrapper(Func function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public TResult Invoke(T arg) - => function(arg); - - public static implicit operator FunctionWrapper(Func func) - => new(func); - } - - public readonly struct FunctionWrapper - : IFunction - { - readonly Func function; +namespace NetFabric.Hyperlinq; - public FunctionWrapper(Func function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); +[StructLayout(LayoutKind.Auto)] +public readonly struct FunctionWrapper(Func function) + : IFunction +{ + readonly Func function + = function ?? throw new ArgumentNullException(nameof(function)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public TResult Invoke(T1 arg1, T2 arg2) - => function(arg1, arg2); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TResult Invoke() + => function(); - public static implicit operator FunctionWrapper(Func func) - => new(func); - } - - public readonly struct FunctionWrapper - : IFunction - { - readonly Func function; + public static implicit operator FunctionWrapper(Func func) + => new(func); +} - public FunctionWrapper(Func function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); +[StructLayout(LayoutKind.Auto)] +public readonly struct FunctionWrapper(Func function) + : IFunction +{ + readonly Func function + = function ?? throw new ArgumentNullException(nameof(function)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public TResult Invoke(T1 arg1, T2 arg2, T3 arg3) - => function(arg1, arg2, arg3); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TResult Invoke(T arg) + => function(arg); - public static implicit operator FunctionWrapper(Func func) - => new(func); - } + public static implicit operator FunctionWrapper(Func func) + => new(func); +} - public readonly struct FunctionWrapper - : IFunction - { - readonly Func function; +[StructLayout(LayoutKind.Auto)] +public readonly struct FunctionWrapper(Func function) + : IFunction +{ + readonly Func function + = function ?? throw new ArgumentNullException(nameof(function)); - public FunctionWrapper(Func function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TResult Invoke(T1 arg1, T2 arg2) + => function(arg1, arg2); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4) - => function(arg1, arg2, arg3, arg4); + public static implicit operator FunctionWrapper(Func func) + => new(func); +} - public static implicit operator FunctionWrapper(Func func) - => new(func); - } +[StructLayout(LayoutKind.Auto)] +public readonly struct FunctionWrapper(Func function) + : IFunction +{ + readonly Func function + = function ?? throw new ArgumentNullException(nameof(function)); - public readonly struct FunctionWrapper - : IFunction - { - readonly Func function; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3) + => function(arg1, arg2, arg3); - public FunctionWrapper(Func function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); + public static implicit operator FunctionWrapper(Func func) + => new(func); +} - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - => function(arg1, arg2, arg3, arg4, arg5); +[StructLayout(LayoutKind.Auto)] +public readonly struct FunctionWrapper(Func function) + : IFunction +{ + readonly Func function + = function ?? throw new ArgumentNullException(nameof(function)); - public static implicit operator FunctionWrapper(Func func) - => new(func); - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4) + => function(arg1, arg2, arg3, arg4); - public readonly struct FunctionWrapper - : IFunction - { - readonly Func function; + public static implicit operator FunctionWrapper(Func func) + => new(func); +} - public FunctionWrapper(Func function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); +[StructLayout(LayoutKind.Auto)] +public readonly struct FunctionWrapper(Func function) + : IFunction +{ + readonly Func function + = function ?? throw new ArgumentNullException(nameof(function)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - => function(arg1, arg2, arg3, arg4, arg5, arg6); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + => function(arg1, arg2, arg3, arg4, arg5); - public static implicit operator FunctionWrapper(Func func) - => new(func); - } + public static implicit operator FunctionWrapper(Func func) + => new(func); +} - public readonly struct FunctionWrapper - : IFunction - { - readonly Func function; +[StructLayout(LayoutKind.Auto)] +public readonly struct FunctionWrapper(Func function) + : IFunction +{ + readonly Func function + = function ?? throw new ArgumentNullException(nameof(function)); - public FunctionWrapper(Func function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + => function(arg1, arg2, arg3, arg4, arg5, arg6); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - => function(arg1, arg2, arg3, arg4, arg5, arg6, arg7); + public static implicit operator FunctionWrapper(Func func) + => new(func); +} - public static implicit operator FunctionWrapper(Func func) - => new(func); - } +[StructLayout(LayoutKind.Auto)] +public readonly struct FunctionWrapper(Func function) + : IFunction +{ + readonly Func function + = function ?? throw new ArgumentNullException(nameof(function)); - public readonly struct FunctionWrapper - : IFunction - { - readonly Func function; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + => function(arg1, arg2, arg3, arg4, arg5, arg6, arg7); - public FunctionWrapper(Func function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); + public static implicit operator FunctionWrapper(Func func) + => new(func); +} - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - => function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); +[StructLayout(LayoutKind.Auto)] +public readonly struct FunctionWrapper(Func function) + : IFunction +{ + readonly Func function + = function ?? throw new ArgumentNullException(nameof(function)); - public static implicit operator FunctionWrapper(Func func) - => new(func); - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + => function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - public readonly struct FunctionWrapper - : IFunction - { - readonly Func function; + public static implicit operator FunctionWrapper(Func func) + => new(func); +} - public FunctionWrapper(Func function) - => this.function = function ?? throw new ArgumentNullException(nameof(function)); +[StructLayout(LayoutKind.Auto)] +public readonly struct FunctionWrapper(Func function) + : IFunction +{ + readonly Func function + = function ?? throw new ArgumentNullException(nameof(function)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - => function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + => function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - public static implicit operator FunctionWrapper(Func func) - => new(func); - } -} + public static implicit operator FunctionWrapper(Func func) + => new(func); +} \ No newline at end of file diff --git a/NetFabric.Hyperlinq.Abstractions/IAction.cs b/NetFabric.Hyperlinq.Abstractions/IAction.cs new file mode 100644 index 000000000..3cdaa8d21 --- /dev/null +++ b/NetFabric.Hyperlinq.Abstractions/IAction.cs @@ -0,0 +1,190 @@ +namespace NetFabric.Hyperlinq; + +/// +/// Defines an interface for a generic action that can be invoked with a readonly reference to an argument of type . +/// +/// The type of the argument to be passed when invoking the action. +public interface IAction +{ + /// + /// Invokes the action with a readonly reference to the specified argument of type . + /// + /// The readonly reference to the argument to be passed to the action. + void Invoke(ref readonly T arg); +} + +/// +/// Defines an interface for a generic action that can be invoked with readonly references to two arguments of type and . +/// +/// The type of the first argument to be passed when invoking the action. +/// The type of the second argument to be passed when invoking the action. +public interface IAction +{ + /// + /// Invokes the action with readonly references to the specified arguments of type and . + /// + /// The readonly reference to the first argument to be passed to the action. + /// The readonly reference to the second argument to be passed to the action. + void Invoke(ref readonly T1 arg1, ref readonly T2 arg2); +} + +/// +/// Defines an interface for a generic action that can be invoked with readonly references to three arguments of type , , and . +/// +/// The type of the first argument to be passed when invoking the action. +/// The type of the second argument to be passed when invoking the action. +/// The type of the third argument to be passed when invoking the action. +public interface IAction +{ + /// + /// Invokes the action with readonly references to the specified arguments of type , , and . + /// + /// The readonly reference to the first argument to be passed to the action. + /// The readonly reference to the second argument to be passed to the action. + /// The readonly reference to the third argument to be passed to the action. + void Invoke(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3); +} + +/// +/// Defines an interface for a generic action that can be invoked with readonly references to nine arguments of types to . +/// +/// The type of the first argument to be passed when invoking the action. +/// The type of the second argument to be passed when invoking the action. +/// The type of the third argument to be passed when invoking the action. +/// The type of the fourth argument to be passed when invoking the action. +public interface IAction +{ + /// + /// Invokes the action with readonly references to the specified arguments of types to . + /// + /// The readonly reference to the first argument to be passed to the action. + /// The readonly reference to the second argument to be passed to the action. + /// The readonly reference to the third argument to be passed to the action. + /// The readonly reference to the fourth argument to be passed to the action. + void Invoke(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4); +} + +/// +/// Defines an interface for a generic action that can be invoked with readonly references to nine arguments of types to . +/// +/// The type of the first argument to be passed when invoking the action. +/// The type of the second argument to be passed when invoking the action. +/// The type of the third argument to be passed when invoking the action. +/// The type of the fourth argument to be passed when invoking the action. +/// The type of the fifth argument to be passed when invoking the action. +public interface IAction +{ + /// + /// Invokes the action with readonly references to the specified arguments of types to . + /// + /// The readonly reference to the first argument to be passed to the action. + /// The readonly reference to the second argument to be passed to the action. + /// The readonly reference to the third argument to be passed to the action. + /// The readonly reference to the fourth argument to be passed to the action. + /// The readonly reference to the fifth argument to be passed to the action. + void Invoke(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5); +} + +/// +/// Defines an interface for a generic action that can be invoked with readonly references to nine arguments of types to . +/// +/// The type of the first argument to be passed when invoking the action. +/// The type of the second argument to be passed when invoking the action. +/// The type of the third argument to be passed when invoking the action. +/// The type of the fourth argument to be passed when invoking the action. +/// The type of the fifth argument to be passed when invoking the action. +/// The type of the sixth argument to be passed when invoking the action. +public interface IAction +{ + /// + /// Invokes the action with readonly references to the specified arguments of types to . + /// + /// The readonly reference to the first argument to be passed to the action. + /// The readonly reference to the second argument to be passed to the action. + /// The readonly reference to the third argument to be passed to the action. + /// The readonly reference to the fourth argument to be passed to the action. + /// The readonly reference to the fifth argument to be passed to the action. + /// The readonly reference to the sixth argument to be passed to the action. + void Invoke(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6); +} + +/// +/// Defines an interface for a generic action that can be invoked with readonly references to nine arguments of types to . +/// +/// The type of the first argument to be passed when invoking the action. +/// The type of the second argument to be passed when invoking the action. +/// The type of the third argument to be passed when invoking the action. +/// The type of the fourth argument to be passed when invoking the action. +/// The type of the fifth argument to be passed when invoking the action. +/// The type of the sixth argument to be passed when invoking the action. +/// The type of the seventh argument to be passed when invoking the action. +public interface IAction +{ + /// + /// Invokes the action with readonly references to the specified arguments of types to . + /// + /// The readonly reference to the first argument to be passed to the action. + /// The readonly reference to the second argument to be passed to the action. + /// The readonly reference to the third argument to be passed to the action. + /// The readonly reference to the fourth argument to be passed to the action. + /// The readonly reference to the fifth argument to be passed to the action. + /// The readonly reference to the sixth argument to be passed to the action. + /// The readonly reference to the seventh argument to be passed to the action. + void Invoke(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6, ref readonly T7 arg7); +} + +/// +/// Defines an interface for a generic action that can be invoked with readonly references to nine arguments of types to . +/// +/// The type of the first argument to be passed when invoking the action. +/// The type of the second argument to be passed when invoking the action. +/// The type of the third argument to be passed when invoking the action. +/// The type of the fourth argument to be passed when invoking the action. +/// The type of the fifth argument to be passed when invoking the action. +/// The type of the sixth argument to be passed when invoking the action. +/// The type of the seventh argument to be passed when invoking the action. +/// The type of the eighth argument to be passed when invoking the action. +public interface IAction +{ + /// + /// Invokes the action with readonly references to the specified arguments of types to . + /// + /// The readonly reference to the first argument to be passed to the action. + /// The readonly reference to the second argument to be passed to the action. + /// The readonly reference to the third argument to be passed to the action. + /// The readonly reference to the fourth argument to be passed to the action. + /// The readonly reference to the fifth argument to be passed to the action. + /// The readonly reference to the sixth argument to be passed to the action. + /// The readonly reference to the seventh argument to be passed to the action. + /// The readonly reference to the eighth argument to be passed to the action. + void Invoke(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6, ref readonly T7 arg7, ref readonly T8 arg8); +} + +/// +/// Defines an interface for a generic action that can be invoked with readonly references to nine arguments of types to . +/// +/// The type of the first argument to be passed when invoking the action. +/// The type of the second argument to be passed when invoking the action. +/// The type of the third argument to be passed when invoking the action. +/// The type of the fourth argument to be passed when invoking the action. +/// The type of the fifth argument to be passed when invoking the action. +/// The type of the sixth argument to be passed when invoking the action. +/// The type of the seventh argument to be passed when invoking the action. +/// The type of the eighth argument to be passed when invoking the action. +/// The type of the ninth argument to be passed when invoking the action. +public interface IAction +{ + /// + /// Invokes the action with readonly references to the specified arguments of types to . + /// + /// The readonly reference to the first argument to be passed to the action. + /// The readonly reference to the second argument to be passed to the action. + /// The readonly reference to the third argument to be passed to the action. + /// The readonly reference to the fourth argument to be passed to the action. + /// The readonly reference to the fifth argument to be passed to the action. + /// The readonly reference to the sixth argument to be passed to the action. + /// The readonly reference to the seventh argument to be passed to the action. + /// The readonly reference to the eighth argument to be passed to the action. + /// The readonly reference to the ninth argument to be passed to the action. + void Invoke(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6, ref readonly T7 arg7, ref readonly T8 arg8, ref readonly T9 arg9); +} diff --git a/NetFabric.Hyperlinq.Abstractions/IAsyncFunction.cs b/NetFabric.Hyperlinq.Abstractions/IAsyncFunction.cs index 131aa2992..2303ce808 100644 --- a/NetFabric.Hyperlinq.Abstractions/IAsyncFunction.cs +++ b/NetFabric.Hyperlinq.Abstractions/IAsyncFunction.cs @@ -1,50 +1,46 @@ -using System.Threading; -using System.Threading.Tasks; - -namespace NetFabric.Hyperlinq -{ - public interface IAsyncFunction - { - ValueTask InvokeAsync(T arg, CancellationToken cancellationToken); - } - - public interface IAsyncFunction - { - ValueTask InvokeAsync(T1 arg1, T2 arg2, CancellationToken cancellationToken); - } - - public interface IAsyncFunction - { - ValueTask InvokeAsync(T1 arg1, T2 arg2, T3 arg3, CancellationToken cancellationToken); - } - - public interface IAsyncFunction - { - ValueTask InvokeAsync(T1 arg1, T2 arg2, T3 arg3, T4 arg4, CancellationToken cancellationToken); - } - - public interface IAsyncFunction - { - ValueTask InvokeAsync(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, CancellationToken cancellationToken); - } - - public interface IAsyncFunction - { - ValueTask InvokeAsync(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, CancellationToken cancellationToken); - } - - public interface IAsyncFunction - { - ValueTask InvokeAsync(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, CancellationToken cancellationToken); - } - - public interface IAsyncFunction - { - ValueTask InvokeAsync(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, CancellationToken cancellationToken); - } - - public interface IAsyncFunction - { - ValueTask InvokeAsync(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, CancellationToken cancellationToken); - } +namespace NetFabric.Hyperlinq; + +public interface IAsyncFunction +{ + ValueTask InvokeAsync(ref readonly T arg, CancellationToken cancellationToken); } + +public interface IAsyncFunction +{ + ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, CancellationToken cancellationToken); +} + +public interface IAsyncFunction +{ + ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, CancellationToken cancellationToken); +} + +public interface IAsyncFunction +{ + ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, CancellationToken cancellationToken); +} + +public interface IAsyncFunction +{ + ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, CancellationToken cancellationToken); +} + +public interface IAsyncFunction +{ + ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6, CancellationToken cancellationToken); +} + +public interface IAsyncFunction +{ + ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6, ref readonly T7 arg7, CancellationToken cancellationToken); +} + +public interface IAsyncFunction +{ + ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6, ref readonly T7 arg7, ref readonly T8 arg8, CancellationToken cancellationToken); +} + +public interface IAsyncFunction +{ + ValueTask InvokeAsync(ref readonly T1 arg1, ref readonly T2 arg2, ref readonly T3 arg3, ref readonly T4 arg4, ref readonly T5 arg5, ref readonly T6 arg6, ref readonly T7 arg7, ref readonly T8 arg8, ref readonly T9 arg9, CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/NetFabric.Hyperlinq.Abstractions/IFunction.cs b/NetFabric.Hyperlinq.Abstractions/IFunction.cs index 1133f3133..c1f3acdca 100644 --- a/NetFabric.Hyperlinq.Abstractions/IFunction.cs +++ b/NetFabric.Hyperlinq.Abstractions/IFunction.cs @@ -1,64 +1,51 @@ -using System.Diagnostics.Contracts; +namespace NetFabric.Hyperlinq; -namespace NetFabric.Hyperlinq +public interface IFunction { - public interface IFunction - { - [Pure] - TResult Invoke(); - } - - public interface IFunction - { - [Pure] - TResult Invoke(T arg); - } + TResult Invoke(); +} - public interface IFunction - { - [Pure] - TResult Invoke(T1 arg1, T2 arg2); - } +public interface IFunction +{ + TResult Invoke(T arg); +} - public interface IFunction - { - [Pure] - TResult Invoke(T1 arg1, T2 arg2, T3 arg3); - } +public interface IFunction +{ + TResult Invoke(T1 arg1, T2 arg2); +} - public interface IFunction - { - [Pure] - TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4); - } +public interface IFunction +{ + TResult Invoke(T1 arg1, T2 arg2, T3 arg3); +} - public interface IFunction - { - [Pure] - TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); - } +public interface IFunction +{ + TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4); +} - public interface IFunction - { - [Pure] - TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); - } +public interface IFunction +{ + TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); +} - public interface IFunction - { - [Pure] - TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); - } +public interface IFunction +{ + TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); +} - public interface IFunction - { - [Pure] - TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8); - } +public interface IFunction +{ + TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); +} - public interface IFunction - { - [Pure] - TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9); - } +public interface IFunction +{ + TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8); } + +public interface IFunction +{ + TResult Invoke(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9); +} \ No newline at end of file diff --git a/NetFabric.Hyperlinq.Abstractions/IFunctionIn.cs b/NetFabric.Hyperlinq.Abstractions/IFunctionIn.cs deleted file mode 100644 index 030442141..000000000 --- a/NetFabric.Hyperlinq.Abstractions/IFunctionIn.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace NetFabric.Hyperlinq -{ - public interface IFunctionIn - { - TResult Invoke(in T arg); - } - - public interface IFunctionIn - { - TResult Invoke(in T1 arg1, T2 arg2); - } -} diff --git a/NetFabric.Hyperlinq.Abstractions/IValueEnumerable.cs b/NetFabric.Hyperlinq.Abstractions/IValueEnumerable.cs new file mode 100644 index 000000000..18bc4b96e --- /dev/null +++ b/NetFabric.Hyperlinq.Abstractions/IValueEnumerable.cs @@ -0,0 +1,26 @@ +using System.Diagnostics.CodeAnalysis; + +namespace NetFabric.Hyperlinq; + +/// +/// Represents a read-only collection of values with a non-boxing enumerator, +/// providing an alternative to for improved performance. +/// +/// The type of elements in the collection. +/// The type of the enumerator. +/// +/// This interface is designed to offer improved performance over +/// by avoiding the boxing of the enumerator. It maintains backward compatibility by deriving from +/// . +/// +public interface IValueEnumerable + : IEnumerable + where TEnumerator : struct, IEnumerator +{ + /// + /// Returns an enumerator instance. + /// + /// An enumerator instance. + [return: NotNull] + new TEnumerator GetEnumerator(); +} diff --git a/NetFabric.Hyperlinq.Abstractions/IVectorAction.cs b/NetFabric.Hyperlinq.Abstractions/IVectorAction.cs new file mode 100644 index 000000000..41b4742b4 --- /dev/null +++ b/NetFabric.Hyperlinq.Abstractions/IVectorAction.cs @@ -0,0 +1,147 @@ +using System.Numerics; + +namespace NetFabric.Hyperlinq; + +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP1_0_OR_GREATER + +/// +/// Represents an interface for a generic action that can be invoked with a readonly reference to a argument of type . +/// +/// The type of the elements in the argument. +/// +/// This interface extends the interface to support vectorized operations. It allows actions to be invoked +/// with a readonly reference to a argument, making it suitable for scenarios where vectorization can be applied +/// for improved performance in numerical or computational tasks. +/// +/// +/// The method is used instead in scenarios where vectorization is not available or on elements +/// that don't fit in a . +/// +public interface IVectorAction + : IAction + where T : struct +{ + /// + /// Invokes the action with a readonly reference to the specified argument of type . + /// + /// The readonly reference to the argument to be passed to the action. + void Invoke(ref readonly Vector arg); +} + +/// +/// Represents an interface for a generic 2D action that can be invoked with a readonly reference to a argument of type . +/// +/// The type of the elements in the argument. +/// +/// This interface extends the interface to support 2D vectorized operations. It allows actions to be invoked +/// with a readonly reference to a argument, making it suitable for scenarios where 2D vectorization can be applied +/// for improved performance in numerical or computational tasks. +/// +// +/// The method is used instead in scenarios where vectorization is not available or on elements +/// that don't fit in a . +/// +public interface IVectorAction2D : IAction + where T : struct +{ + /// + /// Invokes the action with a readonly reference to the specified argument of type . + /// + /// The readonly reference to the argument to be passed to the 2D action. + void Invoke(ref readonly Vector arg); +} + +// +/// Represents an interface for a generic 3D action that can be invoked with a readonly reference to a argument of type . +/// +/// The type of the elements in the argument. +/// +/// This interface extends the interface to support 2D vectorized operations. It allows actions to be invoked +/// with a readonly reference to a argument, making it suitable for scenarios where 2D vectorization can be applied +/// for improved performance in numerical or computational tasks. +/// +// +/// The method is used instead in scenarios where vectorization is not available or on elements +/// that don't fit in a . +/// +public interface IVectorAction3D + : IAction + where T : struct +{ + /// + /// Invokes the action with a readonly reference to the specified argument of type . + /// + /// The readonly reference to the argument to be passed to the 2D action. + void Invoke(ref readonly Vector arg); +} + +// +/// Represents an interface for a generic 4D action that can be invoked with a readonly reference to a argument of type . +/// +/// The type of the elements in the argument. +/// +/// This interface extends the interface to support 2D vectorized operations. It allows actions to be invoked +/// with a readonly reference to a argument, making it suitable for scenarios where 2D vectorization can be applied +/// for improved performance in numerical or computational tasks. +/// +// +/// The method is used instead in scenarios where vectorization is not available or on elements +/// that don't fit in a . +/// +public interface IVectorAction4D + : IAction + where T : struct +{ + /// + /// Invokes the action with a readonly reference to the specified argument of type . + /// + /// The readonly reference to the argument to be passed to the 2D action. + void Invoke(ref readonly Vector arg); +} + +// +/// Represents an interface for a generic 5D action that can be invoked with a readonly reference to a argument of type . +/// +/// The type of the elements in the argument. +/// +/// This interface extends the interface to support 2D vectorized operations. It allows actions to be invoked +/// with a readonly reference to a argument, making it suitable for scenarios where 2D vectorization can be applied +/// for improved performance in numerical or computational tasks. +/// +/// +/// The method is used instead in scenarios where vectorization is not available or on elements +/// that don't fit in a . +/// +public interface IVectorAction5D : IAction where T : struct +{ + /// + /// Invokes the action with a readonly reference to the specified argument of type . + /// + /// The readonly reference to the argument. + void Invoke(in Vector arg); +} + +// +/// Represents an interface for a generic 6D action that can be invoked with a readonly reference to a argument of type . +/// +/// The type of the elements in the argument. +/// +/// This interface extends the interface to support 2D vectorized operations. It allows actions to be invoked +/// with a readonly reference to a argument, making it suitable for scenarios where 2D vectorization can be applied +/// for improved performance in numerical or computational tasks. +/// +/// +/// The method is used instead in scenarios where vectorization is not available or on elements +/// that don't fit in a . +/// +public interface IVectorAction6D : IAction where T : struct +{ + /// + /// Invokes the action with a readonly reference to the specified argument of type . + /// + /// The readonly reference to the argument. + void Invoke(in Vector arg); +} + + +#endif diff --git a/NetFabric.Hyperlinq.Abstractions/NetFabric.Hyperlinq.Abstractions.csproj b/NetFabric.Hyperlinq.Abstractions/NetFabric.Hyperlinq.Abstractions.csproj index a7ecc6c65..3cc482b19 100644 --- a/NetFabric.Hyperlinq.Abstractions/NetFabric.Hyperlinq.Abstractions.csproj +++ b/NetFabric.Hyperlinq.Abstractions/NetFabric.Hyperlinq.Abstractions.csproj @@ -5,9 +5,10 @@ NetFabric.Hyperlinq.Abstractions NetFabric.Hyperlinq.Abstractions Abstractions for high performance enumeration. - 1.3.0 + 2.0.0 Icon.png LICENSE + README.md netfabric, hyperlinq, abstractions, linq, enumeration, performance true true @@ -18,21 +19,23 @@ + - + + all runtime; build; native; contentfiles; analyzers - + all runtime; build; native; contentfiles; analyzers - + diff --git a/NetFabric.Hyperlinq.Abstractions/README.md b/NetFabric.Hyperlinq.Abstractions/README.md new file mode 100644 index 000000000..d3e9863e7 --- /dev/null +++ b/NetFabric.Hyperlinq.Abstractions/README.md @@ -0,0 +1,65 @@ +# NetFabric.Hyperlinq.Abstractions + +This library provides abstractions for optimizing the performance of enumerations. + +## IValueEnumerable Interface + +In this package, you'll find the `IValueEnumerable` interface. It's designed for collections that want a value type enumerator for better performance, avoiding the enumerator boxing present in `IEnumerable` and `IEnumerable`. + +## Value Delegates + +In C#, the commonly used predefined delegates [Func](https://github.com/dotnet/dotnet/blob/57e423d62059914d1b92854b656abecdc120e538/src/runtime/src/libraries/System.Private.CoreLib/src/System/Function.cs#L6) and [Action](https://github.com/dotnet/dotnet/blob/57e423d62059914d1b92854b656abecdc120e538/src/runtime/src/libraries/System.Private.CoreLib/src/System/Action.cs#L9) can lead to performance issues due to heap allocation and virtual calls. Value delegates address this by providing optimized performance for resource-intensive scenarios. + +It's worth noting that value delegates aren't automatically supported by the compiler and need explicit implementation. + +The package introduces interfaces like `IAction`, `IFunction`, `IAsyncFunction`, and `IVectorAction`. These interfaces define a method `Invoke()` that can be implemented by a value type. Instances of this value type can replace traditional delegates as parameters and can also hold state, similar to the reference type generated by the compiler when using delegates. + +Here's an example of a value type, `SumValueAction`, implementing `IAction` for calculating the sum: + +```csharp +public struct SumValueAction : IAction + where T : struct, IAdditiveIdentity, IAdditionOperators +{ + T sum; + + public SumValueAction() + { + sum = T.AdditiveIdentity; + } + + public readonly T Result + => sum; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IAction.Invoke(ref readonly T item) + => sum += item; +} +``` + +Here's an example of a method implementation that's support the use of a value delegate: + +```csharp +public static void ForEachEx(this IEnumerable source, ref TAction action) + where TAction : struct, IAction +{ + foreach (var item in source) + action.Invoke(in item); +} +``` + +The use of the interface as a constraint avoids the boxing of the value delegate. + +These can be used as follow to calculate the sum of the elements of a collection: + +```csharp +var action = new SumValueAction(); +collection.ForEachEx(ref action); +console.WriteLine(action.Result); +``` + +The package also includes wrappers enabling the use of delegates, along with implicit cast operators converting a delegate to a value delegate. + +References: + +- ["An interface for value-type enumerators, a proposal"](https://www.linkedin.com/pulse/interface-value-type-enumerators-proposal-ant%25C3%25A3o-almada/) +- ["The Battle of Loops: foreach vs. ForEach in C#"](https://www.linkedin.com/pulse/battle-loops-foreach-vs-c-ant%25C3%25A3o-almada/) \ No newline at end of file diff --git a/NetFabric.Hyperlinq.Abstractions/ValueEnumerable.cs b/NetFabric.Hyperlinq.Abstractions/ValueEnumerable.cs deleted file mode 100644 index d4078c94f..000000000 --- a/NetFabric.Hyperlinq.Abstractions/ValueEnumerable.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; - -namespace NetFabric.Hyperlinq -{ - public interface IValueEnumerable - : IEnumerable - where TEnumerator : struct, IEnumerator - { - [return: NotNull] new TEnumerator GetEnumerator(); - } - - public interface IValueReadOnlyCollection - : IReadOnlyCollection - , IValueEnumerable - where TEnumerator : struct, IEnumerator - { - } - - public interface IValueReadOnlyList - : IReadOnlyList - , IValueReadOnlyCollection - where TEnumerator : struct, IEnumerator - { - } -}