Skip to content

Commit f0e7729

Browse files
committed
Add EquatableArray<T> type
1 parent 39290dc commit f0e7729

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

CommunityToolkit.Mvvm.SourceGenerators/CommunityToolkit.Mvvm.SourceGenerators.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxNodeExtensions.cs" />
7070
<Compile Include="$(MSBuildThisFileDirectory)Extensions\TypeDeclarationSyntaxExtensions.cs" />
7171
<Compile Include="$(MSBuildThisFileDirectory)Helpers\Comparer{T,TSelf}.cs" />
72+
<Compile Include="$(MSBuildThisFileDirectory)Helpers\EquatableArray.cs" />
7273
<Compile Include="$(MSBuildThisFileDirectory)Helpers\HashCode.cs" />
7374
<Compile Include="$(MSBuildThisFileDirectory)Helpers\ImmutableArrayBuilder{T}.cs" />
7475
<Compile Include="$(MSBuildThisFileDirectory)Helpers\ObjectPool{T}.cs" />
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Collections.Immutable;
7+
using System.Diagnostics.CodeAnalysis;
8+
using System.Linq;
9+
using System.Runtime.CompilerServices;
10+
11+
namespace CommunityToolkit.Mvvm.SourceGenerators.Helpers;
12+
13+
/// <summary>
14+
/// An imutable, equatable array. This is equivalent to <see cref="ImmutableArray{T}"/> but with value equality support.
15+
/// </summary>
16+
/// <typeparam name="T">The type of values in the array.</typeparam>
17+
internal readonly struct EquatableArray<T> : IEquatable<EquatableArray<T>>
18+
where T : IEquatable<T>
19+
{
20+
/// <summary>
21+
/// The underlying <typeparamref name="T"/> array.
22+
/// </summary>
23+
private readonly T[]? array;
24+
25+
/// <summary>
26+
/// Creates a new <see cref="EquatableArray{T}"/> instance.
27+
/// </summary>
28+
/// <param name="array">The input <see cref="ImmutableArray{T}"/> to wrap.</param>
29+
public EquatableArray(ImmutableArray<T> array)
30+
{
31+
this.array = Unsafe.As<ImmutableArray<T>, T[]?>(ref array);
32+
}
33+
34+
/// <sinheritdoc/>
35+
public bool Equals(EquatableArray<T> array)
36+
{
37+
return AsImmutableArray().SequenceEqual(array.AsImmutableArray());
38+
}
39+
40+
/// <sinheritdoc/>
41+
public override bool Equals([NotNullWhen(true)] object? obj)
42+
{
43+
return obj is EquatableArray<T> array && Equals(this, array);
44+
}
45+
46+
/// <sinheritdoc/>
47+
public override int GetHashCode()
48+
{
49+
if (this.array is not T[] array)
50+
{
51+
return 0;
52+
}
53+
54+
HashCode hashCode = default;
55+
56+
foreach (T item in array)
57+
{
58+
hashCode.Add(item);
59+
}
60+
61+
return hashCode.ToHashCode();
62+
}
63+
64+
/// <summary>
65+
/// Gets an <see cref="ImmutableArray{T}"/> instance from the current <see cref="EquatableArray{T}"/>.
66+
/// </summary>
67+
/// <returns>The <see cref="ImmutableArray{T}"/> from the current <see cref="EquatableArray{T}"/>.</returns>
68+
public ImmutableArray<T> AsImmutableArray()
69+
{
70+
return Unsafe.As<T[]?, ImmutableArray<T>>(ref Unsafe.AsRef(in this.array));
71+
}
72+
73+
/// <summary>
74+
/// Creates an <see cref="EquatableArray{T}"/> instance from a given <see cref="ImmutableArray{T}"/>.
75+
/// </summary>
76+
/// <param name="array">The input <see cref="ImmutableArray{T}"/> instance.</param>
77+
/// <returns>An <see cref="EquatableArray{T}"/> instance from a given <see cref="ImmutableArray{T}"/>.</returns>
78+
public static EquatableArray<T> FromImmutableArray(ImmutableArray<T> array)
79+
{
80+
return new(array);
81+
}
82+
83+
/// <summary>
84+
/// Implicitly converts an <see cref="ImmutableArray{T}"/> to <see cref="EquatableArray{T}"/>.
85+
/// </summary>
86+
/// <returns>An <see cref="EquatableArray{T}"/> instance from a given <see cref="ImmutableArray{T}"/>.</returns>
87+
public static implicit operator EquatableArray<T>(ImmutableArray<T> array)
88+
{
89+
return FromImmutableArray(array);
90+
}
91+
92+
/// <summary>
93+
/// Implicitly converts an <see cref="EquatableArray{T}"/> to <see cref="ImmutableArray{T}"/>.
94+
/// </summary>
95+
/// <returns>An <see cref="ImmutableArray{T}"/> instance from a given <see cref="EquatableArray{T}"/>.</returns>
96+
public static implicit operator ImmutableArray<T>(EquatableArray<T> array)
97+
{
98+
return array.AsImmutableArray();
99+
}
100+
101+
/// <summary>
102+
/// Checks whether two <see cref="EquatableArray{T}"/> values are the same.
103+
/// </summary>
104+
/// <param name="left">The first <see cref="EquatableArray{T}"/> value.</param>
105+
/// <param name="right">The second <see cref="EquatableArray{T}"/> value.</param>
106+
/// <returns>Whether <paramref name="left"/> and <paramref name="right"/> are equal.</returns>
107+
public static bool operator ==(EquatableArray<T> left, EquatableArray<T> right)
108+
{
109+
return left.Equals(right);
110+
}
111+
112+
/// <summary>
113+
/// Checks whether two <see cref="EquatableArray{T}"/> values are not the same.
114+
/// </summary>
115+
/// <param name="left">The first <see cref="EquatableArray{T}"/> value.</param>
116+
/// <param name="right">The second <see cref="EquatableArray{T}"/> value.</param>
117+
/// <returns>Whether <paramref name="left"/> and <paramref name="right"/> are not equal.</returns>
118+
public static bool operator !=(EquatableArray<T> left, EquatableArray<T> right)
119+
{
120+
return !left.Equals(right);
121+
}
122+
}

0 commit comments

Comments
 (0)