Skip to content

Commit

Permalink
Add Where()
Browse files Browse the repository at this point in the history
  • Loading branch information
aalmada committed Sep 10, 2023
1 parent 6ee5a97 commit 13e522b
Show file tree
Hide file tree
Showing 9 changed files with 259 additions and 23 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2018-2021 Antao Almada
Copyright (c) 2018-2023 Antao Almada

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand All @@ -7,7 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.0" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.8" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;netcoreapp3.1;net5.0</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="NetFabric.Assertive" Version="3.0.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
<PackageReference Include="NetFabric.Assertive" Version="4.0.0" />
<PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.msbuild" Version="3.0.3">
<PackageReference Include="coverlet.msbuild" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ public readonly struct ForwardEnumeration
internal ForwardEnumeration(DoublyLinkedList<T> list)
=> this.list = list;

public WhereForwardEnumeration Where(Func<T, bool> predicate)
=> new(list, predicate);

public int Count =>
list.count;

Expand Down Expand Up @@ -102,12 +105,12 @@ public bool MoveNext()
return current is not null;
}

public readonly void Reset()
=> Throw.NotSupportedException();
public void Reset()
=> current = null;

public readonly void Dispose()
{ }
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ public readonly struct ReverseEnumeration
internal ReverseEnumeration(DoublyLinkedList<T> list)
=> this.list = list;

public WhereReverseEnumeration Where(Func<T, bool> predicate)
=> new(list, predicate);

public int Count =>
list.count;

Expand Down Expand Up @@ -101,8 +104,8 @@ public bool MoveNext()
return current is not null;
}

public readonly void Reset()
=> Throw.NotSupportedException();
public void Reset()
=> current = null;

public readonly void Dispose()
{ }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using NetFabric.Hyperlinq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;

