From ad5b1f63cca2fd808fd09ced2ce82a555b2f4fbb Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Thu, 14 Apr 2022 23:43:56 -0400 Subject: [PATCH] Address PR feedback --- src/libraries/System.Memory/System.Memory.sln | 115 ++++++++++-------- .../tests/Span/CommonPrefixLength.T.cs | 92 ++++++++------ .../src/System/MemoryExtensions.cs | 62 ++++------ .../src/System/Xml/Core/XmlTextReaderImpl.cs | 2 +- 4 files changed, 145 insertions(+), 126 deletions(-) diff --git a/src/libraries/System.Memory/System.Memory.sln b/src/libraries/System.Memory/System.Memory.sln index 9315b9cbb51bf9..4573bcc5812309 100644 --- a/src/libraries/System.Memory/System.Memory.sln +++ b/src/libraries/System.Memory/System.Memory.sln @@ -1,4 +1,8 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32412.434 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", "..\..\coreclr\System.Private.CoreLib\System.Private.CoreLib.csproj", "{7746BFD6-E6D6-4703-AA2D-43380B5DEA22}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{6A54FACA-933E-4C1D-92AB-1A5506CFC212}" @@ -25,17 +29,23 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gen", "gen", "{2BEB1A89-DD2 EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Checked|Any CPU = Checked|Any CPU + Checked|x64 = Checked|x64 + Checked|x86 = Checked|x86 Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 - Checked|Any CPU = Checked|Any CPU - Checked|x64 = Checked|x64 - Checked|x86 = Checked|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Checked|Any CPU.ActiveCfg = Checked|x64 + {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Checked|Any CPU.Build.0 = Checked|x64 + {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Checked|x64.ActiveCfg = Checked|x64 + {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Checked|x64.Build.0 = Checked|x64 + {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Checked|x86.ActiveCfg = Checked|x86 + {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Checked|x86.Build.0 = Checked|x86 {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Debug|Any CPU.ActiveCfg = Debug|x64 {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Debug|Any CPU.Build.0 = Debug|x64 {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Debug|x64.ActiveCfg = Debug|x64 @@ -48,12 +58,12 @@ Global {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Release|x64.Build.0 = Release|x64 {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Release|x86.ActiveCfg = Release|x86 {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Release|x86.Build.0 = Release|x86 - {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Checked|Any CPU.ActiveCfg = Checked|x64 - {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Checked|Any CPU.Build.0 = Checked|x64 - {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Checked|x64.ActiveCfg = Checked|x64 - {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Checked|x64.Build.0 = Checked|x64 - {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Checked|x86.ActiveCfg = Checked|x86 - {7746BFD6-E6D6-4703-AA2D-43380B5DEA22}.Checked|x86.Build.0 = Checked|x86 + {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Checked|Any CPU.Build.0 = Debug|Any CPU + {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Checked|x64.ActiveCfg = Debug|Any CPU + {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Checked|x64.Build.0 = Debug|Any CPU + {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Checked|x86.ActiveCfg = Debug|Any CPU + {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Checked|x86.Build.0 = Debug|Any CPU {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Debug|Any CPU.Build.0 = Debug|Any CPU {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -66,12 +76,12 @@ Global {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Release|x64.Build.0 = Release|Any CPU {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Release|x86.ActiveCfg = Release|Any CPU {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Release|x86.Build.0 = Release|Any CPU - {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Checked|Any CPU.Build.0 = Debug|Any CPU - {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Checked|x64.ActiveCfg = Debug|Any CPU - {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Checked|x64.Build.0 = Debug|Any CPU - {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Checked|x86.ActiveCfg = Debug|Any CPU - {6A54FACA-933E-4C1D-92AB-1A5506CFC212}.Checked|x86.Build.0 = Debug|Any CPU + {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Checked|Any CPU.Build.0 = Debug|Any CPU + {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Checked|x64.ActiveCfg = Debug|Any CPU + {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Checked|x64.Build.0 = Debug|Any CPU + {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Checked|x86.ActiveCfg = Debug|Any CPU + {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Checked|x86.Build.0 = Debug|Any CPU {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Debug|Any CPU.Build.0 = Debug|Any CPU {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -84,12 +94,12 @@ Global {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Release|x64.Build.0 = Release|Any CPU {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Release|x86.ActiveCfg = Release|Any CPU {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Release|x86.Build.0 = Release|Any CPU - {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Checked|Any CPU.Build.0 = Debug|Any CPU - {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Checked|x64.ActiveCfg = Debug|Any CPU - {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Checked|x64.Build.0 = Debug|Any CPU - {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Checked|x86.ActiveCfg = Debug|Any CPU - {9112BAE3-344D-4DD0-ADC9-478D82B84584}.Checked|x86.Build.0 = Debug|Any CPU + {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Checked|Any CPU.Build.0 = Debug|Any CPU + {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Checked|x64.ActiveCfg = Debug|Any CPU + {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Checked|x64.Build.0 = Debug|Any CPU + {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Checked|x86.ActiveCfg = Debug|Any CPU + {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Checked|x86.Build.0 = Debug|Any CPU {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Debug|Any CPU.Build.0 = Debug|Any CPU {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -102,12 +112,12 @@ Global {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Release|x64.Build.0 = Release|Any CPU {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Release|x86.ActiveCfg = Release|Any CPU {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Release|x86.Build.0 = Release|Any CPU - {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Checked|Any CPU.Build.0 = Debug|Any CPU - {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Checked|x64.ActiveCfg = Debug|Any CPU - {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Checked|x64.Build.0 = Debug|Any CPU - {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Checked|x86.ActiveCfg = Debug|Any CPU - {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92}.Checked|x86.Build.0 = Debug|Any CPU + {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Checked|Any CPU.Build.0 = Debug|Any CPU + {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Checked|x64.ActiveCfg = Debug|Any CPU + {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Checked|x64.Build.0 = Debug|Any CPU + {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Checked|x86.ActiveCfg = Debug|Any CPU + {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Checked|x86.Build.0 = Debug|Any CPU {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Debug|Any CPU.Build.0 = Debug|Any CPU {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -120,12 +130,12 @@ Global {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Release|x64.Build.0 = Release|Any CPU {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Release|x86.ActiveCfg = Release|Any CPU {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Release|x86.Build.0 = Release|Any CPU - {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Checked|Any CPU.Build.0 = Debug|Any CPU - {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Checked|x64.ActiveCfg = Debug|Any CPU - {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Checked|x64.Build.0 = Debug|Any CPU - {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Checked|x86.ActiveCfg = Debug|Any CPU - {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297}.Checked|x86.Build.0 = Debug|Any CPU + {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Checked|Any CPU.Build.0 = Debug|Any CPU + {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Checked|x64.ActiveCfg = Debug|Any CPU + {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Checked|x64.Build.0 = Debug|Any CPU + {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Checked|x86.ActiveCfg = Debug|Any CPU + {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Checked|x86.Build.0 = Debug|Any CPU {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Debug|Any CPU.Build.0 = Debug|Any CPU {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -138,12 +148,12 @@ Global {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Release|x64.Build.0 = Release|Any CPU {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Release|x86.ActiveCfg = Release|Any CPU {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Release|x86.Build.0 = Release|Any CPU - {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Checked|Any CPU.Build.0 = Debug|Any CPU - {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Checked|x64.ActiveCfg = Debug|Any CPU - {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Checked|x64.Build.0 = Debug|Any CPU - {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Checked|x86.ActiveCfg = Debug|Any CPU - {EFF00253-633C-4D2F-86EE-F40C721F6A68}.Checked|x86.Build.0 = Debug|Any CPU + {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Checked|Any CPU.Build.0 = Debug|Any CPU + {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Checked|x64.ActiveCfg = Debug|Any CPU + {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Checked|x64.Build.0 = Debug|Any CPU + {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Checked|x86.ActiveCfg = Debug|Any CPU + {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Checked|x86.Build.0 = Debug|Any CPU {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Debug|Any CPU.Build.0 = Debug|Any CPU {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -156,12 +166,12 @@ Global {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Release|x64.Build.0 = Release|Any CPU {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Release|x86.ActiveCfg = Release|Any CPU {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Release|x86.Build.0 = Release|Any CPU - {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Checked|Any CPU.Build.0 = Debug|Any CPU - {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Checked|x64.ActiveCfg = Debug|Any CPU - {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Checked|x64.Build.0 = Debug|Any CPU - {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Checked|x86.ActiveCfg = Debug|Any CPU - {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7}.Checked|x86.Build.0 = Debug|Any CPU + {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Checked|Any CPU.Build.0 = Debug|Any CPU + {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Checked|x64.ActiveCfg = Debug|Any CPU + {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Checked|x64.Build.0 = Debug|Any CPU + {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Checked|x86.ActiveCfg = Debug|Any CPU + {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Checked|x86.Build.0 = Debug|Any CPU {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Debug|Any CPU.Build.0 = Debug|Any CPU {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -174,22 +184,16 @@ Global {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Release|x64.Build.0 = Release|Any CPU {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Release|x86.ActiveCfg = Release|Any CPU {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Release|x86.Build.0 = Release|Any CPU - {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Checked|Any CPU.Build.0 = Debug|Any CPU - {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Checked|x64.ActiveCfg = Debug|Any CPU - {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Checked|x64.Build.0 = Debug|Any CPU - {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Checked|x86.ActiveCfg = Debug|Any CPU - {DA7CEED7-1A86-4221-B4AD-4307AB83A31F}.Checked|x86.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {7746BFD6-E6D6-4703-AA2D-43380B5DEA22} = {C352AC7D-959D-431F-AF83-2CA506B70D59} - {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92} = {C352AC7D-959D-431F-AF83-2CA506B70D59} {6A54FACA-933E-4C1D-92AB-1A5506CFC212} = {FA259C32-B79B-4DE2-9677-055D5D25FA33} - {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297} = {FA259C32-B79B-4DE2-9677-055D5D25FA33} {9112BAE3-344D-4DD0-ADC9-478D82B84584} = {7212FBCF-E89D-4065-9DCE-D5F7E5D3EF1D} + {C9417154-D8DB-4FF9-9DD8-6B2ED351FC92} = {C352AC7D-959D-431F-AF83-2CA506B70D59} + {C2BC6AE7-7E8B-4AA2-8E9F-5D4B9127B297} = {FA259C32-B79B-4DE2-9677-055D5D25FA33} {EFF00253-633C-4D2F-86EE-F40C721F6A68} = {2BEB1A89-DD2D-42BD-95DD-89860A0C9663} {84AD7BF6-D76C-4BEE-9879-5A23150DD3F7} = {2BEB1A89-DD2D-42BD-95DD-89860A0C9663} {DA7CEED7-1A86-4221-B4AD-4307AB83A31F} = {2BEB1A89-DD2D-42BD-95DD-89860A0C9663} @@ -197,4 +201,7 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {65DB6A6B-0AAC-4BC2-A61A-641679771DC7} EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + ..\System.Private.CoreLib\src\System.Private.CoreLib.Shared.projitems*{7746bfd6-e6d6-4703-aa2d-43380b5dea22}*SharedItemsImports = 5 + EndGlobalSection EndGlobal diff --git a/src/libraries/System.Memory/tests/Span/CommonPrefixLength.T.cs b/src/libraries/System.Memory/tests/Span/CommonPrefixLength.T.cs index 7d02c5a2ccd4ca..c8ddc58d924d93 100644 --- a/src/libraries/System.Memory/tests/Span/CommonPrefixLength.T.cs +++ b/src/libraries/System.Memory/tests/Span/CommonPrefixLength.T.cs @@ -18,15 +18,7 @@ public static class CommonPrefixLengthTests [InlineData(0, 2)] public static void OneOrBothZeroLength_Returns0(int length1, int length2) { - Assert.Equal(0, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length1], new char[length2])); - Assert.Equal(0, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length1], new char[length2], null)); - Assert.Equal(0, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length1], new char[length2], EqualityComparer.Default)); - Assert.Equal(0, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length1], new char[length2], NonDefaultEqualityComparer.Instance)); - - Assert.Equal(0, MemoryExtensions.CommonPrefixLength((Span)new char[length1], new char[length2])); - Assert.Equal(0, MemoryExtensions.CommonPrefixLength((Span)new char[length1], new char[length2], null)); - Assert.Equal(0, MemoryExtensions.CommonPrefixLength((Span)new char[length1], new char[length2], EqualityComparer.Default)); - Assert.Equal(0, MemoryExtensions.CommonPrefixLength((Span)new char[length1], new char[length2], NonDefaultEqualityComparer.Instance)); + ValidateWithDefaultValues(length1, length2, NonDefaultEqualityComparer.Instance, 0); } [Theory] @@ -35,15 +27,7 @@ public static void OneOrBothZeroLength_Returns0(int length1, int length2) [InlineData(15)] public static void SameLengthAllEqual_ReturnsLength(int length) { - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length], new char[length])); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length], new char[length], null)); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length], new char[length], EqualityComparer.Default)); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length], new char[length], NonDefaultEqualityComparer.Instance)); - - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((Span)new char[length], new char[length])); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((Span)new char[length], new char[length], null)); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((Span)new char[length], new char[length], EqualityComparer.Default)); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((Span)new char[length], new char[length], NonDefaultEqualityComparer.Instance)); + ValidateWithDefaultValues(length, length, NonDefaultEqualityComparer.Instance, length); } [Theory] @@ -52,15 +36,7 @@ public static void SameLengthAllEqual_ReturnsLength(int length) [InlineData(15)] public static void FirstShorterAllEqual_ReturnsFirstLength(int length) { - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length], new char[length + 1])); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length], new char[length + 1], null)); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length], new char[length + 1], EqualityComparer.Default)); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length], new char[length + 1], NonDefaultEqualityComparer.Instance)); - - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((Span)new char[length], new char[length + 1])); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((Span)new char[length], new char[length + 1], null)); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((Span)new char[length], new char[length + 1], EqualityComparer.Default)); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((Span)new char[length], new char[length + 1], NonDefaultEqualityComparer.Instance)); + ValidateWithDefaultValues(length, length + 1, NonDefaultEqualityComparer.Instance, length); } [Theory] @@ -69,15 +45,20 @@ public static void FirstShorterAllEqual_ReturnsFirstLength(int length) [InlineData(15)] public static void SecondShorterAllEqual_ReturnsSecondLength(int length) { - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length + 1], new char[length])); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length + 1], new char[length], null)); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length + 1], new char[length], EqualityComparer.Default)); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new char[length + 1], new char[length], NonDefaultEqualityComparer.Instance)); - - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((Span)new char[length + 1], new char[length])); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((Span)new char[length + 1], new char[length], null)); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((Span)new char[length + 1], new char[length], EqualityComparer.Default)); - Assert.Equal(length, MemoryExtensions.CommonPrefixLength((Span)new char[length + 1], new char[length], NonDefaultEqualityComparer.Instance)); + ValidateWithDefaultValues(length + 1, length, NonDefaultEqualityComparer.Instance, length); + } + + private static void ValidateWithDefaultValues(int length1, int length2, IEqualityComparer customComparer, int expected) + { + Assert.Equal(expected, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new T[length1], new T[length2])); + Assert.Equal(expected, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new T[length1], new T[length2], null)); + Assert.Equal(expected, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new T[length1], new T[length2], EqualityComparer.Default)); + Assert.Equal(expected, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)new T[length1], new T[length2], customComparer)); + + Assert.Equal(expected, MemoryExtensions.CommonPrefixLength((Span)new T[length1], new T[length2])); + Assert.Equal(expected, MemoryExtensions.CommonPrefixLength((Span)new T[length1], new T[length2], null)); + Assert.Equal(expected, MemoryExtensions.CommonPrefixLength((Span)new T[length1], new T[length2], EqualityComparer.Default)); + Assert.Equal(expected, MemoryExtensions.CommonPrefixLength((Span)new T[length1], new T[length2], customComparer)); } [Fact] @@ -114,11 +95,50 @@ public static void PartialEquals_ReturnsPrefixLength_ReferenceType() Assert.Equal(4, MemoryExtensions.CommonPrefixLength((Span)arr1, arr2, NonDefaultEqualityComparer.Instance)); } + [Fact] + public static void Comparer_UsedInComparisons_ReferenceType() + { + string[] arr1 = new string[] { null, "a", null, "b", "c", "d", "e" }; + string[] arr2 = new string[] { null, "A", null, "B", "F", "G", "H" }; + + Assert.Equal(4, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)arr1, arr2, StringComparer.OrdinalIgnoreCase)); + Assert.Equal(4, MemoryExtensions.CommonPrefixLength((Span)arr1, arr2, StringComparer.OrdinalIgnoreCase)); + + Assert.Equal(1, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)arr1, arr2, NonDefaultEqualityComparer.Instance)); + Assert.Equal(1, MemoryExtensions.CommonPrefixLength((Span)arr1, arr2, NonDefaultEqualityComparer.Instance)); + + Assert.Equal(1, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)arr1, arr2, EqualityComparer.Default)); + Assert.Equal(1, MemoryExtensions.CommonPrefixLength((Span)arr1, arr2, EqualityComparer.Default)); + } + + [Fact] + public static void Comparer_UsedInComparisons_ValueType() + { + int[] arr1 = new[] { 1, 2, 3, 4, 5, 6 }; + int[] arr2 = new[] { -1, 2, -3, 4, -7, -8 }; + + Assert.Equal(4, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)arr1, arr2, AbsoluteValueComparer.Instance)); + Assert.Equal(4, MemoryExtensions.CommonPrefixLength((Span)arr1, arr2, AbsoluteValueComparer.Instance)); + + Assert.Equal(0, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)arr1, arr2, NonDefaultEqualityComparer.Instance)); + Assert.Equal(0, MemoryExtensions.CommonPrefixLength((Span)arr1, arr2, NonDefaultEqualityComparer.Instance)); + + Assert.Equal(0, MemoryExtensions.CommonPrefixLength((ReadOnlySpan)arr1, arr2, EqualityComparer.Default)); + Assert.Equal(0, MemoryExtensions.CommonPrefixLength((Span)arr1, arr2, EqualityComparer.Default)); + } + private sealed class NonDefaultEqualityComparer : IEqualityComparer { public static NonDefaultEqualityComparer Instance { get; } = new NonDefaultEqualityComparer(); public bool Equals(T? x, T? y) => EqualityComparer.Default.Equals(x, y); public int GetHashCode([DisallowNull] T obj) => EqualityComparer.Default.GetHashCode(obj); } + + private sealed class AbsoluteValueComparer : IEqualityComparer + { + public static AbsoluteValueComparer Instance { get; } = new AbsoluteValueComparer(); + public bool Equals(int x, int y) => Math.Abs(x) == Math.Abs(y); + public int GetHashCode(int x) => Math.Abs(x).GetHashCode(); + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs b/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs index 6dd7cf34d9aad4..560925d532fdf1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs @@ -2035,15 +2035,7 @@ public static int CommonPrefixLength(this ReadOnlySpan span, ReadOnlySpan< { // Shrink one of the spans if necessary to ensure they're both the same length. We can then iterate until // the Length of one of them and at least have bounds checks removed from that one. - if (other.Length > span.Length) - { - other = other.Slice(0, span.Length); - } - else if (span.Length > other.Length) - { - span = span.Slice(0, other.Length); - } - Debug.Assert(span.Length == other.Length); + SliceLongerSpanToMatchShorterLength(ref span, ref other); // Find the first element pairwise that is not equal, and return its index as the length // of the sequence before it that matches. @@ -2066,8 +2058,34 @@ public static int CommonPrefixLength(this ReadOnlySpan span, ReadOnlySpan< /// The length of the common prefix shared by the two spans. If there's no shared prefix, 0 is returned. public static int CommonPrefixLength(this ReadOnlySpan span, ReadOnlySpan other, IEqualityComparer? comparer) { + // If the comparer is null or the default, and T is a value type, we want to use EqualityComparer.Default.Equals + // directly to enable devirtualization. The non-comparer overload already does so, so just use it. + if (typeof(T).IsValueType && (comparer is null || comparer == EqualityComparer.Default)) + { + return CommonPrefixLength(span, other); + } + // Shrink one of the spans if necessary to ensure they're both the same length. We can then iterate until // the Length of one of them and at least have bounds checks removed from that one. + SliceLongerSpanToMatchShorterLength(ref span, ref other); + + // Ensure we have a comparer, then compare the spans. + comparer ??= EqualityComparer.Default; + for (int i = 0; i < span.Length; i++) + { + if (!comparer.Equals(span[i], other[i])) + { + return i; + } + } + + return span.Length; + } + + /// Determines if one span is longer than the other, and slices the longer one to match the length of the shorter. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SliceLongerSpanToMatchShorterLength(ref ReadOnlySpan span, ref ReadOnlySpan other) + { if (other.Length > span.Length) { other = other.Slice(0, span.Length); @@ -2077,32 +2095,6 @@ public static int CommonPrefixLength(this ReadOnlySpan span, ReadOnlySpan< span = span.Slice(0, other.Length); } Debug.Assert(span.Length == other.Length); - - // Find the first element pairwise that is not equal, and return its index as the length - // of the sequence before it that matches. - if (typeof(T).IsValueType && (comparer is null || comparer == EqualityComparer.Default)) // special-cased to enable devirtualization - { - for (int i = 0; i < span.Length; i++) - { - if (!EqualityComparer.Default.Equals(span[i], other[i])) - { - return i; - } - } - } - else - { - comparer ??= EqualityComparer.Default; - for (int i = 0; i < span.Length; i++) - { - if (!comparer.Equals(span[i], other[i])) - { - return i; - } - } - } - - return span.Length; } /// Writes the specified interpolated string to the character span. diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs index 47502038e8bd3b..97d01af0afba91 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs @@ -3269,7 +3269,7 @@ private void EatPreamble() Debug.Assert(_ps.encoding != null); Debug.Assert(_ps.bytes != null); ReadOnlySpan preamble = _ps.encoding.Preamble; - if (preamble.CommonPrefixLength(_ps.bytes.AsSpan(0, _ps.bytesUsed)) == preamble.Length) + if (_ps.bytes.AsSpan(0, _ps.bytesUsed).StartsWith(preamble)) { _ps.bytePos = preamble.Length; }