Skip to content

Commit 7157f8f

Browse files
committed
Add SortedSet.AsValueEnumerable
1 parent 2cb8155 commit 7157f8f

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

src/ZLinq/Linq/AsValueEnumerable.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ public static ValueEnumerable<FromHashSet<T>, T> AsValueEnumerable<T>(this HashS
8585
return new(new(Throws.IfNull(source)));
8686
}
8787

88+
public static ValueEnumerable<FromSortedSet<T>, T> AsValueEnumerable<T>(this SortedSet<T> source)
89+
{
90+
return new(new(Throws.IfNull(source)));
91+
}
92+
8893
#if NET8_0_OR_GREATER
8994

9095
public static ValueEnumerable<FromImmutableArray<T>, T> AsValueEnumerable<T>(this ImmutableArray<T> source)
@@ -974,6 +979,56 @@ public void Dispose()
974979
}
975980
}
976981

982+
[StructLayout(LayoutKind.Auto)]
983+
public struct FromSortedSet<T>(SortedSet<T> source) : IValueEnumerator<T>
984+
{
985+
bool isInit;
986+
SortedSet<T>.Enumerator enumerator;
987+
988+
// for Contains, need to check ICollection of IEqualityComparer due to compatibility
989+
internal SortedSet<T> GetSource() => source;
990+
991+
public bool TryGetNonEnumeratedCount(out int count)
992+
{
993+
count = source.Count;
994+
return true;
995+
}
996+
997+
public bool TryGetSpan(out ReadOnlySpan<T> span)
998+
{
999+
span = default;
1000+
return false;
1001+
}
1002+
1003+
public bool TryCopyTo(Span<T> destination, Index offset) => false;
1004+
1005+
public bool TryGetNext(out T current)
1006+
{
1007+
if (!isInit)
1008+
{
1009+
isInit = true;
1010+
enumerator = source.GetEnumerator();
1011+
}
1012+
1013+
if (enumerator.MoveNext())
1014+
{
1015+
current = enumerator.Current;
1016+
return true;
1017+
}
1018+
1019+
Unsafe.SkipInit(out current);
1020+
return false;
1021+
}
1022+
1023+
public void Dispose()
1024+
{
1025+
if (isInit)
1026+
{
1027+
enumerator.Dispose();
1028+
}
1029+
}
1030+
}
1031+
9771032
#if NET8_0_OR_GREATER
9781033
[StructLayout(LayoutKind.Auto)]
9791034
public struct FromImmutableArray<T>(ImmutableArray<T> source) : IValueEnumerator<T>

src/ZLinq/Linq/Contains.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ public static Boolean Contains<TSource>(this ValueEnumerable<FromHashSet<TSource
2929
return innerCollection.Contains(value);
3030
}
3131

32+
public static Boolean Contains<TSource>(this ValueEnumerable<FromSortedSet<TSource>, TSource> source, TSource value)
33+
{
34+
var innerCollection = source.Enumerator.GetSource();
35+
return innerCollection.Contains(value);
36+
}
37+
3238
public static Boolean Contains<TEnumerator, TSource>(this ValueEnumerable<TEnumerator, TSource> source, TSource value)
3339
where TEnumerator : struct, IValueEnumerator<TSource>
3440
#if NET9_0_OR_GREATER

tests/ZLinq.Tests/Linq/AsValueEnumerableTest.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,37 @@ public void FromHashSet_BasicFunctionality()
330330
resultArray.ShouldBe(source.ToArray(), ignoreOrder: true);
331331
}
332332

333+
[Fact]
334+
public void FromSortedSet_BasicFunctionality()
335+
{
336+
// Arrange
337+
var source = new SortedSet<int>(new[] { 5, 2, 1, 4, 3 });
338+
339+
// Act
340+
var result = source.AsValueEnumerable();
341+
342+
// Assert
343+
result.TryGetNonEnumeratedCount(out var count).ShouldBeTrue();
344+
count.ShouldBe(source.Count);
345+
346+
result.TryGetSpan(out var span).ShouldBeFalse();
347+
348+
var resultArray = result.ToArray();
349+
resultArray.ShouldBe(new[] { 1, 2, 3, 4, 5 }); // SortedSet should be ordered
350+
}
351+
352+
[Fact]
353+
public void FromSortedSet_ContainsOptimization()
354+
{
355+
// Arrange
356+
var source = new SortedSet<int>(new[] { 1, 2, 3, 4, 5 });
357+
var result = source.AsValueEnumerable();
358+
359+
// Act & Assert
360+
result.Contains(3).ShouldBeTrue();
361+
result.Contains(6).ShouldBeFalse();
362+
}
363+
333364
#if NET8_0_OR_GREATER
334365
[Fact]
335366
public void FromImmutableArray_BasicFunctionality()

0 commit comments

Comments
 (0)