Skip to content

Commit

Permalink
Add Union method; up dotnet to 9
Browse files Browse the repository at this point in the history
  • Loading branch information
Cadabra committed Nov 29, 2024
1 parent f4b0964 commit 093b1e8
Show file tree
Hide file tree
Showing 12 changed files with 236 additions and 10 deletions.
2 changes: 1 addition & 1 deletion samples/Benchmarks/Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand Down
2 changes: 1 addition & 1 deletion samples/SampleUsing/SampleUsing.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand Down
2 changes: 1 addition & 1 deletion samples/UsingWithFewSubranges/UsingWithFewSubranges.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand Down
2 changes: 1 addition & 1 deletion samples/UsingWithSubrange/UsingWithSubrange.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand Down
115 changes: 115 additions & 0 deletions src/DateRecurrenceR/Collections/UnionEnumerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using System.Collections;

namespace DateRecurrenceR.Collections;

internal struct UnionEnumerator : IEnumerator<DateOnly>
{
private readonly EWrapper[] _enumerators;
private DateOnly? _current = null;

public UnionEnumerator(IReadOnlyList<IEnumerator<DateOnly>> enumerators)
{
var hash = new HashSet<EWrapper>();

for (var i = 0; i < enumerators.Count; i++)
{
if (enumerators[i] is UnionEnumerator ue)
{
for (var j = 0; j < ue._enumerators.Length; j++)
{
hash.Add(ue._enumerators[j]);
}
}
else
{
hash.Add(new EWrapper(enumerators[i]));
}
}

_enumerators = hash.ToArray();

Current = default;
}

public bool MoveNext()
{
var nextIndex = -1;

for (var i = 0; i < _enumerators.Length; i++)
{
if (_current.HasValue)
{
while (_enumerators[i].CanMoveNext && _enumerators[i].Enum.Current <= _current.Value)
{
_enumerators[i].MoveNext();
}
}
else
{
_enumerators[i].MoveNext();
}
}

for (var i = 0; i < _enumerators.Length; i++)
{
if (!_enumerators[i].CanMoveNext) continue;

_current = _enumerators[i].Enum.Current;
nextIndex = i;
break;
}

for (var i = 0; i < _enumerators.Length; i++)
{
if (!_enumerators[i].CanMoveNext || !(_current > _enumerators[i].Enum.Current)) continue;

_current = _enumerators[i].Enum.Current;
nextIndex = i;
}

if (nextIndex < 0)
{
return false;
}

Current = _enumerators[nextIndex].Enum.Current;

return true;
}

public void Reset()
{
throw new NotSupportedException();
}

public DateOnly Current { get; private set; }

object IEnumerator.Current => Current;

public void Dispose()
{
}

private struct EWrapper
{
public EWrapper(IEnumerator<DateOnly> @enum)
{
Enum = @enum;
CanMoveNext = true;
}

public IEnumerator<DateOnly> Enum { get; }
public bool CanMoveNext { get; private set; }

public bool MoveNext()
{
CanMoveNext = Enum.MoveNext();
return CanMoveNext;
}

public override int GetHashCode()
{
return Enum.GetHashCode();
}
}
}
2 changes: 1 addition & 1 deletion src/DateRecurrenceR/Core/IInt32Based.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace DateRecurrenceR.Core;
///
/// </summary>
/// <typeparam name="TSelf"></typeparam>
#if NET8_0
#if NET8_0_OR_GREATER
public interface IInt32Based<TSelf> : IEquatable<TSelf>, IEqualityOperators<TSelf, TSelf, bool>, IMinMaxValue<TSelf>
where TSelf : IInt32Based<TSelf>;
#endif
2 changes: 1 addition & 1 deletion src/DateRecurrenceR/DateRecurrenceR.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<Version>0.5.3-beta.2</Version>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<ImplicitUsings>enable</ImplicitUsings>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>net6.0;net8.0;net9.0</TargetFrameworks>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<Deterministic>true</Deterministic>
Expand Down
10 changes: 10 additions & 0 deletions src/DateRecurrenceR/Recurrence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ public readonly partial struct Recurrence
{
private static readonly EmptyEnumerator EmptyEnumerator = new();

public static IEnumerator<DateOnly> Union(IEnumerator<DateOnly> d1, IEnumerator<DateOnly> d2)
{
return new UnionEnumerator(new[] {d1, d2});
}

public static IEnumerator<DateOnly> Union(params IEnumerator<DateOnly>[] enumerators)
{
return new UnionEnumerator(enumerators);
}

private static DateOnly DateOnlyMin(DateOnly val1, DateOnly val2)
{
return val1 <= val2 ? val1 : val2;
Expand Down
4 changes: 2 additions & 2 deletions src/DateRecurrenceR/WeekDays.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ namespace DateRecurrenceR;

public sealed class WeekDays
{
#if NET8_0
#if NET8_0_OR_GREATER
private readonly WeekDaysArray _ds = new WeekDaysArray();
#else
private readonly bool[] _ds = new bool[DaysInWeek];
Expand Down Expand Up @@ -38,7 +38,7 @@ public WeekDays(DayOfWeek day1, DayOfWeek day2, DayOfWeek day3, DayOfWeek day4,
{
}

#if NET8_0
#if NET8_0_OR_GREATER
public WeekDays(WeekDaysArray daysArray)
{
MinDay = (DayOfWeek) DaysInWeek;
Expand Down
2 changes: 1 addition & 1 deletion src/DateRecurrenceR/WeekDaysArray.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#if NET8_0
#if NET8_0_OR_GREATER
namespace DateRecurrenceR;

[System.Runtime.CompilerServices.InlineArray(7)]
Expand Down
101 changes: 101 additions & 0 deletions test/DateRecurrenceR.Tests.Unit/Collections/UnionEnumeratorTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using DateRecurrenceR.Collections;
using DateRecurrenceR.Core;
using FluentAssertions;
using JetBrains.Annotations;

namespace DateRecurrenceR.Tests.Unit.Collections;

[TestSubject(typeof(UnionEnumerator))]
public class UnionEnumeratorTest
{
[Fact]
public void Union_two_recurrences()
{
// Arrange
const int takeCount = 5;
var interval = new Interval(1);
var beginDate = DateOnly.MinValue;
var fromDate = beginDate;

var enumerator1 = Recurrence.Yearly(beginDate, fromDate, takeCount, new DayOfYear(1), interval);
var enumerator2 = Recurrence.Yearly(beginDate, fromDate, takeCount, new DayOfYear(2), interval);

var res = Recurrence.Union(enumerator1, enumerator2);

// Act
var list = new List<DateOnly>();

while (res.MoveNext())
{
list.Add(res.Current);
}

//Assert
list.Count.Should().Be(takeCount * 2);
}

[Fact]
public void Union_one_recurrence_multiple_times()
{
// Arrange
const int takeCount = 5;
var dayOfYear = new DayOfYear(256);
var interval = new Interval(1);
var beginDate = DateOnly.MinValue;
var fromDate = beginDate;

var equivalentEnumerator = Recurrence.Yearly(beginDate, fromDate, takeCount, dayOfYear, interval);
var enumerator = Recurrence.Yearly(beginDate, fromDate, takeCount, dayOfYear, interval);

var res = Recurrence.Union(enumerator, enumerator, enumerator, enumerator);
res = Recurrence.Union(res, enumerator, enumerator, enumerator);
res = Recurrence.Union(res, enumerator, enumerator);
res = Recurrence.Union(res, enumerator);

// Act
var equivalentList = new List<DateOnly>();
while (equivalentEnumerator.MoveNext())
{
equivalentList.Add(equivalentEnumerator.Current);
}

var list = new List<DateOnly>();
while (res.MoveNext())
{
list.Add(res.Current);
}

//Assert
list.Count.Should().Be(takeCount);
list.Should().BeEquivalentTo(equivalentList);
}

[Fact]
public void Union_two_recurrence_multiple_times()
{
// Arrange
const int takeCount = 5;
var interval = new Interval(1);
var beginDate = DateOnly.MinValue;
var fromDate = beginDate;

var enumerator1 = Recurrence.Yearly(beginDate, fromDate, takeCount, new DayOfYear(1), interval);
var enumerator2 = Recurrence.Yearly(beginDate, fromDate, takeCount, new DayOfYear(2), interval);

var res1 = Recurrence.Union(enumerator1, enumerator1, enumerator1, enumerator1);
var res2 = Recurrence.Union(enumerator2, enumerator2, enumerator2, enumerator2);
var res = Recurrence.Union(res1, res2);
res = Recurrence.Union(res, res1, enumerator2, enumerator1);
res = Recurrence.Union(res, res2, enumerator1, enumerator2);

// Act
var list = new List<DateOnly>();
while (res.MoveNext())
{
list.Add(res.Current);
}

//Assert
list.Count.Should().Be(takeCount * 2);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
Expand Down

0 comments on commit 093b1e8

Please sign in to comment.