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