namespace NetFabric
{
public partial class DoublyLinkedList<T>
{
public readonly struct WhereForwardEnumeration
: IValueEnumerable<T, WhereForwardEnumeration.DisposableEnumerator>
{
readonly DoublyLinkedList<T> list;
readonly Func<T, bool> predicate;

internal WhereForwardEnumeration(DoublyLinkedList<T> list, Func<T, bool> predicate)
{
this.list = list;
this.predicate = predicate;
}

[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator() =>
new(list, predicate);

DisposableEnumerator IValueEnumerable<T, WhereForwardEnumeration.DisposableEnumerator>.GetEnumerator() =>
new(list, predicate);

IEnumerator<T> IEnumerable<T>.GetEnumerator() =>
new DisposableEnumerator(list, predicate);

IEnumerator IEnumerable.GetEnumerator() =>
new DisposableEnumerator(list, predicate);

public struct Enumerator
{
readonly DoublyLinkedList<T> list;
readonly Func<T, bool> predicate;
readonly int version;
Node? current;

internal Enumerator(DoublyLinkedList<T> list, Func<T, bool> predicate)
{
this.list = list;
this.predicate = predicate;
version = list.version;
current = null;
}

public readonly T Current
=> current!.Value;

public bool MoveNext()
{
if (version != list.version)
Throw.InvalidOperationException();
do
{
current = current is null
? list.First
: current.Next;
}
while (current is not null && !predicate(current.Value));
return current is not null;
}
}

public struct DisposableEnumerator
: IEnumerator<T>
{
readonly DoublyLinkedList<T> list;
readonly Func<T, bool> predicate;
readonly int version;
Node? current;

internal DisposableEnumerator(DoublyLinkedList<T> list, Func<T, bool> predicate)
{
this.list = list;
this.predicate = predicate;
version = list.version;
current = null;
}

public readonly T Current
=> current!.Value;
readonly object? IEnumerator.Current
=> current!.Value;

public bool MoveNext()
{
if (version != list.version)
Throw.InvalidOperationException();
do
{
current = current is null
? list.First
: current.Next;
}
while (current is not null && !predicate(current.Value));
return current is not null;
}

public void Reset()
=> current = null;

public readonly void Dispose()
{ }
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using NetFabric.Hyperlinq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;

namespace NetFabric
{
public partial class DoublyLinkedList<T>
{
public readonly struct WhereReverseEnumeration
: IValueEnumerable<T, WhereReverseEnumeration.DisposableEnumerator>
{
readonly DoublyLinkedList<T> list;
readonly Func<T, bool> predicate;

internal WhereReverseEnumeration(DoublyLinkedList<T> list, Func<T, bool> predicate)
{
this.list = list;
this.predicate = predicate;
}

[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator() =>
new(list, predicate);

DisposableEnumerator IValueEnumerable<T, WhereReverseEnumeration.DisposableEnumerator>.GetEnumerator() =>
new(list, predicate);

IEnumerator<T> IEnumerable<T>.GetEnumerator() =>
new DisposableEnumerator(list, predicate);

IEnumerator IEnumerable.GetEnumerator() =>
new DisposableEnumerator(list, predicate);

public struct Enumerator
{
readonly DoublyLinkedList<T> list;
readonly Func<T, bool> predicate;
readonly int version;
Node? current;

internal Enumerator(DoublyLinkedList<T> list, Func<T, bool> predicate)
{
this.list = list;
this.predicate = predicate;
version = list.version;
current = null;
}

public readonly T Current
=> current!.Value;

public bool MoveNext()
{
if (version != list.version)
Throw.InvalidOperationException();
do
{
current = current is null
? list.Last
: current.Previous;
}
while (current is not null && !predicate(current.Value));
return current is not null;
}
}

public struct DisposableEnumerator
: IEnumerator<T>
{
readonly DoublyLinkedList<T> list;
readonly Func<T, bool> predicate;
readonly int version;
Node? current;

internal DisposableEnumerator(DoublyLinkedList<T> list, Func<T, bool> predicate)
{
this.list = list;
this.predicate = predicate;
version = list.version;
current = null;
}

public readonly T Current
=> current!.Value;
readonly object? IEnumerator.Current
=> current!.Value;

public bool MoveNext()
{
if (version != list.version)
Throw.InvalidOperationException();
do
{
current = current is null
? list.Last
: current.Previous;
}
while (current is not null && !predicate(current.Value));
return current is not null;
}

public void Reset()
=> current = null;

public readonly void Dispose()
{ }
}
}
}
}
4 changes: 2 additions & 2 deletions NetFabric.DoublyLinkedList/DoublyLinkedList'1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ public void RemoveLast()
tail = node.Previous;
tail.Next = null;
}
node.Invalidate();
node!.Invalidate();
count--;
version++;
}
Expand Down Expand Up @@ -944,7 +944,7 @@ public void ReverseInPlace()
if (count < 2)
return;

Node temp;
Node? temp;
var current = head;
while (current is not null)
{
Expand Down
14 changes: 7 additions & 7 deletions NetFabric.DoublyLinkedList/NetFabric.DoublyLinkedList.csproj
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net461;netstandard2.0; net6.0</TargetFrameworks>
<PackageId>NetFabric.DoublyLinkedList</PackageId>
<Title>NetFabric.DoublyLinkedList</Title>
<Description>An alternative to System.Collection.Generics.LinkedList with reverse operation and enumeration without allocation.</Description>
<Version>3.0.0</Version>
<Version>3.1.0</Version>
<Authors>Antao Almada</Authors>
<Copyright>Copyright 2018-2021 Antao Almada</Copyright>
<Copyright>Copyright 2018-2023 Antao Almada</Copyright>
<PackageIcon>Icon.png</PackageIcon>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageTags>collections, data structures, algorithms, list</PackageTags>
Expand All @@ -29,16 +29,16 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Nullable" Version="1.3.0">
<PackageReference Include="Nullable" Version="1.3.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0">
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NetFabric.Hyperlinq.Abstractions" Version="1.3.0" />
<PackageReference Include="NetFabric.Hyperlinq.Analyzer" Version="2.0.3">
<PackageReference Include="NetFabric.Hyperlinq.Analyzer" Version="2.1.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down

0 comments on commit 13e522b

Please sign in to comment.