Skip to content

Commit 4dc1a79

Browse files
committed
Common array EqualityComparers (for types that previously had specialized GetHashCode)
1 parent 0e7b688 commit 4dc1a79

File tree

1 file changed

+48
-42
lines changed

1 file changed

+48
-42
lines changed

src/fsharp/FSharp.Core/prim-types.fs

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,49 +1590,55 @@ namespace Microsoft.FSharp.Core
15901590
| true, ty when ty.Equals typeof<float32> -> box EqualityComparer<float32>.Default
15911591
| _ -> null
15921592

1593-
let arrayEqualityComparer<'T> er comparer =
1594-
let arrayEquals (er:bool) (iec:System.Collections.IEqualityComparer) (xobj:obj) (yobj:obj) : bool =
1595-
match xobj,yobj with
1596-
| null, null -> true
1597-
| null, _ -> false
1598-
| _, null -> false
1599-
| (:? (obj[]) as arr1), (:? (obj[]) as arr2) -> GenericEqualityObjArray er iec arr1 arr2
1600-
| _ ->
1601-
match xobj,yobj with
1602-
| (:? (byte[]) as arr1), (:? (byte[]) as arr2) -> GenericEqualityByteArray arr1 arr2
1603-
| _ ->
1604-
match xobj,yobj with
1605-
| (:? (int32[]) as arr1), (:? (int32[]) as arr2) -> GenericEqualityInt32Array arr1 arr2
1606-
| _ ->
1607-
match xobj,yobj with
1608-
| (:? (int64[]) as arr1), (:? (int64[]) as arr2) -> GenericEqualityInt64Array arr1 arr2
1609-
| _ ->
1610-
match xobj,yobj with
1611-
| (:? (char[]) as arr1), (:? (char[]) as arr2) -> GenericEqualityCharArray arr1 arr2
1612-
| _ ->
1613-
match xobj,yobj with
1614-
| (:? (float32[]) as arr1), (:? (float32[]) as arr2) -> GenericEqualitySingleArray er arr1 arr2
1615-
| _ ->
1616-
match xobj,yobj with
1617-
| (:? (float[]) as arr1), (:? (float[]) as arr2) -> GenericEqualityDoubleArray er arr1 arr2
1618-
| _ ->
1619-
match xobj,yobj with
1620-
| (:? System.Array as arr1), (:? System.Array as arr2) -> GenericEqualityArbArray er iec arr1 arr2
1621-
| _ -> raise (Exception "invalid logic - expected array")
1622-
1623-
let getHashCode (iec, xobj:obj) =
1624-
match xobj with
1625-
| null -> 0
1626-
| :? (obj[]) as oa -> GenericHashObjArray iec oa
1627-
| :? (byte[]) as ba -> GenericHashByteArray ba
1628-
| :? (int[]) as ba -> GenericHashInt32Array ba
1629-
| :? (int64[]) as ba -> GenericHashInt64Array ba
1630-
| :? System.Array as a -> GenericHashArbArray iec a
1631-
| _ -> raise (Exception "invalid logic - expected array")
1593+
let inline nullableEqualityComparer<'a when 'a : null> equals getHashCode =
1594+
box { new EqualityComparer<'a>() with
1595+
member __.Equals (x,y) =
1596+
match x, y with
1597+
| null, null -> true
1598+
| null, _ -> false
1599+
| _, null -> false
1600+
| _ -> equals x y
1601+
1602+
member __.GetHashCode x =
1603+
match x with
1604+
| null -> 0
1605+
| _ -> getHashCode x }
1606+
1607+
let tryGetFSharpArrayEqualityComparer (ty:Type) er comparer : obj =
1608+
if ty.Equals typeof<obj[]> then nullableEqualityComparer (fun x y -> GenericEqualityObjArray er comparer x y) (GenericHashObjArray fsEqualityComparerUnlimitedHashingPER)
1609+
elif ty.Equals typeof<byte[]> then nullableEqualityComparer GenericEqualityByteArray GenericHashByteArray
1610+
elif ty.Equals typeof<int32[]> then nullableEqualityComparer GenericEqualityInt32Array GenericHashInt32Array
1611+
elif ty.Equals typeof<int64[]> then nullableEqualityComparer GenericEqualityInt64Array GenericHashInt64Array
1612+
else null
16321613

1633-
{ new EqualityComparer<'T>() with
1634-
member __.Equals (x, y) = arrayEquals er comparer (box x) (box y)
1635-
member __.GetHashCode x = getHashCode (fsEqualityComparerUnlimitedHashingPER, box x) }
1614+
let arrayEqualityComparer<'T> er comparer =
1615+
match tryGetFSharpArrayEqualityComparer typeof<'T> er comparer with
1616+
| :? EqualityComparer<'T> as arrayComparer -> arrayComparer
1617+
| _ ->
1618+
{ new EqualityComparer<'T>() with
1619+
member __.Equals (x, y) =
1620+
let xobj, yobj = box x, box y
1621+
match xobj,yobj with
1622+
| null, null -> true
1623+
| null, _ -> false
1624+
| _, null -> false
1625+
| (:? (char[]) as arr1), (:? (char[]) as arr2) -> GenericEqualityCharArray arr1 arr2
1626+
| _ ->
1627+
match xobj,yobj with
1628+
| (:? (float32[]) as arr1), (:? (float32[]) as arr2) -> GenericEqualitySingleArray er arr1 arr2
1629+
| _ ->
1630+
match xobj,yobj with
1631+
| (:? (float[]) as arr1), (:? (float[])as arr2) -> GenericEqualityDoubleArray er arr1 arr2
1632+
| _ ->
1633+
match xobj,yobj with
1634+
| (:? System.Array as arr1), (:? System.Array as arr2) -> GenericEqualityArbArray er comparer arr1 arr2
1635+
| _ -> raise (Exception "invalid logic - expected array")
1636+
1637+
member __.GetHashCode x =
1638+
match box x with
1639+
| null -> 0
1640+
| :? System.Array as a -> GenericHashArbArray fsEqualityComparerUnlimitedHashingPER a
1641+
| _ -> raise (Exception "invalid logic - expected array") }
16361642

16371643
let structuralEqualityComparer<'T> comparer =
16381644
{ new EqualityComparer<'T>() with

0 commit comments

Comments
 (0)