From 2333e7b8059e307ed86191f772a48b44396d0016 Mon Sep 17 00:00:00 2001 From: kzrnm Date: Tue, 24 Jan 2023 08:55:45 +0900 Subject: [PATCH 1/9] Make SourceExpander.Embedder switchable --- Directory.Build.props | 3 + .../ac-library-csharp/Internal/InternalBit.cs | 4 +- .../ac-library-csharp/Math/DynamicModInt.cs | 12 +- Source/ac-library-csharp/Math/StaticModInt.cs | 10 +- Source/ac-library-csharp/String/StringLib.cs | 4 +- .../ac-library-csharp.csproj | 110 +++++++++--------- .../SourceExpanderTest.cs | 19 ++- 7 files changed, 92 insertions(+), 70 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index e8dbdcb..95ddb0b 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -16,6 +16,9 @@ $(MSBuildThisFileDirectory)bin\Packages\$(Configuration)\ + true + $(DefineConstants);EMBEDDING + true true snupkg diff --git a/Source/ac-library-csharp/Internal/InternalBit.cs b/Source/ac-library-csharp/Internal/InternalBit.cs index fe831a4..5d66101 100644 --- a/Source/ac-library-csharp/Internal/InternalBit.cs +++ b/Source/ac-library-csharp/Internal/InternalBit.cs @@ -37,7 +37,9 @@ public static uint ExtractLowestSetBit(int n) [MethodImpl(256)] public static int Bsf(uint n) { - //Contract.Assert(n > 0, reason: $"{nameof(n)} must positive"); +#if EMBEDDING + Contract.Assert(n > 0, reason: $"{nameof(n)} must positive"); +#endif return BitOperations.TrailingZeroCount(n); } diff --git a/Source/ac-library-csharp/Math/DynamicModInt.cs b/Source/ac-library-csharp/Math/DynamicModInt.cs index 634abd6..5e572ad 100644 --- a/Source/ac-library-csharp/Math/DynamicModInt.cs +++ b/Source/ac-library-csharp/Math/DynamicModInt.cs @@ -1,8 +1,10 @@ using System; -using System.Globalization; -using System.Numerics; using System.Runtime.CompilerServices; using AtCoder.Internal; +#if GENERIC_MATH +using System.Globalization; +using System.Numerics; +#endif namespace AtCoder { @@ -88,8 +90,10 @@ public static int Mod public static DynamicModInt Raw(int v) { var u = unchecked((uint)v); - //Contract.Assert(bt != null, $"{nameof(DynamicModInt)}<{nameof(T)}>.{nameof(Mod)} is undefined."); - //Contract.Assert(u < Mod, $"{nameof(u)} must be less than {nameof(Mod)}."); +#if EMBEDDING + Contract.Assert(bt != null, $"{nameof(DynamicModInt)}<{nameof(T)}>.{nameof(Mod)} is undefined."); + Contract.Assert(u < Mod, $"{nameof(u)} must be less than {nameof(Mod)}."); +#endif return new DynamicModInt(u); } diff --git a/Source/ac-library-csharp/Math/StaticModInt.cs b/Source/ac-library-csharp/Math/StaticModInt.cs index 653e9e1..a3f6e8e 100644 --- a/Source/ac-library-csharp/Math/StaticModInt.cs +++ b/Source/ac-library-csharp/Math/StaticModInt.cs @@ -1,8 +1,10 @@ using System; -using System.Globalization; -using System.Numerics; using System.Runtime.CompilerServices; using AtCoder.Internal; +#if GENERIC_MATH +using System.Globalization; +using System.Numerics; +#endif namespace AtCoder { @@ -92,7 +94,9 @@ public readonly struct StaticModInt public static StaticModInt Raw(int v) { var u = unchecked((uint)v); - //Contract.Assert(u < Mod, $"{nameof(u)} must be less than {nameof(Mod)}."); +#if EMBEDDING + Contract.Assert(u < Mod, $"{nameof(u)} must be less than {nameof(Mod)}."); +#endif return new StaticModInt(u); } diff --git a/Source/ac-library-csharp/String/StringLib.cs b/Source/ac-library-csharp/String/StringLib.cs index c1ace4e..853af7f 100644 --- a/Source/ac-library-csharp/String/StringLib.cs +++ b/Source/ac-library-csharp/String/StringLib.cs @@ -151,7 +151,9 @@ static int[] CreateIdx(ReadOnlySpan m) public static int[] SuffixArray(int[] s, int upper) { Contract.Assert(0 <= upper, reason: $"{nameof(upper)} must be positive."); - //Contract.Assert(s.All(si => (uint)si <= (uint)upper), reason: $"si ∈ {nameof(s)} must be 0 <= si && si <= {nameof(upper)}"); +#if EMBEDDING + Contract.Assert(s.All(si => (uint)si <= (uint)upper), reason: $"si ∈ {nameof(s)} must be 0 <= si && si <= {nameof(upper)}"); +#endif return InternalString.SaIs(s, upper); } #endregion SuffixArray diff --git a/Source/ac-library-csharp/ac-library-csharp.csproj b/Source/ac-library-csharp/ac-library-csharp.csproj index fee010c..57ad6bf 100644 --- a/Source/ac-library-csharp/ac-library-csharp.csproj +++ b/Source/ac-library-csharp/ac-library-csharp.csproj @@ -1,69 +1,69 @@  - - net7.0;netcoreapp3.1;netstandard2.1 - AtCoder - Library + + net7.0;netcoreapp3.1;netstandard2.1 + AtCoder + Library - 7.3 - 8 - 11 + 7.3 + 8 + 11 - false + false - ac-library-csharp;AtCoder - ac-library-csharp - C# port of ac-library - true - true + ac-library-csharp;AtCoder + ac-library-csharp + C# port of ac-library + true + true - $(NoWarn);CS1574;CA1034;CS1591;CS1734;IDE0039;IDE0057 + $(NoWarn);CS1574;CA1034;CS1591;CS1734;IDE0039;IDE0057 - - LICENSE + + LICENSE - $(DefineConstants);ATCODER_CONTRACT + $(DefineConstants);ATCODER_CONTRACT - true - $(DefineConstants);GENERIC_MATH - - - - + true + $(DefineConstants);GENERIC_MATH + + + + - - - - + + + + - - - false - Analyzer - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + + + false + Analyzer + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + - - - - True - True - MathLib.Convolution.Primitives.tt - - - TextTemplatingFileGenerator - MathLib.Convolution.Primitives.cs - - - - True - True - MathLib.Convolution.Primitives.tt - - + + + + True + True + MathLib.Convolution.Primitives.tt + + + TextTemplatingFileGenerator + MathLib.Convolution.Primitives.cs + + + + True + True + MathLib.Convolution.Primitives.tt + + diff --git a/Test/ac-library-csharp.Test/SourceExpanderTest.cs b/Test/ac-library-csharp.Test/SourceExpanderTest.cs index d96b042..80208ed 100644 --- a/Test/ac-library-csharp.Test/SourceExpanderTest.cs +++ b/Test/ac-library-csharp.Test/SourceExpanderTest.cs @@ -8,6 +8,13 @@ namespace AtCoder.Embedding { public class SourceExpanderTest { + class EmbeddingFact : FactAttribute + { +#if !EMBEDDING + public override string Skip => "SourceExpander.Embedder is disabled."; +#endif + } + #if NETCOREAPP3_0 const bool useIntrinsics = false; const string languageVersion = "7.3"; @@ -19,13 +26,13 @@ public class SourceExpanderTest const string languageVersion = "11.0"; #endif - [Fact] + [EmbeddingFact] public void AssemblyName() { typeof(Segtree<,>).Assembly.GetName().Name.Should().Be("ac-library-csharp"); } - [Fact] + [EmbeddingFact] public async Task Symbol() { var embedded = await EmbeddedData.LoadFromAssembly(typeof(Segtree<,>)); @@ -41,7 +48,7 @@ public async Task Symbol() .Be(useIntrinsics); } - [Fact] + [EmbeddingFact] public async Task LanguageVersion() { var embedded = await EmbeddedData.LoadFromAssembly(typeof(Segtree<,>)); @@ -50,7 +57,7 @@ public async Task LanguageVersion() .WhoseValue.Should().Be(languageVersion); } - [Fact] + [EmbeddingFact] public async Task EmbeddedSource() { var embedded = await EmbeddedData.LoadFromAssembly(typeof(Segtree<,>)); @@ -67,7 +74,7 @@ public async Task EmbeddedSource() "AtCoder.Segtree"); } - [Fact] + [EmbeddingFact] public async Task EmbeddedNamespaces() { var embedded = await EmbeddedData.LoadFromAssembly(typeof(Segtree<,>)); @@ -81,7 +88,7 @@ public async Task EmbeddedNamespaces() } - [Fact] + [EmbeddingFact] public async Task RemoveContract() { var embedded = await EmbeddedData.LoadFromAssembly(typeof(Segtree<,>)); From 29244a8f4ac47569da14d21f31ab7dcdfa72434b Mon Sep 17 00:00:00 2001 From: kzrnm Date: Tue, 24 Jan 2023 08:55:59 +0900 Subject: [PATCH 2/9] Fix analyzer --- Source/AtCoderAnalyzer/AnalyzerReleases.Shipped.md | 8 -------- .../Diagnostics/DiagnosticDescriptors.cs | 11 +++++++---- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/Source/AtCoderAnalyzer/AnalyzerReleases.Shipped.md b/Source/AtCoderAnalyzer/AnalyzerReleases.Shipped.md index 5845a6f..460a52a 100644 --- a/Source/AtCoderAnalyzer/AnalyzerReleases.Shipped.md +++ b/Source/AtCoderAnalyzer/AnalyzerReleases.Shipped.md @@ -28,11 +28,3 @@ AC0003 | Type Define | Error | Not defined IStaticMod AC0004 | Type Define | Error | Not defined IDynamicModID AC0005 | Type Define | Error | Not defined ISegtreeOperator AC0006 | Type Define | Error | Not defined ILazySegtreeOperator - -## Release 1.10.0 - -### Changed Rules - -Rule ID | Category | Severity | Notes ---------|----------|----------|-------------------- -AC0007 | Type Define | Info | Operator method doesn't have `MethodImpl(AggressiveInlining)` attribute diff --git a/Source/AtCoderAnalyzer/Diagnostics/DiagnosticDescriptors.cs b/Source/AtCoderAnalyzer/Diagnostics/DiagnosticDescriptors.cs index d4f8d82..e476776 100644 --- a/Source/AtCoderAnalyzer/Diagnostics/DiagnosticDescriptors.cs +++ b/Source/AtCoderAnalyzer/Diagnostics/DiagnosticDescriptors.cs @@ -5,9 +5,10 @@ namespace AtCoderAnalyzer.Diagnostics { public static class DiagnosticDescriptors { +#pragma warning disable IDE0090 // Avoid 'new(...)' for Shipped.md internal static Diagnostic AC0001_MultiplyOverflowInt32(SyntaxNode node) => Diagnostic.Create(AC0001_MultiplyOverflowInt32_Descriptor, node.GetLocation(), node.ToString()); - internal static readonly DiagnosticDescriptor AC0001_MultiplyOverflowInt32_Descriptor = new( + internal static readonly DiagnosticDescriptor AC0001_MultiplyOverflowInt32_Descriptor = new DiagnosticDescriptor( "AC0001", new LocalizableResourceString( nameof(DiagnosticsResources.AC0001_Title), @@ -23,7 +24,7 @@ internal static Diagnostic AC0001_MultiplyOverflowInt32(SyntaxNode node) ); internal static Diagnostic AC0002_LeftShiftOverflowInt32(SyntaxNode node) => Diagnostic.Create(AC0002_LeftShiftOverflowInt32_Descriptor, node.GetLocation(), node.ToString()); - internal static readonly DiagnosticDescriptor AC0002_LeftShiftOverflowInt32_Descriptor = new( + internal static readonly DiagnosticDescriptor AC0002_LeftShiftOverflowInt32_Descriptor = new DiagnosticDescriptor( "AC0002", new LocalizableResourceString( nameof(DiagnosticsResources.AC0002_Title), @@ -40,7 +41,8 @@ internal static Diagnostic AC0002_LeftShiftOverflowInt32(SyntaxNode node) internal static Diagnostic AC0007_AgressiveInlining(Location location, IEnumerable methods) => Diagnostic.Create(AC0007_AgressiveInlining_Descriptor, location, string.Join(", ", methods)); - internal static readonly DiagnosticDescriptor AC0007_AgressiveInlining_Descriptor = new( + + internal static readonly DiagnosticDescriptor AC0007_AgressiveInlining_Descriptor = new DiagnosticDescriptor( "AC0007", new LocalizableResourceString( nameof(DiagnosticsResources.AC0007_Title), @@ -57,7 +59,7 @@ internal static Diagnostic AC0007_AgressiveInlining(Location location, IEnumerab internal static Diagnostic AC0008_DefineOperatorType(Location location, IEnumerable types) => Diagnostic.Create(AC0008_DefineOperatorType_Descriptor, location, string.Join(", ", types)); - internal static readonly DiagnosticDescriptor AC0008_DefineOperatorType_Descriptor = new( + internal static readonly DiagnosticDescriptor AC0008_DefineOperatorType_Descriptor = new DiagnosticDescriptor( "AC0008", new LocalizableResourceString( nameof(DiagnosticsResources.AC0008_Title), @@ -71,5 +73,6 @@ internal static Diagnostic AC0008_DefineOperatorType(Location location, IEnumera DiagnosticSeverity.Error, isEnabledByDefault: true ); +#pragma warning restore IDE0090 } } From b3ef1e50d0c17b26477c94466b17551bf2e554c9 Mon Sep 17 00:00:00 2001 From: kzrnm Date: Tue, 24 Jan 2023 09:09:02 +0900 Subject: [PATCH 3/9] Add test for embedder switching --- Test/ac-library-csharp.Test/SourceExpanderTest.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Test/ac-library-csharp.Test/SourceExpanderTest.cs b/Test/ac-library-csharp.Test/SourceExpanderTest.cs index 80208ed..e62b844 100644 --- a/Test/ac-library-csharp.Test/SourceExpanderTest.cs +++ b/Test/ac-library-csharp.Test/SourceExpanderTest.cs @@ -26,6 +26,18 @@ class EmbeddingFact : FactAttribute const string languageVersion = "11.0"; #endif + [Fact] + public async Task Embedding() + { + var embedded = await EmbeddedData.LoadFromAssembly(typeof(Segtree<,>)); + embedded.AssemblyMetadatas.Keys.Should() +#if EMBEDDING + .ContainMatch(@"SourceExpander.*"); +#else + .NotContainMatch(@"SourceExpander.*"); +#endif + } + [EmbeddingFact] public void AssemblyName() { From e9b917edda530c8c5ac8cc03c87630a9322b2c71 Mon Sep 17 00:00:00 2001 From: kzrnm Date: Tue, 24 Jan 2023 14:06:44 +0900 Subject: [PATCH 4/9] format --- Source/AtCoderAnalyzer/Diagnostics/DiagnosticDescriptors.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/AtCoderAnalyzer/Diagnostics/DiagnosticDescriptors.cs b/Source/AtCoderAnalyzer/Diagnostics/DiagnosticDescriptors.cs index e476776..8368783 100644 --- a/Source/AtCoderAnalyzer/Diagnostics/DiagnosticDescriptors.cs +++ b/Source/AtCoderAnalyzer/Diagnostics/DiagnosticDescriptors.cs @@ -41,7 +41,7 @@ internal static Diagnostic AC0002_LeftShiftOverflowInt32(SyntaxNode node) internal static Diagnostic AC0007_AgressiveInlining(Location location, IEnumerable methods) => Diagnostic.Create(AC0007_AgressiveInlining_Descriptor, location, string.Join(", ", methods)); - + internal static readonly DiagnosticDescriptor AC0007_AgressiveInlining_Descriptor = new DiagnosticDescriptor( "AC0007", new LocalizableResourceString( From d162b45c12f4943acc26a42a37872b415db56914 Mon Sep 17 00:00:00 2001 From: kzrnm Date: Tue, 24 Jan 2023 14:17:35 +0900 Subject: [PATCH 5/9] Set up release/atcoder --- .github/workflows/build-release-publish.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-release-publish.yml b/.github/workflows/build-release-publish.yml index 5de7196..80c883b 100644 --- a/.github/workflows/build-release-publish.yml +++ b/.github/workflows/build-release-publish.yml @@ -4,6 +4,7 @@ on: push: branches: - main + - release/atcoder tags: - "v[0-9]+.[0-9]+.[0-9]+*" From ebc0476f96c50cb168fa6e8f595007de6d4d164f Mon Sep 17 00:00:00 2001 From: kzrnm Date: Tue, 24 Jan 2023 14:23:39 +0900 Subject: [PATCH 6/9] Disable Embedder --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 95ddb0b..fddbf58 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -16,7 +16,7 @@ $(MSBuildThisFileDirectory)bin\Packages\$(Configuration)\ - true + false $(DefineConstants);EMBEDDING true From eba22d515f8b0211ca0f538271a5780ed0ea1baf Mon Sep 17 00:00:00 2001 From: kzrnm Date: Tue, 24 Jan 2023 14:23:52 +0900 Subject: [PATCH 7/9] Disable AtCoderAnalyzer --- Source/AtCoderAnalyzer/AtCoderAnalyzer.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/AtCoderAnalyzer/AtCoderAnalyzer.csproj b/Source/AtCoderAnalyzer/AtCoderAnalyzer.csproj index 1b8df18..632059e 100644 --- a/Source/AtCoderAnalyzer/AtCoderAnalyzer.csproj +++ b/Source/AtCoderAnalyzer/AtCoderAnalyzer.csproj @@ -9,6 +9,7 @@ Analyzer For AtCoder library MIT $(NoWarn);CS1998 + false true From 4935fdeec53384373fa3998f9f822585b44a3863 Mon Sep 17 00:00:00 2001 From: kzrnm Date: Tue, 24 Jan 2023 14:20:23 +0900 Subject: [PATCH 8/9] v3.0.0-atcoder1 --- CHANGELOG.md | 8 ++++++++ Directory.Build.props | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4124b53..3ca6c3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.0.0-pre1] - 2023-01-24 +- Rename assembly from AtCoderLibrary to ac-library-csharp +- Rename some methods/classes to PascalCase + +## [3.0.0-atcoder1] - 2023-01-24 +- Make SourceExpander.Embedder switchable +- Disable some Contract.Assert + ## [2.1.1] - 2023-01-17 - Optimize PrimitiveRoot diff --git a/Directory.Build.props b/Directory.Build.props index fddbf58..93dfa19 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -7,8 +7,8 @@ https://github.com/kzrnm/ac-library-csharp https://github.com/kzrnm/ac-library-csharp/blob/main/CHANGELOG.md - 2.1.1 - 2.1.1.101 + 3.0.0-atcoder1 + 3.0.0.1 $(GIT_COMMIT) True From cdf854551301bca8a38f332733507ae28a1db7b4 Mon Sep 17 00:00:00 2001 From: kzrnm Date: Tue, 24 Jan 2023 16:17:49 +0900 Subject: [PATCH 9/9] Add SuffixArray test --- Source/ac-library-csharp/String/StringLib.cs | 1 + .../String/StringLibTest.cs | 22 ++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Source/ac-library-csharp/String/StringLib.cs b/Source/ac-library-csharp/String/StringLib.cs index 853af7f..20df0c6 100644 --- a/Source/ac-library-csharp/String/StringLib.cs +++ b/Source/ac-library-csharp/String/StringLib.cs @@ -389,6 +389,7 @@ public static int[] SaIs(ReadOnlySpan s, int upper, int thresholdNaive, int Induce(lms, s, sa, ls, sumS, sumL); // LMSを再帰的にソート + // m の値は再帰ごとに半分以下になるので再帰の回数も log(n) に抑えられる if (m > 0) { var sortedLms = new SimpleList(m); diff --git a/Test/ac-library-csharp.Test/String/StringLibTest.cs b/Test/ac-library-csharp.Test/String/StringLibTest.cs index bf30736..1692172 100644 --- a/Test/ac-library-csharp.Test/String/StringLibTest.cs +++ b/Test/ac-library-csharp.Test/String/StringLibTest.cs @@ -271,7 +271,7 @@ public void SAAllABTest() } } [Fact] - public void SA() + public void SuffixArray() { var s = "missisippi"; @@ -296,6 +296,26 @@ public void SA() s[sa[i]..].Should().Be(answer[i]); } } + [Fact] + public void SuffixArrayInt() + { + int[] s, sa; + s = Enumerable.Range(0, 500000).SelectMany(i => new[] { i, ~i }).ToArray(); + sa = StringLib.SuffixArray(s); + sa.Should().Equal( + Enumerable.Range(0, 500000).Select(i => 999999 - 2 * i).Concat( + Enumerable.Range(0, 500000).Select(i => 2 * i)) + ); + + s = Enumerable.Range(0, 1000000).ToArray(); + sa = StringLib.SuffixArray(s); + sa.Should().Equal(s); + + s = Enumerable.Range(0, 1000000).Reverse().ToArray(); + sa = StringLib.SuffixArray(s); + sa.Should().Equal(s); + } + [Fact] public void SASingle() {