Skip to content

Commit

Permalink
Added span interop
Browse files Browse the repository at this point in the history
  • Loading branch information
sakno committed Aug 17, 2024
1 parent 5cbb4c6 commit 140ee52
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
28 changes: 27 additions & 1 deletion src/DotNext.Tests/Runtime/ValueReferenceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,20 @@ public static void MutableEmptyRef()
var reference = default(ValueReference<float>);
True(reference.IsEmpty);
Null(reference.ToString());

Span<float> span = reference;
True(span.IsEmpty);
}

[Fact]
public static void ImmutableEmptyRef()
{
var reference = default(ReadOnlyValueReference<float>);
True(reference.IsEmpty);
Null(reference.ToString());

ReadOnlySpan<float> span = reference;
True(span.IsEmpty);
}

[Fact]
Expand Down Expand Up @@ -167,6 +173,26 @@ public static void ArrayCovariance()
Equal("b", roRef.Value);
}

[Fact]
public static void SpanInterop()
{
var reference = new ValueReference<int>(42);
Span<int> span = reference;
Equal(1, span.Length);

True(Unsafe.AreSame(in reference.Value, in span[0]));
}

[Fact]
public static void ReadOnlySpanInterop()
{
ReadOnlyValueReference<int> reference = new ValueReference<int>(42);
ReadOnlySpan<int> span = reference;
Equal(1, span.Length);

True(Unsafe.AreSame(in reference.Value, in span[0]));
}

private record class MyClass : IResettable
{
internal static string StaticObject;
Expand Down
16 changes: 16 additions & 0 deletions src/DotNext/Runtime/ValueReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ public bool Equals(ValueReference<T> reference)
/// <returns>The immutable field reference.</returns>
public static implicit operator ReadOnlyValueReference<T>(ValueReference<T> reference)
=> Unsafe.BitCast<ValueReference<T>, ReadOnlyValueReference<T>>(reference);

/// <summary>
/// Gets a span over the referenced value.
/// </summary>
/// <param name="reference">The value reference.</param>
/// <returns>The span that contains <see cref="Value"/>; or empty span if <paramref name="reference"/> is empty.</returns>
public static implicit operator Span<T>(ValueReference<T> reference)
=> reference.IsEmpty ? new() : new(ref reference.Value);
}

/// <summary>
Expand Down Expand Up @@ -205,6 +213,14 @@ public bool Equals(ReadOnlyValueReference<T> reference)
/// <returns><see langword="true"/> if both references are not equal; otherwise, <see langword="false"/>.</returns>
public static bool operator !=(ReadOnlyValueReference<T> x, ReadOnlyValueReference<T> y)
=> x.Equals(y) is false;

/// <summary>
/// Gets a span over the referenced value.
/// </summary>
/// <param name="reference">The value reference.</param>
/// <returns>The span that contains <see cref="Value"/>; or empty span if <paramref name="reference"/> is empty.</returns>
public static implicit operator ReadOnlySpan<T>(ReadOnlyValueReference<T> reference)
=> reference.IsEmpty ? new() : new(in reference.Value);
}

[SuppressMessage("Performance", "CA1812", Justification = "Used for reinterpret cast")]
Expand Down

0 comments on commit 140ee52

Please sign in to comment.