diff --git a/.github/workflows/build-release-publish.yml b/.github/workflows/build-release-publish.yml index 5de7196a..80c883b9 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]+*" diff --git a/CHANGELOG.md b/CHANGELOG.md index 4124b534..3ca6c3ad 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 e8dbdcb5..93dfa19e 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 @@ -16,6 +16,9 @@ $(MSBuildThisFileDirectory)bin\Packages\$(Configuration)\ + false + $(DefineConstants);EMBEDDING + true true snupkg diff --git a/Source/AtCoderAnalyzer/AnalyzerReleases.Shipped.md b/Source/AtCoderAnalyzer/AnalyzerReleases.Shipped.md index 5845a6f4..460a52a9 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/AtCoderAnalyzer.csproj b/Source/AtCoderAnalyzer/AtCoderAnalyzer.csproj index 1b8df18b..632059e1 100644 --- a/Source/AtCoderAnalyzer/AtCoderAnalyzer.csproj +++ b/Source/AtCoderAnalyzer/AtCoderAnalyzer.csproj @@ -9,6 +9,7 @@ Analyzer For AtCoder library MIT $(NoWarn);CS1998 + false true diff --git a/Source/AtCoderAnalyzer/Diagnostics/DiagnosticDescriptors.cs b/Source/AtCoderAnalyzer/Diagnostics/DiagnosticDescriptors.cs index d4f8d828..83687831 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 } } diff --git a/Source/ac-library-csharp/Internal/InternalBit.cs b/Source/ac-library-csharp/Internal/InternalBit.cs index fe831a46..5d661011 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 634abd64..5e572ad8 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 653e9e16..a3f6e8e6 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 c1ace4ee..20df0c6a 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 @@ -387,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/Source/ac-library-csharp/ac-library-csharp.csproj b/Source/ac-library-csharp/ac-library-csharp.csproj index fee010c0..57ad6bf4 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 d96b0427..e62b844e 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"; @@ -20,12 +27,24 @@ public class SourceExpanderTest #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() { 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 +60,7 @@ public async Task Symbol() .Be(useIntrinsics); } - [Fact] + [EmbeddingFact] public async Task LanguageVersion() { var embedded = await EmbeddedData.LoadFromAssembly(typeof(Segtree<,>)); @@ -50,7 +69,7 @@ public async Task LanguageVersion() .WhoseValue.Should().Be(languageVersion); } - [Fact] + [EmbeddingFact] public async Task EmbeddedSource() { var embedded = await EmbeddedData.LoadFromAssembly(typeof(Segtree<,>)); @@ -67,7 +86,7 @@ public async Task EmbeddedSource() "AtCoder.Segtree"); } - [Fact] + [EmbeddingFact] public async Task EmbeddedNamespaces() { var embedded = await EmbeddedData.LoadFromAssembly(typeof(Segtree<,>)); @@ -81,7 +100,7 @@ public async Task EmbeddedNamespaces() } - [Fact] + [EmbeddingFact] public async Task RemoveContract() { var embedded = await EmbeddedData.LoadFromAssembly(typeof(Segtree<,>)); diff --git a/Test/ac-library-csharp.Test/String/StringLibTest.cs b/Test/ac-library-csharp.Test/String/StringLibTest.cs index bf307368..1692172b 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() {