From 16b788bf92de7cc53c4d9ffa25505f98d1495701 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 14 Sep 2026 14:48:05 +0000 Subject: [PATCH] Add a PreciseNumber storage-type alias package [minor] Semantics.Quantities.Precise joins Double, Float and Decimal as a props-only satellite, binding every quantity to ktsu.PreciseNumber.PreciseNumber so a consumer writes Mass rather than Mass. It is the first alias package whose storage type comes from a package rather than being a C# keyword, which is the only real difference. The generator script learns to write a fully qualified name into the alias, and the project carries a PackageReference on ktsu.PreciseNumber so the name resolves for a consumer. Semantics.Quantities itself still has no PreciseNumber dependency: the support is opt-in through this package alone. What it buys is exactness. A unit factor is applied at the precision the value carries rather than at the fifteen to seventeen significant digits a double holds, so Length.FromFoot(1).In(Units.Inch) is exactly 12 where double gives 12.000000000000002, and Velocity3D.One.Length() is the square root of three to fifty digits rather than to a double's worth. PreciseNumber is deliberately not added to precision.json. That file feeds PrecisionGenerator, which emits typeof() into StorageTypes in the core ktsu.Semantics.Quantities assembly, so an entry there would force the core to reference ktsu.PreciseNumber and undo the separation this package exists to keep. StorageTypes has no reader anywhere in the repository, so the entry would buy nothing in exchange. Worth revisiting only if StorageTypes acquires a purpose, and then as a decision about where it should live. Testing: PreciseNumberStorageConversionTests runs the shared conversion suite over PreciseNumber with exact assertions, one derived line as the base class intends. Its tolerance for non-terminating answers is 1e-35 rather than something tighter because the limit is the expected literals, not the storage type: the knot is a repeating fraction written to 38 decimal places and PreciseNumber answers it with 50 correct digits, so the residual measured is the truncation of the reference value. That is still ten orders of magnitude tighter than decimal's, so a factor arriving through a double fails it by a wide margin. All 1248 tests pass, the solution builds with no warnings, and rebuilding the generated sources and regenerating the alias props leaves no diff. The package was packed and checked: buildTransitive props, no lib assemblies, no empty symbols package, and dependencies on both ktsu.Semantics.Quantities and ktsu.PreciseNumber for each of net8.0, net9.0 and net10.0. A consumer project built against the props confirmed the aliases resolve and the two values above. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_017jrnV7N94UGL8fDRRE8Xt8 --- CLAUDE.md | 4 +- Directory.Packages.props | 1 + README.md | 1 + Semantics.Quantities.Decimal/README.md | 1 + Semantics.Quantities.Double/README.md | 1 + Semantics.Quantities.Float/README.md | 1 + Semantics.Quantities.Precise/README.md | 101 ++++++++ .../Semantics.Quantities.Precise.csproj | 33 +++ .../ktsu.Semantics.Quantities.Precise.props | 226 ++++++++++++++++++ .../Quantities/StorageConversionTests.cs | 17 ++ Semantics.Test/Semantics.Test.csproj | 4 + Semantics.sln | 14 ++ scripts/Generate-AliasProps.ps1 | 5 +- 13 files changed, 406 insertions(+), 3 deletions(-) create mode 100644 Semantics.Quantities.Precise/README.md create mode 100644 Semantics.Quantities.Precise/Semantics.Quantities.Precise.csproj create mode 100644 Semantics.Quantities.Precise/buildTransitive/ktsu.Semantics.Quantities.Precise.props diff --git a/CLAUDE.md b/CLAUDE.md index 753e64a8..7a12dd74 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -44,7 +44,7 @@ The opt-in lives in `.sonarlint/sonar-local.props` (analyzer package) and `.sona | `Semantics.Color` | Physically-grounded color types. Canonical linear-RGB `Color` hub plus color-space satellites (`Srgb`, `Hsl`, `Hsv`, `Oklab`, `Oklch`); every type converts to and from every other, routed through the nearest shared hub (`Srgb` within the sRGB family, `Oklab` within the perceptual family, linear `Color` across families) so no conversion takes a redundant gamma round-trip. Also WCAG accessibility tooling, HSL/perceptual adjustment operations (lighten/saturate/hue/invert), and `NamedColors`. Targets `net8.0`–`net10.0` + `netstandard2.0`/`netstandard2.1`. | | `Semantics.Quantities` | Hand-written runtime types (`IPhysicalQuantity`, `PhysicalQuantityCore`, `IVector0`..`IVector4`, `UnitSystem`) plus generator output under `Generated/`. Every generated quantity is a `readonly record struct`. | | `Semantics.SourceGenerators` | Roslyn incremental generators that emit quantity types, units, conversions, magnitudes, physical constants, and storage-type helpers from metadata. Only the physics-specific half lives here — `Models/`, `Metadata/`, `Generators/`, and the bindings in `SemanticsGenerator`/`SemanticsDiagnostics`/`Emit`. The C# syntax templates come from `ktsu.CodeBlocker.Templates`; the metadata-driven generator base, metadata loading and the diagnostic catalogue come from `ktsu.SourceGeneratorToolkit` (#181, #192). | -| `Semantics.Quantities.{Double,Float,Decimal}` | Props-only satellite packages. Each ships a `buildTransitive` props file (generated by `scripts/Generate-AliasProps.ps1`) that injects global-using aliases binding every quantity to one storage type, so consumers write `Mass` instead of `Mass`. | +| `Semantics.Quantities.{Double,Float,Decimal,Precise}` | Props-only satellite packages. Each ships a `buildTransitive` props file (generated by `scripts/Generate-AliasProps.ps1`) that injects global-using aliases binding every quantity to one storage type, so consumers write `Mass` instead of `Mass`. `Precise` binds to `ktsu.PreciseNumber.PreciseNumber` and is the one whose storage type comes from a package rather than being a C# keyword, so it carries a `PackageReference` the others do not; the core `Semantics.Quantities` still has no PreciseNumber dependency. | | `Semantics.Vocabulary` | **Shared source, not a project.** Resolves `dimensions.json` into the quantities and operators it describes and separates out what cannot be honoured. Compiled into both `Semantics.SourceGenerators` and `Semantics.Cpp` via `Compile Include`; see its README for why source rather than an assembly, and what that costs. | | `Semantics.Cpp` | The C++ projection of the quantity vocabulary, in its own project because `ktsu.Coder` ships no `net8.0`. Reads `dimensions.json` and emits one C++ class per dimension, per vector form and per named overload, plus the declared relationships as operators. | | `Semantics.Cpp.Test` | Its tests, including ones that compile the whole generated vocabulary with `g++`/`clang++`, assert what it means through `static_assert`, and check that a dimensionally wrong product — scalar or componentwise — is refused by the compiler. Also `SevenTargetProjectionTests`, which is not about C++ at all: see below. | @@ -381,7 +381,7 @@ var converted = sourceString.As(); - Edit `Semantics.SourceGenerators/Metadata/dimensions.json` to add a dimension, vector form, semantic overload, or relationship. - Rebuild `Semantics.SourceGenerators` and the consuming `Semantics.Quantities` project; emitted files appear in `Semantics.Quantities/Generated/Semantics.SourceGenerators//`. - Treat generator output as committed source. Diff it before commit so accidental regressions are visible. -- After adding or renaming a quantity, regenerate the storage-type alias props with `pwsh scripts/Generate-AliasProps.ps1` (it reads the generated catalogue and rewrites `Semantics.Quantities.{Double,Float,Decimal}/buildTransitive/*.props`) and commit them. The `verify-generated` workflow rebuilds, regenerates, and fails the PR if either the generated sources or the alias props drift. +- After adding or renaming a quantity, regenerate the storage-type alias props with `pwsh scripts/Generate-AliasProps.ps1` (it reads the generated catalogue and rewrites `Semantics.Quantities.{Double,Float,Decimal,Precise}/buildTransitive/*.props`) and commit them. The `verify-generated` workflow rebuilds, regenerates, and fails the PR if either the generated sources or the alias props drift. - Factory names are the **singular lemma** (#49). The generator emits `From{name}` using each unit's `name` from `units.json` verbatim (e.g. `Length.FromMeter`, `Mass.FromKilogram`, `Speed.FromMeterPerSecond`, `Length.FromFoot`, `Frequency.FromHertz`). The rule is purely mechanical, so `name` must itself be the singular lemma — including compounds, whose leading noun is singular too (`MeterPerSecond`, `RevolutionPerMinute`, `PartPerMillion`, not `MeterPerSecond`/`RevolutionPerMinute`/`PartPerMillion`). There is no `factoryName` field and no pluralisation step; the generator never has to know English pluralisation. - Generator diagnostics: - **SEM001** — a relationship in `dimensions.json` references a dimension that does not exist (typo or rename). The operator is silently dropped. diff --git a/Directory.Packages.props b/Directory.Packages.props index 82a0bd57..2ba64ec3 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,6 +10,7 @@ + diff --git a/README.md b/README.md index 1788c7c3..597b0746 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ Each package has its own README with the full API surface, examples, and referen | [`ktsu.Semantics.Quantities.Double`](Semantics.Quantities.Double/README.md) | `double` storage-type aliases | [README](Semantics.Quantities.Double/README.md) | | [`ktsu.Semantics.Quantities.Float`](Semantics.Quantities.Float/README.md) | `float` storage-type aliases | [README](Semantics.Quantities.Float/README.md) | | [`ktsu.Semantics.Quantities.Decimal`](Semantics.Quantities.Decimal/README.md) | `decimal` storage-type aliases | [README](Semantics.Quantities.Decimal/README.md) | +| [`ktsu.Semantics.Quantities.Precise`](Semantics.Quantities.Precise/README.md) | `ktsu.PreciseNumber` storage-type aliases | [README](Semantics.Quantities.Precise/README.md) | | [`ktsu.Semantics.Music`](Semantics.Music/README.md) | Musical value types and harmonic analysis | [README](Semantics.Music/README.md) | | [`ktsu.Semantics.Color`](Semantics.Color/README.md) | Linear/perceptual color with accessibility tooling | [README](Semantics.Color/README.md) | diff --git a/Semantics.Quantities.Decimal/README.md b/Semantics.Quantities.Decimal/README.md index c96a6976..3a7ca32f 100644 --- a/Semantics.Quantities.Decimal/README.md +++ b/Semantics.Quantities.Decimal/README.md @@ -66,6 +66,7 @@ The aliases are project-wide global usings keyed on the bare type name (`Mass`, - [`ktsu.Semantics.Quantities.Double`](../Semantics.Quantities.Double/README.md) - [`ktsu.Semantics.Quantities.Float`](../Semantics.Quantities.Float/README.md) - `ktsu.Semantics.Quantities.Decimal` (this package) +- [`ktsu.Semantics.Quantities.Precise`](../Semantics.Quantities.Precise/README.md) A project that genuinely needs mixed storage types should skip the alias packages and reference `ktsu.Semantics.Quantities` directly, writing the closed generic (`Mass`) explicitly. diff --git a/Semantics.Quantities.Double/README.md b/Semantics.Quantities.Double/README.md index 73e76f2d..2ea123cb 100644 --- a/Semantics.Quantities.Double/README.md +++ b/Semantics.Quantities.Double/README.md @@ -66,6 +66,7 @@ The aliases are project-wide global usings keyed on the bare type name (`Mass`, - `ktsu.Semantics.Quantities.Double` (this package) - [`ktsu.Semantics.Quantities.Float`](../Semantics.Quantities.Float/README.md) - [`ktsu.Semantics.Quantities.Decimal`](../Semantics.Quantities.Decimal/README.md) +- [`ktsu.Semantics.Quantities.Precise`](../Semantics.Quantities.Precise/README.md) A project that genuinely needs mixed storage types should skip the alias packages and reference `ktsu.Semantics.Quantities` directly, writing the closed generic (`Mass`) explicitly. diff --git a/Semantics.Quantities.Float/README.md b/Semantics.Quantities.Float/README.md index a90fdfc3..007714ad 100644 --- a/Semantics.Quantities.Float/README.md +++ b/Semantics.Quantities.Float/README.md @@ -66,6 +66,7 @@ The aliases are project-wide global usings keyed on the bare type name (`Mass`, - [`ktsu.Semantics.Quantities.Double`](../Semantics.Quantities.Double/README.md) - `ktsu.Semantics.Quantities.Float` (this package) - [`ktsu.Semantics.Quantities.Decimal`](../Semantics.Quantities.Decimal/README.md) +- [`ktsu.Semantics.Quantities.Precise`](../Semantics.Quantities.Precise/README.md) A project that genuinely needs mixed storage types should skip the alias packages and reference `ktsu.Semantics.Quantities` directly, writing the closed generic (`Mass`) explicitly. diff --git a/Semantics.Quantities.Precise/README.md b/Semantics.Quantities.Precise/README.md new file mode 100644 index 00000000..dcf61a96 --- /dev/null +++ b/Semantics.Quantities.Precise/README.md @@ -0,0 +1,101 @@ +# ktsu.Semantics.Quantities.Precise + +> Storage-type aliases that bind every `ktsu.Semantics.Quantities` type to `ktsu.PreciseNumber.PreciseNumber`, so you write `Mass` instead of `Mass`, project-wide. + +[![License](https://img.shields.io/github/license/ktsu-dev/Semantics.svg?label=License&logo=nuget)](../LICENSE.md) +[![NuGet Version](https://img.shields.io/nuget/v/ktsu.Semantics.Quantities.Precise?label=Stable&logo=nuget)](https://nuget.org/packages/ktsu.Semantics.Quantities.Precise) +[![NuGet Version](https://img.shields.io/nuget/vpre/ktsu.Semantics.Quantities.Precise?label=Latest&logo=nuget)](https://nuget.org/packages/ktsu.Semantics.Quantities.Precise) +[![NuGet Downloads](https://img.shields.io/nuget/dt/ktsu.Semantics.Quantities.Precise?label=Downloads&logo=nuget)](https://nuget.org/packages/ktsu.Semantics.Quantities.Precise) +[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/ktsu-dev/Semantics?label=Commits&logo=github)](https://github.com/ktsu-dev/Semantics/commits/main) +[![GitHub contributors](https://img.shields.io/github/contributors/ktsu-dev/Semantics?label=Contributors&logo=github)](https://github.com/ktsu-dev/Semantics/graphs/contributors) +[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/ktsu-dev/Semantics/dotnet.yml?label=Build&logo=github)](https://github.com/ktsu-dev/Semantics/actions) + +`ktsu.Semantics.Quantities.Precise` is a satellite of [`ktsu.Semantics.Quantities`](../Semantics.Quantities/README.md) in the [ktsu.Semantics](../README.md) family. Read the core package README first for the quantity API itself. + +## Introduction + +Every quantity in `ktsu.Semantics.Quantities` is generic over its numeric storage type, so you normally write `Mass`, `Speed`, and so on. If a project uses one storage type throughout, that generic argument is noise. + +This package is props-only. It ships no assembly, just a `buildTransitive` props file that injects one C# global-using alias per quantity, binding each open generic type to [`ktsu.PreciseNumber.PreciseNumber`](https://nuget.org/packages/ktsu.PreciseNumber). Reference it and you can write `Mass`, `Speed`, `Force3D` with no generic argument, and every quantity resolves to its `PreciseNumber` form. The aliases are real `Mass` (and so on), so they interoperate with the entire API with no conversion. + +Installing this package also pulls in the matching version of `ktsu.Semantics.Quantities` and `ktsu.PreciseNumber` as dependencies, so it is the only reference you need. The core quantities package does not depend on `ktsu.PreciseNumber`; that dependency arrives only with this package. + +## Why this storage type + +`PreciseNumber` is an arbitrary-precision type — a `BigInteger` significand with a decimal exponent — so a unit factor is applied at the precision the value carries rather than at the 15 to 17 significant digits a `double` holds. Conversions that terminate come out exact: + +```csharp +Length.FromFoot(PreciseNumber.One).In(Units.Inch) // exactly 12 +1.0 * 0.3048 / 0.0254 // 12.000000000000002 in double +``` + +Roots are computed in the storage type's own arithmetic rather than through a `double` round trip, so a vector length keeps its digits too: + +```csharp +Velocity3D.One.Length() // 1.73205080756887729352744634150587236694280525381038 +``` + +This costs speed and allocation against `double`, so it suits work where the error budget matters more than throughput — long-horizon integration, unit-conversion chains, and reference values to check a faster pipeline against. + +Two limits worth knowing. The logarithmic scales (`Decibels`, `Cents`, `PH`, and the rest) still compute through `double` whatever the storage type. And a quotient that does not terminate is rounded to a precision derived from its operands, not carried forever. + +## Installation + +### Package Manager Console + +```powershell +Install-Package ktsu.Semantics.Quantities.Precise +``` + +### .NET CLI + +```bash +dotnet add package ktsu.Semantics.Quantities.Precise +``` + +### Package Reference + +```xml + +``` + +## Usage Example + +```csharp +using ktsu.Semantics.Quantities; // types resolve to their PreciseNumber form via the injected aliases +using ktsu.PreciseNumber; + +Mass mass = Mass.FromKilogram(10.ToPreciseNumber()); +Speed speed = Speed.FromMeterPerSecond(15.ToPreciseNumber()); +Mass total = mass + Mass.FromKilogram(2.ToPreciseNumber()); // still a Mass, full identity + +Force3D f = new() { X = 3.ToPreciseNumber(), Y = 4.ToPreciseNumber(), Z = PreciseNumber.Zero }; +ForceMagnitude mag = f.Magnitude(); // exactly 5 +``` + +Under the hood the injected alias looks like this (one line per quantity, roughly 220 in total): + +```xml + +``` + +## Use exactly one storage-type alias package per project + +The aliases are project-wide global usings keyed on the bare type name (`Mass`, `Speed`, ...). Referencing two flavor packages in the same project would define the same alias name twice (one bound to `PreciseNumber`, one to another type), which is a compile error. So reference exactly one of: + +- [`ktsu.Semantics.Quantities.Double`](../Semantics.Quantities.Double/README.md) +- [`ktsu.Semantics.Quantities.Float`](../Semantics.Quantities.Float/README.md) +- [`ktsu.Semantics.Quantities.Decimal`](../Semantics.Quantities.Decimal/README.md) +- `ktsu.Semantics.Quantities.Precise` (this package) + +A project that genuinely needs mixed storage types should skip the alias packages and reference `ktsu.Semantics.Quantities` directly, writing the closed generic (`Mass`) explicitly. + +The alias lists are generated from the quantity catalogue by `scripts/Generate-AliasProps.ps1` and validated in CI, so they stay in lockstep with the quantities the core package emits. + +## Contributing + +Contributions are welcome! Feel free to open issues or submit pull requests. + +## License + +This project is licensed under the MIT License. See the [LICENSE.md](../LICENSE.md) file for details. diff --git a/Semantics.Quantities.Precise/Semantics.Quantities.Precise.csproj b/Semantics.Quantities.Precise/Semantics.Quantities.Precise.csproj new file mode 100644 index 00000000..78ad5c60 --- /dev/null +++ b/Semantics.Quantities.Precise/Semantics.Quantities.Precise.csproj @@ -0,0 +1,33 @@ + + + + + + + net10.0;net9.0;net8.0 + + false + + false + false + Storage-type aliases for ktsu.Semantics.Quantities. Reference this package to write `Mass` instead of `Mass<PreciseNumber>` (and every other quantity) bound to ktsu.PreciseNumber, project-wide. Unit factors and vector lengths are then exact to the precision the value carries rather than to a double. Use one storage-type alias package per project. + + $(NoWarn);NU5128 + + + + + + + + + + + + + + diff --git a/Semantics.Quantities.Precise/buildTransitive/ktsu.Semantics.Quantities.Precise.props b/Semantics.Quantities.Precise/buildTransitive/ktsu.Semantics.Quantities.Precise.props new file mode 100644 index 00000000..5769af15 --- /dev/null +++ b/Semantics.Quantities.Precise/buildTransitive/ktsu.Semantics.Quantities.Precise.props @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Semantics.Test/Quantities/StorageConversionTests.cs b/Semantics.Test/Quantities/StorageConversionTests.cs index b398c3cd..38a4bfca 100644 --- a/Semantics.Test/Quantities/StorageConversionTests.cs +++ b/Semantics.Test/Quantities/StorageConversionTests.cs @@ -7,6 +7,7 @@ namespace ktsu.Semantics.Test.Quantities; using System.Linq; using System.Numerics; using System.Reflection; +using ktsu.PreciseNumber; using ktsu.Semantics.Quantities; using ktsu.Semantics.Quantities.Units; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -23,6 +24,22 @@ public sealed class DoubleStorageConversionTests() : StorageConversionTests(tolerance: "1e-25", decimalExact: true); +/// +/// Runs over , the storage type the +/// ktsu.Semantics.Quantities.Precise alias package binds to. +/// +/// +/// The tolerance is ten orders of magnitude tighter than 's, so a factor that +/// reached the type through a — wrong from about the sixteenth digit — fails here +/// by an enormous margin. It is not tighter still because the limit is the expected literals rather +/// than the storage type: the knot is a repeating fraction written to 38 decimal places, and +/// PreciseNumber answers it with 50 correct digits, so the residual being measured is the truncation +/// of the reference value. Lengthening that literal is what would buy a tighter bound. +/// +[TestClass] +public sealed class PreciseNumberStorageConversionTests() + : StorageConversionTests(tolerance: "1e-35", decimalExact: true); + /// /// The same unit conversions, physics relationships and vector lengths, run over each storage type. /// diff --git a/Semantics.Test/Semantics.Test.csproj b/Semantics.Test/Semantics.Test.csproj index 73ea1410..01b93430 100644 --- a/Semantics.Test/Semantics.Test.csproj +++ b/Semantics.Test/Semantics.Test.csproj @@ -43,6 +43,10 @@ + + diff --git a/Semantics.sln b/Semantics.sln index 3fe8046c..b51638b3 100644 --- a/Semantics.sln +++ b/Semantics.sln @@ -29,6 +29,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Semantics.Cpp", "Semantics. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Semantics.Cpp.Test", "Semantics.Cpp.Test\Semantics.Cpp.Test.csproj", "{2E8EAA2E-59FB-410D-9DB1-C9850311B029}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Semantics.Quantities.Precise", "Semantics.Quantities.Precise\Semantics.Quantities.Precise.csproj", "{5A67DFC3-E2D2-41B9-9E42-0B4727AF0C7D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -195,6 +197,18 @@ Global {2E8EAA2E-59FB-410D-9DB1-C9850311B029}.Release|x64.Build.0 = Release|Any CPU {2E8EAA2E-59FB-410D-9DB1-C9850311B029}.Release|x86.ActiveCfg = Release|Any CPU {2E8EAA2E-59FB-410D-9DB1-C9850311B029}.Release|x86.Build.0 = Release|Any CPU + {5A67DFC3-E2D2-41B9-9E42-0B4727AF0C7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A67DFC3-E2D2-41B9-9E42-0B4727AF0C7D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A67DFC3-E2D2-41B9-9E42-0B4727AF0C7D}.Debug|x64.ActiveCfg = Debug|Any CPU + {5A67DFC3-E2D2-41B9-9E42-0B4727AF0C7D}.Debug|x64.Build.0 = Debug|Any CPU + {5A67DFC3-E2D2-41B9-9E42-0B4727AF0C7D}.Debug|x86.ActiveCfg = Debug|Any CPU + {5A67DFC3-E2D2-41B9-9E42-0B4727AF0C7D}.Debug|x86.Build.0 = Debug|Any CPU + {5A67DFC3-E2D2-41B9-9E42-0B4727AF0C7D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A67DFC3-E2D2-41B9-9E42-0B4727AF0C7D}.Release|Any CPU.Build.0 = Release|Any CPU + {5A67DFC3-E2D2-41B9-9E42-0B4727AF0C7D}.Release|x64.ActiveCfg = Release|Any CPU + {5A67DFC3-E2D2-41B9-9E42-0B4727AF0C7D}.Release|x64.Build.0 = Release|Any CPU + {5A67DFC3-E2D2-41B9-9E42-0B4727AF0C7D}.Release|x86.ActiveCfg = Release|Any CPU + {5A67DFC3-E2D2-41B9-9E42-0B4727AF0C7D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/scripts/Generate-AliasProps.ps1 b/scripts/Generate-AliasProps.ps1 index f5e55c7f..6a21f5c2 100644 --- a/scripts/Generate-AliasProps.ps1 +++ b/scripts/Generate-AliasProps.ps1 @@ -43,11 +43,14 @@ if ($typeNames.Count -eq 0) { throw "No quantity types found under $generatedRoot. Build Semantics.Quantities first so the generated files exist." } -# PascalCase project/package suffix => C# storage keyword. +# PascalCase project/package suffix => the storage type as it is written in the alias. +# A keyword for the built-in types; a fully qualified name for one that comes from a package, +# since the alias is expanded in projects that have no using directives of ours. $storageTypes = [ordered]@{ 'Double' = 'double' 'Float' = 'float' 'Decimal' = 'decimal' + 'Precise' = 'ktsu.PreciseNumber.PreciseNumber' } foreach ($entry in $storageTypes.GetEnumerator()) {