Skip to content

Commit

Permalink
Merge pull request #49 from pfpack/release/v1.2.0-rc.2
Browse files Browse the repository at this point in the history
release/v1.2.0-rc.2
  • Loading branch information
andreise authored Aug 23, 2023
2 parents 98856bb + ff65948 commit 299b8aa
Show file tree
Hide file tree
Showing 18 changed files with 109 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal Builder AddRange([AllowNull] T[] items, int length)
{
var itemsLength = items?.Length ?? default;

if (InnerAllocHelper.IsWithin(length, itemsLength) is not true)
if (InnerAllocHelper.IsWithinLength(length, itemsLength) is not true)
{
throw InnerExceptionFactory.StartSegmentIsNotWithinArray(nameof(length), length, itemsLength);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal Builder AddRange(FlatArray<T>? items, int length)
private Builder InnerAddRangeChecked(
FlatArray<T> items, int length, [CallerArgumentExpression(nameof(length))] string lengthParamName = "")
{
if (InnerAllocHelper.IsWithin(length, items.length) is not true)
if (InnerAllocHelper.IsWithinLength(length, items.length) is not true)
{
throw InnerExceptionFactory.StartSegmentIsNotWithinArray(lengthParamName, length, items.length);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ private Builder InnerAddRangeChecked(
{
var itemsLength = items.IsDefault ? default : items.Length;

if (InnerAllocHelper.IsWithin(length, itemsLength) is not true)
if (InnerAllocHelper.IsWithinLength(length, itemsLength) is not true)
{
throw InnerExceptionFactory.StartSegmentIsNotWithinArray(lengthParamName, length, itemsLength);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;

namespace System;

partial struct FlatArray<T>
{
partial class Builder
{
// TODO: Add the tests and make public
internal Builder AddRange([AllowNull] List<T> items)
{
if (items is null || items.Count == default)
{
return this;
}

InnerAddRange(items, items.Count);
return this;
}

// TODO: Add the tests and make public
internal Builder AddRange([AllowNull] List<T> items, int length)
{
var itemsLength = items?.Count ?? default;

if (InnerAllocHelper.IsWithinLength(length, itemsLength) is not true)
{
throw InnerExceptionFactory.StartSegmentIsNotWithinArray(nameof(length), length, itemsLength);
}

if (items is null || items.Count == default)
{
return this;
}

InnerAddRange(items, length);
return this;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void InnerAddRange(List<T> items, int length)
{
Debug.Assert(items.Count != default);
Debug.Assert(length > 0 && length <= items.Count);

InnerBufferHelperEx.EnsureBufferCapacity(ref this.items, this.length, length);
items.CopyTo(0, this.items, this.length, length);
this.length += length;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ internal int Capacity

set
{
if (InnerAllocHelper.IsWithin(length, value) is not true)
if (value >= length is not true)
{
throw InnerBuilderExceptionFactory.CapacityOutOfRange_MustBeGreaterThanOrEqualToLength(value, length);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ partial class Builder
{
private static class InnerBufferHelperEx
{
// The caller MUST ensure the length and the length increase are GREATER than zero
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void EnsureBufferCapacity(
ref T[] array,
Expand All @@ -20,8 +19,8 @@ internal static void EnsureBufferCapacity(
Debug.Assert(lengthIncrease >= 0);

int newLength = unchecked(length + lengthIncrease);
int doubleLength = length << 1; // unchecked(length * 2);
int newCapacity = unchecked((uint)newLength) > unchecked((uint)doubleLength)
int doubleLength = InnerAllocHelper.DoubleUnchecked(length);
int newCapacity = InnerAllocHelper.IsWithinCapacityUnchecked(doubleLength, newLength)
? newLength
: doubleLength;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ internal static FlatArray<T> InternalFromArrayChecked([AllowNull] T[] source, in
{
var sourceLength = source?.Length ?? default;

if (InnerAllocHelper.IsSegmentWithin(start, length, sourceLength) is not true)
if (InnerAllocHelper.IsSegmentWithinLength(start, length, sourceLength) is not true)
{
throw InnerExceptionFactory.SegmentIsNotWithinArray(start, length, sourceLength);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ internal static FlatArray<T> From(FlatArray<T>? source, int start, int length)

internal static FlatArray<T> InternalFromFlatArrayChecked(FlatArray<T> source, int start, int length)
{
if (InnerAllocHelper.IsSegmentWithin(start, length, source.length) is not true)
if (InnerAllocHelper.IsSegmentWithinLength(start, length, source.length) is not true)
{
throw InnerExceptionFactory.SegmentIsNotWithinArray(start, length, source.length);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ internal static FlatArray<T> InternalFromImmutableArrayChecked(ImmutableArray<T>
{
var sourceLength = source.IsDefault ? default : source.Length;

if (InnerAllocHelper.IsSegmentWithin(start, length, sourceLength) is not true)
if (InnerAllocHelper.IsSegmentWithinLength(start, length, sourceLength) is not true)
{
throw InnerExceptionFactory.SegmentIsNotWithinArray(start, length, sourceLength);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ internal static FlatArray<T> InternalFromListChecked([AllowNull] List<T> source,
{
var sourceLength = source?.Count ?? default;

if (InnerAllocHelper.IsSegmentWithin(start, length, sourceLength) is not true)
if (InnerAllocHelper.IsSegmentWithinLength(start, length, sourceLength) is not true)
{
throw InnerExceptionFactory.SegmentIsNotWithinArray(start, length, sourceLength);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ private static class InnerAllocHelper
{
internal const int DefaultPositiveCapacity = 4;

// The caller MUST ensure the length is GREATER than or EQUAL to zero
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool IsIndexInRange(int index, int length)
{
Expand All @@ -19,56 +18,75 @@ internal static bool IsIndexInRange(int index, int length)
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool IsWithin(int value, int threshold)
=>
unchecked((uint)value) <= unchecked((uint)threshold);
internal static bool IsWithinLength(int value, int length)
{
Debug.Assert(value >= 0);
Debug.Assert(length >= 0);

return InnerIsWithinUnchecked(value, length);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool IsSegmentWithin(int start, int length, int threshold)
internal static bool IsSegmentWithinLength(int segmentStart, int segmentLength, int length)
{
Debug.Assert(segmentStart >= 0);
Debug.Assert(segmentLength >= 0);
Debug.Assert(length >= 0);

return (ulong)unchecked((uint)segmentStart) + unchecked((uint)segmentLength) <= unchecked((uint)length);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool IsWithinCapacityUnchecked(int value, int capacity)
=>
(ulong)unchecked((uint)start) + unchecked((uint)length) <= unchecked((uint)threshold);
InnerIsWithinUnchecked(value, capacity);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int EnsurePositiveCapacity(int capacity)
=>
capacity > 0 ? capacity : DefaultPositiveCapacity;
{
Debug.Assert(capacity >= 0);

return capacity > 0 ? capacity : DefaultPositiveCapacity;
}

// The caller MUST ensure the capacity is GREATER than or EQUAL to zero
internal static int EnsureCapacityWithinDefaultPositive(int capacity)
{
Debug.Assert(capacity >= 0);

return IsWithin(capacity, DefaultPositiveCapacity) ? capacity : DefaultPositiveCapacity;
return InnerIsWithinUnchecked(capacity, DefaultPositiveCapacity) ? capacity : DefaultPositiveCapacity;
}

// The caller MUST ensure the capacity is GREATER than zero and LESS than the max capacity
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int EnlargeCapacity(int capacity, int maxCapacity)
{
Debug.Assert(capacity > 0 && capacity < maxCapacity);

int newCapacity = InnerDoubleUnchecked(capacity);
return IsWithin(newCapacity, maxCapacity) ? newCapacity : maxCapacity;
int newCapacity = DoubleUnchecked(capacity);
return InnerIsWithinUnchecked(newCapacity, maxCapacity) ? newCapacity : maxCapacity;
}

// The caller MUST ensure the length is GREATER than zero and LESS than or EQUAL to the capacity
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool IsHugeCapacity(int length, int capacity)
{
Debug.Assert(length > 0 && length <= capacity);

if (IsWithin(capacity, DefaultPositiveCapacity))
if (InnerIsWithinUnchecked(capacity, DefaultPositiveCapacity))
{
return false;
}

int doubleLength = InnerDoubleUnchecked(length);
return IsWithin(doubleLength, capacity);
int doubleLength = DoubleUnchecked(length);
return InnerIsWithinUnchecked(doubleLength, capacity);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int InnerDoubleUnchecked(int value)
internal static int DoubleUnchecked(int value)
=>
value << 1; // unchecked(value * 2);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool InnerIsWithinUnchecked(int value, int threshold)
=>
unchecked((uint)value) <= unchecked((uint)threshold);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ internal static T[] Copy(T[] array)
=>
new ReadOnlySpan<T>(array).ToArray();

// The caller MUST ensure the length is within the array length
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static T[] Copy(T[] array, int length)
{
Expand All @@ -24,19 +23,17 @@ internal static T[] Copy(T[] array, int length)
return sourceSpan.ToArray();
}

// The caller MUST ensure the segment is within the array
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static T[] CopySegment(T[] array, int start, int length)
{
Debug.Assert(InnerAllocHelper.IsSegmentWithin(start, length, array.Length));
Debug.Assert(InnerAllocHelper.IsSegmentWithinLength(start, length, array.Length));

var sourceSpan = start == default && length == array.Length
? new ReadOnlySpan<T>(array)
: new ReadOnlySpan<T>(array, start, length);
return sourceSpan.ToArray();
}

// The caller MUST ensure the lengths are within the arrays actual lengths
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static T[] Concat(T[] array1, int length1, T[] array2, int length2)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal static FlatArray<T> FromArray(T[] source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static FlatArray<T> FromArray(T[] source, int start, int length)
{
Debug.Assert(InnerAllocHelper.IsSegmentWithin(start, length, source.Length));
Debug.Assert(InnerAllocHelper.IsSegmentWithinLength(start, length, source.Length));

return length == default ? default : new(InnerArrayHelper.CopySegment(source, start, length), default);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal static FlatArray<T> FromFlatArray(FlatArray<T> source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static FlatArray<T> FromFlatArray(FlatArray<T> source, int start, int length)
{
Debug.Assert(InnerAllocHelper.IsSegmentWithin(start, length, source.length));
Debug.Assert(InnerAllocHelper.IsSegmentWithinLength(start, length, source.length));

return length == default ? default : new(InnerArrayHelper.CopySegment(source.items!, start, length), default);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ internal static FlatArray<T> FromImmutableArray(ImmutableArray<T> source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static FlatArray<T> FromImmutableArray(ImmutableArray<T> source, int start, int length)
{
Debug.Assert(InnerAllocHelper.IsSegmentWithin(start, length, source.IsDefault ? default : source.Length));
Debug.Assert(InnerAllocHelper.IsSegmentWithinLength(start, length, source.IsDefault ? default : source.Length));

if (source.IsDefaultOrEmpty)
if (length == default)
{
return default;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ internal static FlatArray<T> FromList(List<T> source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static FlatArray<T> FromList(List<T> source, int start, int length)
{
Debug.Assert(InnerAllocHelper.IsSegmentWithin(start, length, source.Count));
Debug.Assert(InnerAllocHelper.IsSegmentWithinLength(start, length, source.Count));

if (length == default)
{
Expand Down
2 changes: 1 addition & 1 deletion src/flatcollections-array/FlatArray/FlatArray.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<Description>PrimeFuncPack Core.FlatArray is a core library for .NET consisting of immutable FlatArray targeted for use in functional programming.</Description>
<RootNamespace>System</RootNamespace>
<AssemblyName>PrimeFuncPack.Core.FlatArray</AssemblyName>
<Version>1.2.0-rc.1</Version>
<Version>1.2.0-rc.2</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/flatcollections/FlatCollections/FlatCollections.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<Description>PrimeFuncPack Core.FlatCollections is a set of immutable Flat collections for .NET designed for developing business applications based on functional programming.</Description>
<RootNamespace>System</RootNamespace>
<AssemblyName>PrimeFuncPack.Core.FlatCollections</AssemblyName>
<Version>1.2.0-rc.1</Version>
<Version>1.2.0-rc.2</Version>
</PropertyGroup>

<ItemGroup>
Expand All @@ -32,7 +32,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="PrimeFuncPack.Core.FlatArray" Version="1.2.0-rc.1" />
<PackageReference Include="PrimeFuncPack.Core.FlatArray" Version="1.2.0-rc.2" />
</ItemGroup>

</Project>

0 comments on commit 299b8aa

Please sign in to comment.