From e02bfb89e8c3d7f31135b279b6a390eef7d30413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=A4gi?= Date: Sat, 29 Apr 2023 15:34:40 +0200 Subject: [PATCH 01/30] Create first skeleton of systems --- quantities.test/LengthTest.cs | 1 + quantities/IQuantityFactory.cs | 11 +++++++++ quantities/quantities/Length.cs | 7 ++++++ quantities/systems/ISystem.cs | 42 +++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 quantities/IQuantityFactory.cs create mode 100644 quantities/systems/ISystem.cs diff --git a/quantities.test/LengthTest.cs b/quantities.test/LengthTest.cs index f3cc97d6..eadb16a5 100644 --- a/quantities.test/LengthTest.cs +++ b/quantities.test/LengthTest.cs @@ -143,6 +143,7 @@ public void LengthByDivisionIsEqualToLengthByConstruction() [Fact] public void SiLengthBySiTimeIsVelocity() { + Length a = Length.Of(3).Si(); Length distance = Length.Si(100); Time duration = Time.Seconds(20); Velocity expected = Velocity.Si(5).PerSecond(); diff --git a/quantities/IQuantityFactory.cs b/quantities/IQuantityFactory.cs new file mode 100644 index 00000000..0bbf9d59 --- /dev/null +++ b/quantities/IQuantityFactory.cs @@ -0,0 +1,11 @@ +using Quantities.Measures; + +namespace Quantities; + +public interface IQuantityFactory + where TDimension : Dimensions.IDimension + where TSelf : struct, IQuantity, TDimension +{ + internal Quant Quant { get; } + internal static abstract TSelf Create(in Quant quant); +} diff --git a/quantities/quantities/Length.cs b/quantities/quantities/Length.cs index 7141666c..69da3d86 100644 --- a/quantities/quantities/Length.cs +++ b/quantities/quantities/Length.cs @@ -3,12 +3,15 @@ using Quantities.Measures; using Quantities.Measures.Transformations; using Quantities.Prefixes; +using Quantities.Systems; using Quantities.Units.Imperial; using Quantities.Units.Si; namespace Quantities.Quantities; public readonly struct Length : IQuantity, ILength + , IQuantityBuilder> + , IQuantityFactory , ISi , IImperial , IMultiplyOperators @@ -19,6 +22,7 @@ namespace Quantities.Quantities; private static readonly ICreate linear = new ToLinear(); private readonly Quant quant; internal Quant Quant => this.quant; + Quant IQuantityFactory.Quant => this.quant; private Length(in Quant quant) => this.quant = quant; public Length To() where TUnit : ISiBaseUnit, ILength @@ -36,6 +40,7 @@ public Length ToImperial() { return new(this.quant.As>()); } + static Length IQuantityFactory.Create(in Quant quant) => new(in quant); public static Length Si(in Double value) where TUnit : ISiBaseUnit, ILength { @@ -75,6 +80,8 @@ internal static Length From(in Volume volume, in Area area) public override String ToString() => this.quant.ToString(); public String ToString(String? format, IFormatProvider? provider) => this.quant.ToString(format, provider); + public static Linear Of(in Double value) => new(in value); + public static Boolean operator ==(Length left, Length right) => left.Equals(right); public static Boolean operator !=(Length left, Length right) => !left.Equals(right); public static implicit operator Double(Length length) => length.quant.Value; diff --git a/quantities/systems/ISystem.cs b/quantities/systems/ISystem.cs new file mode 100644 index 00000000..59179969 --- /dev/null +++ b/quantities/systems/ISystem.cs @@ -0,0 +1,42 @@ + + +using Quantities.Dimensions; +using Quantities.Measures; +using Quantities.Prefixes; +using Quantities.Units.Imperial; +using Quantities.Units.NonStandard; +using Quantities.Units.Si; + +namespace Quantities.Systems; + +public interface ISystem +{ + +} + +public interface IQuantityBuilder + where TSystem : ISystem +{ + public static abstract TSystem Of(in Double value); +} + +public readonly struct Linear : ISystem + where TDimension : Dimensions.IDimension, ILinear + where TSelf : struct, IQuantity, IQuantityFactory, TDimension +{ + private readonly Double value; + internal Linear(in Double value) => this.value = value; + public TSelf Si() where TUnit : ISiBaseUnit, TDimension => TSelf.Create(this.value.As>()); + public TSelf Si() + where TPrefix : IMetricPrefix + where TUnit : ISiBaseUnit, TDimension => TSelf.Create(this.value.As>()); + public TSelf Metric() where TUnit : IMetricUnit, TDimension => TSelf.Create(this.value.As>()); + public TSelf Metric() + where TPrefix : IMetricPrefix + where TUnit : IMetricUnit, TDimension => TSelf.Create(this.value.As>()); + + public TSelf Imperial() where TUnit : IImperial, TDimension => TSelf.Create(this.value.As>()); + public TSelf NonStandard() where TUnit : INoSystem, TDimension => TSelf.Create(this.value.As>()); + +} + From e77814cb9a74efc4e7435567c26b64b88ab81a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=A4gi?= Date: Sun, 30 Apr 2023 04:32:24 +0200 Subject: [PATCH 02/30] Simplify SI units. --- quantities.test/LengthTest.cs | 1 - quantities.test/MassTest.cs | 46 +++++++++---------- quantities/Extensions.cs | 4 +- quantities/ISi.cs | 24 ++-------- quantities/measures/IMeasure.cs | 1 - quantities/measures/Measures.cs | 28 +++-------- quantities/quantities/Area.cs | 8 ++-- quantities/quantities/ElectricCurrent.cs | 8 ++-- quantities/quantities/ElectricPotential.cs | 23 +++++----- quantities/quantities/ElectricalResistance.cs | 22 ++++----- quantities/quantities/Energy.cs | 38 +++++++-------- quantities/quantities/Force.cs | 22 ++++----- quantities/quantities/Length.cs | 12 ++--- quantities/quantities/Mass.cs | 20 ++++---- quantities/quantities/Power.cs | 22 ++++----- quantities/quantities/Temperature.cs | 12 ++--- quantities/quantities/Time.cs | 4 +- quantities/quantities/Velocity.cs | 8 ++-- quantities/quantities/Volume.cs | 8 ++-- quantities/units/IInjectUnit.cs | 6 +-- quantities/units/Si/Base/Ampere.cs | 2 +- quantities/units/Si/Base/Candela.cs | 2 +- quantities/units/Si/Base/Kelvin.cs | 2 +- quantities/units/Si/Base/Kilogram.cs | 2 +- quantities/units/Si/Base/Metre.cs | 2 +- quantities/units/Si/Base/Mole.cs | 2 +- quantities/units/Si/Base/Second.cs | 2 +- quantities/units/Si/Derived/Celsius.cs | 2 +- quantities/units/Si/Derived/Gram.cs | 2 +- quantities/units/Si/Derived/Joule.cs | 2 +- quantities/units/Si/Derived/Newton.cs | 2 +- quantities/units/Si/Derived/Ohm.cs | 2 +- quantities/units/Si/Derived/Volt.cs | 2 +- quantities/units/Si/Derived/Watt.cs | 2 +- quantities/units/Si/ISiBaseUnit.cs | 3 -- quantities/units/Si/ISiDerivedUnit.cs | 17 ------- 36 files changed, 152 insertions(+), 213 deletions(-) delete mode 100644 quantities/units/Si/ISiBaseUnit.cs delete mode 100644 quantities/units/Si/ISiDerivedUnit.cs diff --git a/quantities.test/LengthTest.cs b/quantities.test/LengthTest.cs index eadb16a5..f3cc97d6 100644 --- a/quantities.test/LengthTest.cs +++ b/quantities.test/LengthTest.cs @@ -143,7 +143,6 @@ public void LengthByDivisionIsEqualToLengthByConstruction() [Fact] public void SiLengthBySiTimeIsVelocity() { - Length a = Length.Of(3).Si(); Length distance = Length.Si(100); Time duration = Time.Seconds(20); Velocity expected = Velocity.Si(5).PerSecond(); diff --git a/quantities.test/MassTest.cs b/quantities.test/MassTest.cs index 64048f77..4e2ce654 100644 --- a/quantities.test/MassTest.cs +++ b/quantities.test/MassTest.cs @@ -9,15 +9,15 @@ public sealed class MassTest private const Double gramsInPound = 453.59237; private static readonly Mass onePound = Mass.Imperial(1); [Fact] - public void KilogramToString() => FormattingMatches(v => Mass.Kilogram(v), "kg"); + public void KilogramToString() => FormattingMatches(v => Mass.Si(v), "kg"); [Fact] - public void GramToString() => FormattingMatches(v => Mass.Si(v), "g"); + public void GramToString() => FormattingMatches(v => Mass.Metric(v), "g"); [Fact] public void TonneToString() => FormattingMatches(v => Mass.Metric(v), "t"); [Fact] - public void KiloGramToString() => FormattingMatches(v => Mass.Si(v), "Kg"); + public void KiloGramToString() => FormattingMatches(v => Mass.Metric(v), "Kg"); [Fact] - public void MicroGramToString() => FormattingMatches(v => Mass.Si(v), "μg"); + public void MicroGramToString() => FormattingMatches(v => Mass.Metric(v), "μg"); [Fact] public void KiloTonneToString() => FormattingMatches(v => Mass.Metric(v), "Kt"); [Fact] @@ -25,28 +25,28 @@ public sealed class MassTest [Fact] public void KilogramKiloGramEquivalence() { - Mass siKilogram = Mass.Kilogram(0.3251); - Mass pseudoKiloGram = Mass.Si(0.3251); + Mass siKilogram = Mass.Si(0.3251); + Mass pseudoKiloGram = Mass.Metric(0.3251); Assert.Equal(siKilogram, pseudoKiloGram); } [Fact] public void GramToKilogram() { - Mass mass = Mass.Si(1600); - Mass expected = Mass.Kilogram(1.6); + Mass mass = Mass.Metric(1600); + Mass expected = Mass.Si(1.6); - Mass actual = mass.ToKilogram(); + Mass actual = mass.To(); actual.Matches(expected); } [Fact] public void KilogramToGram() { - Mass mass = Mass.Kilogram(0.8); - Mass expected = Mass.Si(800); + Mass mass = Mass.Si(0.8); + Mass expected = Mass.Metric(800); - Mass actual = mass.To(); + Mass actual = mass.ToMetric(); actual.Matches(expected); } @@ -54,16 +54,16 @@ public void KilogramToGram() public void TonneToKilogram() { Mass mass = Mass.Metric(0.2); - Mass expected = Mass.Kilogram(200); + Mass expected = Mass.Si(200); - Mass actual = mass.ToKilogram(); + Mass actual = mass.To(); actual.Matches(expected); } [Fact] public void KilogramToTonne() { - Mass mass = Mass.Kilogram(1200); + Mass mass = Mass.Si(1200); Mass expected = Mass.Metric(1.2); Mass actual = mass.ToMetric(); @@ -73,7 +73,7 @@ public void KilogramToTonne() [Fact] public void GramToTonne() { - Mass mass = Mass.Si(1500); + Mass mass = Mass.Metric(1500); Mass expected = Mass.Metric(1.5); Mass actual = mass.ToMetric(); @@ -84,16 +84,16 @@ public void GramToTonne() public void TonneToGram() { Mass mass = Mass.Metric(0.003); - Mass expected = Mass.Si(3000); + Mass expected = Mass.Metric(3000); - Mass actual = mass.To(); + Mass actual = mass.ToMetric(); actual.Matches(expected); } [Fact] public void GramToPound() { - Mass mass = Mass.Si(3d * gramsInPound); + Mass mass = Mass.Metric(3d * gramsInPound); Mass expected = Mass.Imperial(3); Mass actual = mass.ToImperial(); @@ -104,9 +104,9 @@ public void GramToPound() public void PoundToGram() { Mass mass = Mass.Imperial(2); - Mass expected = Mass.Si(2d * gramsInPound); + Mass expected = Mass.Metric(2d * gramsInPound); - Mass actual = mass.To(); + Mass actual = mass.ToMetric(); actual.Matches(expected); } @@ -168,7 +168,7 @@ public void DefinitionOfOunceHolds() [Fact] public void DefinitionOfPoundHolds() { - Assert.Equal(Mass.Kilogram(1), Mass.Imperial(1000d / gramsInPound)); + Assert.Equal(Mass.Si(1), Mass.Imperial(1000d / gramsInPound)); } [Fact] public void DefinitionOfStoneHolds() @@ -193,6 +193,6 @@ public void DefinitionOfTonHolds() [Fact] public void DefinitionOfSlugHolds() { - Assert.Equal(Mass.Kilogram(14.59390294), Mass.Imperial(1)); + Assert.Equal(Mass.Si(14.59390294), Mass.Imperial(1)); } } diff --git a/quantities/Extensions.cs b/quantities/Extensions.cs index 58690f88..e344c7e6 100644 --- a/quantities/Extensions.cs +++ b/quantities/Extensions.cs @@ -13,13 +13,13 @@ public static Velocity Per(this IBuilder builder) where TUnit : IMetricUnit, ITime => new(builder.By>()); public static Velocity Per(this IBuilder builder) where TPrefix : IMetricPrefix, IScaleDown - where TUnit : ISiBaseUnit, ITime => new(builder.By>()); + where TUnit : ISiUnit, ITime => new(builder.By>()); public static Velocity PerSecond(this IBuilder builder) => new(builder.By>()); public static DataRate Per(this IBuilder builder) where TUnit : IMetricUnit, ITime => new(builder.By>()); public static DataRate Per(this IBuilder builder) where TPrefix : IMetricPrefix, IScaleDown - where TUnit : ISiBaseUnit, ITime => new(builder.By>()); + where TUnit : ISiUnit, ITime => new(builder.By>()); public static DataRate PerSecond(this IBuilder builder) => new(builder.By>()); internal static Quant To(this Double value) where TDim : Measures.IDimension where TMeasure : IMeasure, ILinear diff --git a/quantities/ISi.cs b/quantities/ISi.cs index 47ef5992..ebecc4c0 100644 --- a/quantities/ISi.cs +++ b/quantities/ISi.cs @@ -9,29 +9,13 @@ internal interface ISi where TDimension : IDimension { public TSelf To() - where TUnit : ISiBaseUnit, TDimension; + where TUnit : ISiUnit, TDimension; public TSelf To() where TPrefix : IMetricPrefix - where TUnit : ISiBaseUnit, TDimension; + where TUnit : ISiUnit, TDimension; public static abstract TSelf Si(in Double value) - where TUnit : ISiBaseUnit, TDimension; + where TUnit : ISiUnit, TDimension; public static abstract TSelf Si(in Double value) where TPrefix : IMetricPrefix - where TUnit : ISiBaseUnit, TDimension; -} - -internal interface ISiDerived - where TSelf : TDimension - where TDimension : IDimension -{ - public TSelf To() - where TUnit : ISiDerivedUnit, TDimension; - public TSelf To() - where TPrefix : IMetricPrefix - where TUnit : ISiDerivedUnit, TDimension; - public static abstract TSelf Si(in Double value) - where TUnit : ISiDerivedUnit, TDimension; - public static abstract TSelf Si(in Double value) - where TPrefix : IMetricPrefix - where TUnit : ISiDerivedUnit, TDimension; + where TUnit : ISiUnit, TDimension; } diff --git a/quantities/measures/IMeasure.cs b/quantities/measures/IMeasure.cs index a9fcba94..a938a237 100644 --- a/quantities/measures/IMeasure.cs +++ b/quantities/measures/IMeasure.cs @@ -1,4 +1,3 @@ -using Quantities.Units; using Quantities.Units.Imperial; using Quantities.Units.NonStandard; using Quantities.Units.Si; diff --git a/quantities/measures/Measures.cs b/quantities/measures/Measures.cs index aed0d9ca..62cf4dae 100644 --- a/quantities/measures/Measures.cs +++ b/quantities/measures/Measures.cs @@ -7,7 +7,7 @@ namespace Quantities.Measures; internal readonly struct Si : ISiMeasure, ILinear - where TUnit : ISiBaseUnit + where TUnit : ISiUnit { public static Double ToSi(in Double value) => value; public static Double FromSi(in Double value) => value; @@ -15,22 +15,22 @@ namespace Quantities.Measures; } internal readonly struct Si : ISiMeasure, ILinear where TPrefix : IPrefix - where TUnit : ISiBaseUnit + where TUnit : ISiUnit { public static Double ToSi(in Double value) => TPrefix.ToSi(in value); public static Double FromSi(in Double value) => TPrefix.FromSi(in value); public static String Representation { get; } = $"{TPrefix.Representation}{TUnit.Representation}"; } -internal readonly struct SiDerived : ISiMeasure, ILinear - where TUnit : ISiDerivedUnit +internal readonly struct Metric : ISiAccepted, ILinear + where TUnit : IMetricUnit { public static Double ToSi(in Double value) => TUnit.ToSi(in value); public static Double FromSi(in Double value) => TUnit.FromSi(in value); public static String Representation => TUnit.Representation; } -internal readonly struct SiDerived : ISiMeasure, ILinear +internal readonly struct Metric : ISiAccepted, ILinear where TPrefix : IPrefix - where TUnit : ISiDerivedUnit + where TUnit : IMetricUnit { public static Double ToSi(in Double value) => TPrefix.ToSi(TUnit.ToSi(in value)); public static Double FromSi(in Double value) => TPrefix.FromSi(TUnit.FromSi(in value)); @@ -50,21 +50,7 @@ namespace Quantities.Measures; public static Double FromSi(in Double value) => TUnit.FromSi(in value); public static String Representation => TUnit.Representation; } -internal readonly struct Metric : ISiAccepted, ILinear - where TUnit : IMetricUnit -{ - public static Double ToSi(in Double value) => TUnit.ToSi(in value); - public static Double FromSi(in Double value) => TUnit.FromSi(in value); - public static String Representation => TUnit.Representation; -} -internal readonly struct Metric : ISiAccepted, ILinear - where TPrefix : IPrefix - where TUnit : IMetricUnit -{ - public static Double ToSi(in Double value) => TPrefix.ToSi(TUnit.ToSi(in value)); - public static Double FromSi(in Double value) => TPrefix.FromSi(TUnit.FromSi(in value)); - public static String Representation { get; } = $"{TPrefix.Representation}{TUnit.Representation}"; -} + internal readonly struct Product : IMeasure where TLeft : IMeasure where TRight : IMeasure diff --git a/quantities/quantities/Area.cs b/quantities/quantities/Area.cs index 98327ef3..293d4db0 100644 --- a/quantities/quantities/Area.cs +++ b/quantities/quantities/Area.cs @@ -20,13 +20,13 @@ namespace Quantities.Quantities; internal Quant Quant => this.quant; private Area(in Quant quant) => this.quant = quant; public Area ToSquare() - where TUnit : ISiBaseUnit, ILength + where TUnit : ISiUnit, ILength { return new(this.quant.To>()); } public Area ToSquare() where TPrefix : IMetricPrefix - where TUnit : ISiBaseUnit, ILength + where TUnit : ISiUnit, ILength { return new(this.quant.To>()); } @@ -57,13 +57,13 @@ public Area ToNonStandard() return new(this.quant.As, Alias>()); } public static Area Square(in Double value) - where TUnit : ISiBaseUnit, ILength + where TUnit : ISiUnit, ILength { return new(value.To>()); } public static Area Square(in Double value) where TPrefix : IMetricPrefix - where TUnit : ISiBaseUnit, ILength + where TUnit : ISiUnit, ILength { return new(value.To>()); } diff --git a/quantities/quantities/ElectricCurrent.cs b/quantities/quantities/ElectricCurrent.cs index 873c187f..bf161c37 100644 --- a/quantities/quantities/ElectricCurrent.cs +++ b/quantities/quantities/ElectricCurrent.cs @@ -16,24 +16,24 @@ namespace Quantities.Quantities; internal Quant Quant => this.quant; private ElectricCurrent(in Quant quant) => this.quant = quant; public ElectricCurrent To() - where TUnit : ISiBaseUnit, IElectricCurrent + where TUnit : ISiUnit, IElectricCurrent { return new(this.quant.As>()); } public ElectricCurrent To() where TPrefix : IMetricPrefix - where TUnit : ISiBaseUnit, IElectricCurrent + where TUnit : ISiUnit, IElectricCurrent { return new(this.quant.As>()); } public static ElectricCurrent Si(in Double value) - where TUnit : ISiBaseUnit, IElectricCurrent + where TUnit : ISiUnit, IElectricCurrent { return new(value.As>()); } public static ElectricCurrent Si(in Double value) where TPrefix : IMetricPrefix - where TUnit : ISiBaseUnit, IElectricCurrent + where TUnit : ISiUnit, IElectricCurrent { return new(value.As>()); } diff --git a/quantities/quantities/ElectricPotential.cs b/quantities/quantities/ElectricPotential.cs index aa87390a..2658400f 100644 --- a/quantities/quantities/ElectricPotential.cs +++ b/quantities/quantities/ElectricPotential.cs @@ -8,36 +8,37 @@ namespace Quantities.Quantities; public readonly struct ElectricPotential : IQuantity, IElectricPotential - , ISiDerived + , ISi , IMultiplyOperators , IDivisionOperators , IDivisionOperators { + // ToDo: Create a generic version of the Creator! private static readonly Creator create = new(); private readonly Quant quant; internal Quant Quant => this.quant; private ElectricPotential(in Quant quant) => this.quant = quant; public ElectricPotential To() - where TUnit : ISiDerivedUnit, IElectricPotential + where TUnit : ISiUnit, IElectricPotential { - return new(this.quant.As>()); + return new(this.quant.As>()); } public ElectricPotential To() where TPrefix : IMetricPrefix - where TUnit : ISiDerivedUnit, IElectricPotential + where TUnit : ISiUnit, IElectricPotential { - return new(this.quant.As>()); + return new(this.quant.As>()); } public static ElectricPotential Si(in Double value) - where TUnit : ISiDerivedUnit, IElectricPotential + where TUnit : ISiUnit, IElectricPotential { - return new(value.As>()); + return new(value.As>()); } public static ElectricPotential Si(in Double value) where TPrefix : IMetricPrefix - where TUnit : ISiDerivedUnit, IElectricPotential + where TUnit : ISiUnit, IElectricPotential { - return new(value.As>()); + return new(value.As>()); } public Boolean Equals(ElectricPotential other) => this.quant.Equals(other.quant); @@ -76,7 +77,7 @@ internal static ElectricPotential From(in Power power, in ElectricCurrent curren private sealed class Creator : IPrefixInject { - public Quant Identity(in Double value) => value.As>(); - public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); + public Quant Identity(in Double value) => value.As>(); + public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); } } diff --git a/quantities/quantities/ElectricalResistance.cs b/quantities/quantities/ElectricalResistance.cs index 3289520e..6c2ddf1c 100644 --- a/quantities/quantities/ElectricalResistance.cs +++ b/quantities/quantities/ElectricalResistance.cs @@ -8,7 +8,7 @@ namespace Quantities.Quantities; public readonly struct ElectricalResistance : IQuantity, IElectricalResistance - , ISiDerived + , ISi , IMultiplyOperators { private static readonly Creator create = new(); @@ -16,26 +16,26 @@ namespace Quantities.Quantities; internal Quant Quant => this.quant; private ElectricalResistance(in Quant quant) => this.quant = quant; public ElectricalResistance To() - where TUnit : ISiDerivedUnit, IElectricalResistance + where TUnit : ISiUnit, IElectricalResistance { - return new(this.quant.As>()); + return new(this.quant.As>()); } public ElectricalResistance To() where TPrefix : IMetricPrefix - where TUnit : ISiDerivedUnit, IElectricalResistance + where TUnit : ISiUnit, IElectricalResistance { - return new(this.quant.As>()); + return new(this.quant.As>()); } public static ElectricalResistance Si(in Double value) - where TUnit : ISiDerivedUnit, IElectricalResistance + where TUnit : ISiUnit, IElectricalResistance { - return new(value.As>()); + return new(value.As>()); } public static ElectricalResistance Si(in Double value) where TPrefix : IMetricPrefix - where TUnit : ISiDerivedUnit, IElectricalResistance + where TUnit : ISiUnit, IElectricalResistance { - return new(value.As>()); + return new(value.As>()); } public Boolean Equals(ElectricalResistance other) => this.quant.Equals(other.quant); @@ -62,7 +62,7 @@ internal static ElectricalResistance From(in ElectricPotential potential, in Ele private sealed class Creator : IPrefixInject { - public Quant Identity(in Double value) => value.As>(); - public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); + public Quant Identity(in Double value) => value.As>(); + public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); } } diff --git a/quantities/quantities/Energy.cs b/quantities/quantities/Energy.cs index c76d3b27..2337fcd1 100644 --- a/quantities/quantities/Energy.cs +++ b/quantities/quantities/Energy.cs @@ -8,7 +8,7 @@ namespace Quantities.Quantities; public readonly struct Energy : IQuantity, IEnergy - , ISiDerived + , ISi , IImperial , IDivisionOperators , IDivisionOperators @@ -17,22 +17,22 @@ namespace Quantities.Quantities; internal Quant Quant => this.quant; private Energy(in Quant quant) => this.quant = quant; public Energy To() - where TUnit : ISiDerivedUnit, IEnergy + where TUnit : ISiUnit, IEnergy { - return new(this.quant.As>()); + return new(this.quant.As>()); } public Energy To() where TPrefix : IMetricPrefix - where TUnit : ISiDerivedUnit, IEnergy + where TUnit : ISiUnit, IEnergy { - return new(this.quant.As>()); + return new(this.quant.As>()); } public Energy ToMetric() where TPrefix : IMetricPrefix - where TPowerUnit : ISiDerivedUnit, IPower + where TPowerUnit : ISiUnit, IPower where TTimeUnit : IMetricUnit, ITransform, ITime { - return new(this.quant.AsProduct, Metric>()); + return new(this.quant.AsProduct, Metric>()); } public Energy ToImperial() where TUnit : IImperial, IEnergy @@ -40,37 +40,37 @@ public Energy ToImperial() return new(this.quant.As>()); } public static Energy Si(in Double value) - where TUnit : ISiDerivedUnit, IEnergy + where TUnit : ISiUnit, IEnergy { - return new(value.As>()); + return new(value.As>()); } public static Energy Si(in Double value) where TPrefix : IMetricPrefix - where TUnit : ISiDerivedUnit, IEnergy + where TUnit : ISiUnit, IEnergy { - return new(value.As>()); + return new(value.As>()); } public static Energy Si(in Double value) where TPrefix : IMetricPrefix - where TPowerUnit : ISiDerivedUnit, IPower - where TTimeUnit : ISiBaseUnit, ITime + where TPowerUnit : ISiUnit, IPower + where TTimeUnit : ISiUnit, ITime { - return new(value.AsProduct, Si>()); + return new(value.AsProduct, Si>()); } public static Energy Si(in Double value) where TPowerPrefix : IPrefix - where TPowerUnit : ISiDerivedUnit, IPower + where TPowerUnit : ISiUnit, IPower where TTimePrefix : IPrefix - where TTimeUnit : ISiBaseUnit, ITime + where TTimeUnit : ISiUnit, ITime { - return new(value.AsProduct, Si>()); + return new(value.AsProduct, Si>()); } public static Energy Metric(in Double value) where TPrefix : IMetricPrefix - where TPowerUnit : ISiDerivedUnit, IPower + where TPowerUnit : ISiUnit, IPower where TTimeUnit : IMetricUnit, ITransform, ITime { - return new(value.AsProduct, Metric>()); + return new(value.AsProduct, Metric>()); } public static Energy Imperial(in Double value) where TUnit : IImperial, IEnergy diff --git a/quantities/quantities/Force.cs b/quantities/quantities/Force.cs index a6e6dc24..360390ff 100644 --- a/quantities/quantities/Force.cs +++ b/quantities/quantities/Force.cs @@ -10,7 +10,7 @@ namespace Quantities.Quantities; public readonly struct Force : IQuantity, IForce - , ISiDerived + , ISi , IImperial , IMetric , INoSystem @@ -21,15 +21,15 @@ namespace Quantities.Quantities; internal Quant Quant => this.quant; private Force(in Quant quant) => this.quant = quant; public Force To() - where TUnit : ISiDerivedUnit, IForce + where TUnit : ISiUnit, IForce { - return new(this.quant.As>()); + return new(this.quant.As>()); } public Force To() where TPrefix : IMetricPrefix - where TUnit : ISiDerivedUnit, IForce + where TUnit : ISiUnit, IForce { - return new(this.quant.As>()); + return new(this.quant.As>()); } public Force ToMetric() where TUnit : IMetricUnit, IForce { @@ -52,15 +52,15 @@ public Force ToNonStandard() return new(this.quant.As>()); } public static Force Si(in Double value) - where TUnit : ISiDerivedUnit, IForce + where TUnit : ISiUnit, IForce { - return new(value.As>()); + return new(value.As>()); } public static Force Si(in Double value) where TPrefix : IMetricPrefix - where TUnit : ISiDerivedUnit, IForce + where TUnit : ISiUnit, IForce { - return new(value.As>()); + return new(value.As>()); } public static Force Metric(in Double value) where TUnit : IMetricUnit, IForce { @@ -109,7 +109,7 @@ internal static Force From(in Power power, in Velocity velocity) private sealed class Creator : IPrefixInject { - public Quant Identity(in Double value) => value.As>(); - public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); + public Quant Identity(in Double value) => value.As>(); + public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); } } \ No newline at end of file diff --git a/quantities/quantities/Length.cs b/quantities/quantities/Length.cs index 69da3d86..bf6de1e1 100644 --- a/quantities/quantities/Length.cs +++ b/quantities/quantities/Length.cs @@ -3,14 +3,12 @@ using Quantities.Measures; using Quantities.Measures.Transformations; using Quantities.Prefixes; -using Quantities.Systems; using Quantities.Units.Imperial; using Quantities.Units.Si; namespace Quantities.Quantities; public readonly struct Length : IQuantity, ILength - , IQuantityBuilder> , IQuantityFactory , ISi , IImperial @@ -25,13 +23,13 @@ namespace Quantities.Quantities; Quant IQuantityFactory.Quant => this.quant; private Length(in Quant quant) => this.quant = quant; public Length To() - where TUnit : ISiBaseUnit, ILength + where TUnit : ISiUnit, ILength { return new(this.quant.As>()); } public Length To() where TPrefix : IMetricPrefix - where TUnit : ISiBaseUnit, ILength + where TUnit : ISiUnit, ILength { return new(this.quant.As>()); } @@ -42,13 +40,13 @@ public Length ToImperial() } static Length IQuantityFactory.Create(in Quant quant) => new(in quant); public static Length Si(in Double value) - where TUnit : ISiBaseUnit, ILength + where TUnit : ISiUnit, ILength { return new(value.As>()); } public static Length Si(in Double value) where TPrefix : IMetricPrefix - where TUnit : ISiBaseUnit, ILength + where TUnit : ISiUnit, ILength { return new(value.As>()); } @@ -80,8 +78,6 @@ internal static Length From(in Volume volume, in Area area) public override String ToString() => this.quant.ToString(); public String ToString(String? format, IFormatProvider? provider) => this.quant.ToString(format, provider); - public static Linear Of(in Double value) => new(in value); - public static Boolean operator ==(Length left, Length right) => left.Equals(right); public static Boolean operator !=(Length left, Length right) => !left.Equals(right); public static implicit operator Double(Length length) => length.quant.Value; diff --git a/quantities/quantities/Mass.cs b/quantities/quantities/Mass.cs index 4f39ef37..0a693693 100644 --- a/quantities/quantities/Mass.cs +++ b/quantities/quantities/Mass.cs @@ -7,23 +7,22 @@ namespace Quantities.Quantities; public readonly struct Mass : IQuantity, IMass - , ISiDerived // ToDo: Should be ISi<>. This is something of an unfortunate happenstance... + , ISi , IMetric , IImperial { private readonly Quant quant; private Mass(in Quant quant) => this.quant = quant; - public Mass ToKilogram() => new(this.quant.As>()); public Mass To() - where TUnit : ISiDerivedUnit, IMass + where TUnit : ISiUnit, IMass { - return new(this.quant.As>()); + return new(this.quant.As>()); } public Mass To() where TPrefix : IMetricPrefix - where TUnit : ISiDerivedUnit, IMass + where TUnit : ISiUnit, IMass { - return new(this.quant.As>()); + return new(this.quant.As>()); } public Mass ToMetric() where TUnit : IMetricUnit, IMass { @@ -40,17 +39,16 @@ public Mass ToImperial() { return new(this.quant.As>()); } - public static Mass Kilogram(in Double value) => new(value.As>()); public static Mass Si(in Double value) - where TUnit : ISiDerivedUnit, IMass + where TUnit : ISiUnit, IMass { - return new(value.As>()); + return new(value.As>()); } public static Mass Si(in Double value) where TPrefix : IMetricPrefix - where TUnit : ISiDerivedUnit, IMass + where TUnit : ISiUnit, IMass { - return new(value.As>()); + return new(value.As>()); } public static Mass Metric(in Double value) where TUnit : IMetricUnit, IMass { diff --git a/quantities/quantities/Power.cs b/quantities/quantities/Power.cs index d4893420..1efbc71c 100644 --- a/quantities/quantities/Power.cs +++ b/quantities/quantities/Power.cs @@ -9,7 +9,7 @@ namespace Quantities.Quantities; public readonly struct Power : IQuantity, IPower - , ISiDerived + , ISi , IImperial , IMetric , IMultiplyOperators @@ -23,15 +23,15 @@ namespace Quantities.Quantities; internal Quant Quant => this.quant; private Power(in Quant quant) => this.quant = quant; public Power To() - where TUnit : ISiDerivedUnit, IPower + where TUnit : ISiUnit, IPower { - return new(this.quant.As>()); + return new(this.quant.As>()); } public Power To() where TPrefix : IMetricPrefix - where TUnit : ISiDerivedUnit, IPower + where TUnit : ISiUnit, IPower { - return new(this.quant.As>()); + return new(this.quant.As>()); } public Power ToMetric() where TUnit : IMetricUnit, IPower @@ -50,15 +50,15 @@ public Power ToImperial() return new(this.quant.As>()); } public static Power Si(in Double value) - where TUnit : ISiDerivedUnit, IPower + where TUnit : ISiUnit, IPower { - return new(value.As>()); + return new(value.As>()); } public static Power Si(in Double value) where TPrefix : IMetricPrefix - where TUnit : ISiDerivedUnit, IPower + where TUnit : ISiUnit, IPower { - return new(value.As>()); + return new(value.As>()); } public static Power Imperial(in Double value) where TUnit : IImperial, IPower @@ -114,7 +114,7 @@ internal static Power From(in Energy energy, in Time time) private sealed class Creator : IPrefixInject { - public Quant Identity(in Double value) => value.As>(); - public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); + public Quant Identity(in Double value) => value.As>(); + public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); } } diff --git a/quantities/quantities/Temperature.cs b/quantities/quantities/Temperature.cs index fafd22e5..7397b9d7 100644 --- a/quantities/quantities/Temperature.cs +++ b/quantities/quantities/Temperature.cs @@ -17,17 +17,17 @@ namespace Quantities.Quantities; internal Quant Quant => this.quant; private Temperature(in Quant quant) => this.quant = quant; public Temperature To() - where TUnit : ISiBaseUnit, ITemperature + where TUnit : ISiUnit, ITemperature { return new(this.quant.As>()); } public Temperature To() where TPrefix : IMetricPrefix - where TUnit : ISiBaseUnit, ITemperature + where TUnit : ISiUnit, ITemperature { return new(this.quant.As>()); } - public Temperature ToCelsius() => new(this.quant.As>()); + public Temperature ToCelsius() => new(this.quant.As>()); public Temperature ToImperial() where TUnit : IImperial, ITemperature { @@ -39,19 +39,19 @@ public Temperature ToNonStandard() return new(this.quant.As>()); } public static Temperature Si(in Double value) - where TUnit : ISiBaseUnit, ITemperature + where TUnit : ISiUnit, ITemperature { return new(value.As>()); } public static Temperature Si(in Double value) where TPrefix : IMetricPrefix - where TUnit : ISiBaseUnit, ITemperature + where TUnit : ISiUnit, ITemperature { return new(value.As>()); } public static Temperature Celsius(in Double value) { - return new(value.As>()); + return new(value.As>()); } public static Temperature Imperial(in Double value) where TUnit : IImperial, ITemperature diff --git a/quantities/quantities/Time.cs b/quantities/quantities/Time.cs index 47f74f4c..359e83f1 100644 --- a/quantities/quantities/Time.cs +++ b/quantities/quantities/Time.cs @@ -19,7 +19,7 @@ namespace Quantities.Quantities; public Time ToSeconds() => new(this.quant.As>()); public Time To() where TPrefix : IMetricPrefix, IScaleDown - where TUnit : ISiBaseUnit, ITime + where TUnit : ISiUnit, ITime { return new(this.quant.As>()); } @@ -32,7 +32,7 @@ public Time To() public static Time Seconds(in Double value) => new(value.As>()); public static Time Si(in Double value) where TPrefix : IMetricPrefix, IScaleDown - where TUnit : ISiBaseUnit, ITime + where TUnit : ISiUnit, ITime { return new(value.As>()); } diff --git a/quantities/quantities/Velocity.cs b/quantities/quantities/Velocity.cs index a95cd279..ee2efa54 100644 --- a/quantities/quantities/Velocity.cs +++ b/quantities/quantities/Velocity.cs @@ -16,13 +16,13 @@ namespace Quantities.Quantities; private readonly Quant quant; internal Quant Quant => this.quant; internal Velocity(in Quant quant) => this.quant = quant; - public IBuilder To() where TUnit : ISiBaseUnit, ILength + public IBuilder To() where TUnit : ISiUnit, ILength { return new Transform>(in this.quant); } public IBuilder To() where TPrefix : IMetricPrefix - where TUnit : ISiBaseUnit, ILength + where TUnit : ISiUnit, ILength { return new Transform>(in this.quant); } @@ -32,10 +32,10 @@ public IBuilder ToImperial() return new Transform>(in this.quant); } public static IBuilder Si(in Double value) - where TUnit : ISiBaseUnit, ILength => new Builder>(in value); + where TUnit : ISiUnit, ILength => new Builder>(in value); public static IBuilder Si(in Double value) where TPrefix : IMetricPrefix - where TUnit : ISiBaseUnit, ILength + where TUnit : ISiUnit, ILength { return new Builder>(in value); } diff --git a/quantities/quantities/Volume.cs b/quantities/quantities/Volume.cs index 32c4d068..e4efe09d 100644 --- a/quantities/quantities/Volume.cs +++ b/quantities/quantities/Volume.cs @@ -16,13 +16,13 @@ namespace Quantities.Quantities; internal Quant Quant => this.quant; private Volume(in Quant quant) => this.quant = quant; public Volume ToCubic() - where TUnit : ISiBaseUnit, ILength + where TUnit : ISiUnit, ILength { return new(this.quant.To>()); } public Volume ToCubic() where TPrefix : IMetricPrefix - where TUnit : ISiBaseUnit, ILength + where TUnit : ISiUnit, ILength { return new(this.quant.To>()); } @@ -48,13 +48,13 @@ public Volume ToCubicImperial() return new(this.quant.To>()); } public static Volume Cubic(in Double value) - where TUnit : ISiBaseUnit, ILength + where TUnit : ISiUnit, ILength { return new(value.To>()); } public static Volume Cubic(in Double value) where TPrefix : IMetricPrefix - where TUnit : ISiBaseUnit, ILength + where TUnit : ISiUnit, ILength { return new(value.To>()); } diff --git a/quantities/units/IInjectUnit.cs b/quantities/units/IInjectUnit.cs index 3218432c..f6362a7d 100644 --- a/quantities/units/IInjectUnit.cs +++ b/quantities/units/IInjectUnit.cs @@ -16,14 +16,10 @@ public readonly ref struct Creator { private readonly ICreate creator; internal Creator(in ICreate creator) => this.creator = creator; - public T Si(in Double value) where TInjectedUnit : ISiBaseUnit, TAlias + public T Si(in Double value) where TInjectedUnit : ISiUnit, TAlias { return this.creator.Create>(in value); } - public T SiDerived(in Double value) where TInjectedUnit : ISiDerivedUnit, TAlias - { - return this.creator.Create>(in value); - } public T Metric(in Double value) where TInjectedUnit : IMetricUnit, TAlias { return this.creator.Create>(in value); diff --git a/quantities/units/Si/Base/Ampere.cs b/quantities/units/Si/Base/Ampere.cs index ea1d3bf7..34cf9ef1 100644 --- a/quantities/units/Si/Base/Ampere.cs +++ b/quantities/units/Si/Base/Ampere.cs @@ -2,7 +2,7 @@ namespace Quantities.Units.Si; -public readonly struct Ampere : ISiBaseUnit, IElectricCurrent +public readonly struct Ampere : ISiUnit, IElectricCurrent { public static String Representation => "A"; } diff --git a/quantities/units/Si/Base/Candela.cs b/quantities/units/Si/Base/Candela.cs index 48e7ef73..7fe20d41 100644 --- a/quantities/units/Si/Base/Candela.cs +++ b/quantities/units/Si/Base/Candela.cs @@ -2,7 +2,7 @@ namespace Quantities.Units.Si; -public readonly struct Candela : ISiBaseUnit, ILuminousIntensity +public readonly struct Candela : ISiUnit, ILuminousIntensity { public static String Representation => "cd"; } diff --git a/quantities/units/Si/Base/Kelvin.cs b/quantities/units/Si/Base/Kelvin.cs index 6dae3349..06798f22 100644 --- a/quantities/units/Si/Base/Kelvin.cs +++ b/quantities/units/Si/Base/Kelvin.cs @@ -2,7 +2,7 @@ namespace Quantities.Units.Si; -public readonly struct Kelvin : ISiBaseUnit, ITemperature +public readonly struct Kelvin : ISiUnit, ITemperature { public static String Representation => "K"; } diff --git a/quantities/units/Si/Base/Kilogram.cs b/quantities/units/Si/Base/Kilogram.cs index 8db18a4e..ebc02998 100644 --- a/quantities/units/Si/Base/Kilogram.cs +++ b/quantities/units/Si/Base/Kilogram.cs @@ -2,7 +2,7 @@ namespace Quantities.Units.Si; -public readonly struct Kilogram : ISiBaseUnit, IMass +public readonly struct Kilogram : ISiUnit, IMass { public static String Representation => "kg"; } diff --git a/quantities/units/Si/Base/Metre.cs b/quantities/units/Si/Base/Metre.cs index 94d0fc68..dc9380a8 100644 --- a/quantities/units/Si/Base/Metre.cs +++ b/quantities/units/Si/Base/Metre.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Si; // Spelling: https://en.wikipedia.org/wiki/Metre -public readonly struct Metre : ISiBaseUnit, ILength +public readonly struct Metre : ISiUnit, ILength { public static String Representation => "m"; } diff --git a/quantities/units/Si/Base/Mole.cs b/quantities/units/Si/Base/Mole.cs index bc62beb8..478bd20f 100644 --- a/quantities/units/Si/Base/Mole.cs +++ b/quantities/units/Si/Base/Mole.cs @@ -2,7 +2,7 @@ namespace Quantities.Units.Si; -public readonly struct Mole : ISiBaseUnit, IAmountOfSubstance +public readonly struct Mole : ISiUnit, IAmountOfSubstance { public static String Representation => "mol"; } diff --git a/quantities/units/Si/Base/Second.cs b/quantities/units/Si/Base/Second.cs index fe0a8b70..069b4bfb 100644 --- a/quantities/units/Si/Base/Second.cs +++ b/quantities/units/Si/Base/Second.cs @@ -2,7 +2,7 @@ namespace Quantities.Units.Si; -public readonly struct Second : ISiBaseUnit, ITime +public readonly struct Second : ISiUnit, ITime { public static String Representation => "s"; } diff --git a/quantities/units/Si/Derived/Celsius.cs b/quantities/units/Si/Derived/Celsius.cs index 5a9d30d2..bf0575fc 100644 --- a/quantities/units/Si/Derived/Celsius.cs +++ b/quantities/units/Si/Derived/Celsius.cs @@ -4,7 +4,7 @@ namespace Quantities.Units.Si.Derived; // [K] ≡ [°C] + 273.15 // Celsius is officially an SI derived unit. -public readonly struct Celsius : ISiDerivedUnit, ITemperature +public readonly struct Celsius : IMetricUnit, ITemperature { private const Decimal kelvinOffset = 273.15m; static Double ITransform.ToSi(in Double nonSiValue) => (Double)((Decimal)nonSiValue + kelvinOffset); diff --git a/quantities/units/Si/Derived/Gram.cs b/quantities/units/Si/Derived/Gram.cs index 79ebe2eb..c8c6920b 100644 --- a/quantities/units/Si/Derived/Gram.cs +++ b/quantities/units/Si/Derived/Gram.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Si.Derived; -public readonly struct Gram : ISiDerivedUnit, IMass +public readonly struct Gram : IMetricUnit, IMass { public static String Representation => "g"; } diff --git a/quantities/units/Si/Derived/Joule.cs b/quantities/units/Si/Derived/Joule.cs index 1bfa8adf..d8aadf13 100644 --- a/quantities/units/Si/Derived/Joule.cs +++ b/quantities/units/Si/Derived/Joule.cs @@ -2,7 +2,7 @@ namespace Quantities.Units.Si.Derived; -public sealed class Joule : ISiDerivedUnit, IEnergy +public sealed class Joule : ISiUnit, IEnergy { public static String Representation => "J"; } diff --git a/quantities/units/Si/Derived/Newton.cs b/quantities/units/Si/Derived/Newton.cs index e0561f69..2b0b8676 100644 --- a/quantities/units/Si/Derived/Newton.cs +++ b/quantities/units/Si/Derived/Newton.cs @@ -2,7 +2,7 @@ namespace Quantities.Units.Si.Derived; -public readonly struct Newton : ISiDerivedUnit, IForce +public readonly struct Newton : ISiUnit, IForce { public static String Representation => "N"; } diff --git a/quantities/units/Si/Derived/Ohm.cs b/quantities/units/Si/Derived/Ohm.cs index c4c0f826..b65911f9 100644 --- a/quantities/units/Si/Derived/Ohm.cs +++ b/quantities/units/Si/Derived/Ohm.cs @@ -2,7 +2,7 @@ namespace Quantities.Units.Si.Derived; -public readonly struct Ohm : ISiDerivedUnit, IElectricalResistance +public readonly struct Ohm : ISiUnit, IElectricalResistance { public static String Representation => "Ω"; } diff --git a/quantities/units/Si/Derived/Volt.cs b/quantities/units/Si/Derived/Volt.cs index 96b5f61e..f676a309 100644 --- a/quantities/units/Si/Derived/Volt.cs +++ b/quantities/units/Si/Derived/Volt.cs @@ -2,7 +2,7 @@ namespace Quantities.Units.Si.Derived; -public readonly struct Volt : ISiDerivedUnit, IElectricPotential +public readonly struct Volt : ISiUnit, IElectricPotential { public static String Representation => "V"; } diff --git a/quantities/units/Si/Derived/Watt.cs b/quantities/units/Si/Derived/Watt.cs index 92d2fc49..0416c24c 100644 --- a/quantities/units/Si/Derived/Watt.cs +++ b/quantities/units/Si/Derived/Watt.cs @@ -2,7 +2,7 @@ namespace Quantities.Units.Si.Derived; -public readonly struct Watt : ISiDerivedUnit, IPower +public readonly struct Watt : ISiUnit, IPower { public static String Representation => "W"; } diff --git a/quantities/units/Si/ISiBaseUnit.cs b/quantities/units/Si/ISiBaseUnit.cs deleted file mode 100644 index 1ddb8bed..00000000 --- a/quantities/units/Si/ISiBaseUnit.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Quantities.Units.Si; - -public interface ISiBaseUnit : ISiUnit { /* marker interface */ } diff --git a/quantities/units/Si/ISiDerivedUnit.cs b/quantities/units/Si/ISiDerivedUnit.cs deleted file mode 100644 index 8039627f..00000000 --- a/quantities/units/Si/ISiDerivedUnit.cs +++ /dev/null @@ -1,17 +0,0 @@ - -using Quantities.Prefixes; - -namespace Quantities.Units.Si; - -public interface ISiDerivedUnit : ISiUnit, ITransform -{ - static Double ITransform.ToSi(in Double value) => value; - static Double ITransform.FromSi(in Double value) => value; -} - -public interface ISiDerivedUnit : ISiDerivedUnit - where TPrefix : IMetricPrefix -{ - static Double ITransform.ToSi(in Double value) => TPrefix.ToSi(in value); - static Double ITransform.FromSi(in Double value) => TPrefix.FromSi(in value); -} From 1875c33f3808199a364351b24d2dad586c5739dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=A4gi?= Date: Sun, 30 Apr 2023 05:16:46 +0200 Subject: [PATCH 03/30] Introduce concept of a root for Quantities. --- quantities/quantities/Data.cs | 12 ++++++++---- quantities/quantities/ElectricCurrent.cs | 13 ++++--------- quantities/quantities/ElectricPotential.cs | 14 ++++---------- quantities/quantities/ElectricalResistance.cs | 11 +++-------- quantities/quantities/Force.cs | 11 +++-------- quantities/quantities/Length.cs | 11 +++-------- quantities/quantities/Power.cs | 15 +++++---------- quantities/quantities/Time.cs | 11 +++-------- quantities/quantities/Velocity.cs | 11 +++-------- quantities/quantities/roots/FractionalRoot.cs | 15 +++++++++++++++ quantities/quantities/roots/IRoot.cs | 11 +++++++++++ quantities/quantities/roots/UnitRoot.cs | 15 +++++++++++++++ 12 files changed, 77 insertions(+), 73 deletions(-) create mode 100644 quantities/quantities/roots/FractionalRoot.cs create mode 100644 quantities/quantities/roots/IRoot.cs create mode 100644 quantities/quantities/roots/UnitRoot.cs diff --git a/quantities/quantities/Data.cs b/quantities/quantities/Data.cs index 9d300280..2ad19a91 100644 --- a/quantities/quantities/Data.cs +++ b/quantities/quantities/Data.cs @@ -2,6 +2,7 @@ using Quantities.Dimensions; using Quantities.Measures; using Quantities.Prefixes; +using Quantities.Quantities.Roots; using Quantities.Units.Si; namespace Quantities.Quantities; @@ -20,7 +21,7 @@ namespace Quantities.Quantities; public readonly struct Data : IQuantity, IAmountOfInformation , IDivisionOperators { - private static readonly Creator create = new(); + private static readonly IRoot root = new Creator(); private readonly Quant quant; internal Quant Quant => this.quant; private Data(in Quant quant) => this.quant = quant; @@ -47,9 +48,9 @@ public static Data In(in Double value) internal static Data From(in Time time, in DataRate rate) { - // ToDo: Recover data units form data rate + // ToDo: Recover data units from data rate Double bytes = Units.Si.Metric.Byte.FromSi(time.Quant.SiMultiply(rate.Quant)); - return new(BinaryPrefix.Scale(in bytes, create)); + return new(BinaryPrefix.Scale(in bytes, root)); } public Boolean Equals(Data other) => this.quant.Equals(other.quant); @@ -70,8 +71,11 @@ internal static Data From(in Time time, in DataRate rate) public static DataRate operator /(Data left, Time right) => DataRate.From(in left, in right); - private sealed class Creator : IPrefixInject + private sealed class Creator : IRoot { + public static Quant One { get; } = 1d.As>(); + public static Quant Zero { get; } = 0d.As>(); + // As bytes are way more common, use them to create data values by default. public Quant Identity(in Double value) => value.As>(); public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); diff --git a/quantities/quantities/ElectricCurrent.cs b/quantities/quantities/ElectricCurrent.cs index bf161c37..c7a84b97 100644 --- a/quantities/quantities/ElectricCurrent.cs +++ b/quantities/quantities/ElectricCurrent.cs @@ -2,6 +2,7 @@ using Quantities.Dimensions; using Quantities.Measures; using Quantities.Prefixes; +using Quantities.Quantities.Roots; using Quantities.Units.Si; namespace Quantities.Quantities; @@ -11,7 +12,7 @@ namespace Quantities.Quantities; , IMultiplyOperators , IMultiplyOperators { - private static readonly Creator create = new(); + private static readonly IRoot root = new UnitRoot(); private readonly Quant quant; internal Quant Quant => this.quant; private ElectricCurrent(in Quant quant) => this.quant = quant; @@ -45,11 +46,11 @@ public static ElectricCurrent Si(in Double value) public override String ToString() => this.quant.ToString(); internal static ElectricCurrent From(in ElectricPotential potential, in ElectricalResistance resistance) { - return new(MetricPrefix.ScaleThree(potential.Quant.SiDivide(resistance.Quant), create)); + return new(MetricPrefix.ScaleThree(potential.Quant.SiDivide(resistance.Quant), root)); } internal static ElectricCurrent From(in Power power, in ElectricPotential potential) { - return new(MetricPrefix.ScaleThree(power.Quant.SiDivide(potential.Quant), create)); + return new(MetricPrefix.ScaleThree(power.Quant.SiDivide(potential.Quant), root)); } public static Boolean operator ==(ElectricCurrent left, ElectricCurrent right) => left.Equals(right); public static Boolean operator !=(ElectricCurrent left, ElectricCurrent right) => !left.Equals(right); @@ -64,10 +65,4 @@ internal static ElectricCurrent From(in Power power, in ElectricPotential potent // Ohm's Law public static ElectricPotential operator *(ElectricCurrent current, ElectricalResistance resistance) => ElectricPotential.From(in current, in resistance); public static Power operator *(ElectricCurrent left, ElectricPotential right) => Power.From(in right, in left); - - private sealed class Creator : IPrefixInject - { - public Quant Identity(in Double value) => value.As>(); - public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); - } } diff --git a/quantities/quantities/ElectricPotential.cs b/quantities/quantities/ElectricPotential.cs index 2658400f..725d9c0a 100644 --- a/quantities/quantities/ElectricPotential.cs +++ b/quantities/quantities/ElectricPotential.cs @@ -2,6 +2,7 @@ using Quantities.Dimensions; using Quantities.Measures; using Quantities.Prefixes; +using Quantities.Quantities.Roots; using Quantities.Units.Si; using Quantities.Units.Si.Derived; @@ -13,8 +14,7 @@ namespace Quantities.Quantities; , IDivisionOperators , IDivisionOperators { - // ToDo: Create a generic version of the Creator! - private static readonly Creator create = new(); + private static readonly IRoot root = new UnitRoot(); private readonly Quant quant; internal Quant Quant => this.quant; private ElectricPotential(in Quant quant) => this.quant = quant; @@ -48,13 +48,13 @@ public static ElectricPotential Si(in Double value) public override String ToString() => this.quant.ToString(); internal static ElectricPotential From(in ElectricCurrent current, in ElectricalResistance resistance) { - return new(MetricPrefix.ScaleThree(current.Quant.SiMultiply(resistance.Quant), create)); + return new(MetricPrefix.ScaleThree(current.Quant.SiMultiply(resistance.Quant), root)); } internal static ElectricPotential From(in Power power, in ElectricCurrent current) { Double siPower = power.To(); Double siCurrent = current.To(); - return new(MetricPrefix.ScaleThree(siPower / siCurrent, create)); + return new(MetricPrefix.ScaleThree(siPower / siCurrent, root)); } public static Boolean operator ==(ElectricPotential left, ElectricPotential right) => left.Equals(right); @@ -74,10 +74,4 @@ internal static ElectricPotential From(in Power power, in ElectricCurrent curren #endregion Ohm's Law public static Power operator *(ElectricPotential left, ElectricCurrent right) => Power.From(in left, in right); - - private sealed class Creator : IPrefixInject - { - public Quant Identity(in Double value) => value.As>(); - public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); - } } diff --git a/quantities/quantities/ElectricalResistance.cs b/quantities/quantities/ElectricalResistance.cs index 6c2ddf1c..e1e41254 100644 --- a/quantities/quantities/ElectricalResistance.cs +++ b/quantities/quantities/ElectricalResistance.cs @@ -2,6 +2,7 @@ using Quantities.Dimensions; using Quantities.Measures; using Quantities.Prefixes; +using Quantities.Quantities.Roots; using Quantities.Units.Si; using Quantities.Units.Si.Derived; @@ -11,7 +12,7 @@ namespace Quantities.Quantities; , ISi , IMultiplyOperators { - private static readonly Creator create = new(); + private static readonly IRoot root = new UnitRoot(); private readonly Quant quant; internal Quant Quant => this.quant; private ElectricalResistance(in Quant quant) => this.quant = quant; @@ -45,7 +46,7 @@ public static ElectricalResistance Si(in Double value) public String ToString(String? format, IFormatProvider? provider) => this.quant.ToString(format, provider); internal static ElectricalResistance From(in ElectricPotential potential, in ElectricCurrent current) { - return new(MetricPrefix.ScaleThree(potential.Quant.SiDivide(current.Quant), create)); + return new(MetricPrefix.ScaleThree(potential.Quant.SiDivide(current.Quant), root)); } public static Boolean operator ==(ElectricalResistance left, ElectricalResistance right) => left.Equals(right); public static Boolean operator !=(ElectricalResistance left, ElectricalResistance right) => !left.Equals(right); @@ -59,10 +60,4 @@ internal static ElectricalResistance From(in ElectricPotential potential, in Ele // Ohm's Law public static ElectricPotential operator *(ElectricalResistance resistance, ElectricCurrent current) => ElectricPotential.From(in current, in resistance); - - private sealed class Creator : IPrefixInject - { - public Quant Identity(in Double value) => value.As>(); - public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); - } } diff --git a/quantities/quantities/Force.cs b/quantities/quantities/Force.cs index 360390ff..fc36d274 100644 --- a/quantities/quantities/Force.cs +++ b/quantities/quantities/Force.cs @@ -2,6 +2,7 @@ using Quantities.Dimensions; using Quantities.Measures; using Quantities.Prefixes; +using Quantities.Quantities.Roots; using Quantities.Units.Imperial; using Quantities.Units.NonStandard; using Quantities.Units.Si; @@ -16,7 +17,7 @@ namespace Quantities.Quantities; , INoSystem , IMultiplyOperators { - private static readonly Creator create = new(); + private static readonly IRoot root = new UnitRoot(); private readonly Quant quant; internal Quant Quant => this.quant; private Force(in Quant quant) => this.quant = quant; @@ -86,7 +87,7 @@ public static Force NonStandard(in Double value) internal static Force From(in Power power, in Velocity velocity) { - return new(MetricPrefix.ScaleThree(power.Quant.SiDivide(velocity.Quant), create)); + return new(MetricPrefix.ScaleThree(power.Quant.SiDivide(velocity.Quant), root)); } public Boolean Equals(Force other) => this.quant.Equals(other.quant); @@ -106,10 +107,4 @@ internal static Force From(in Power power, in Velocity velocity) public static Double operator /(Force left, Force right) => left.quant / right.quant; public static Power operator *(Force force, Velocity velocity) => Power.From(in force, in velocity); - - private sealed class Creator : IPrefixInject - { - public Quant Identity(in Double value) => value.As>(); - public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); - } } \ No newline at end of file diff --git a/quantities/quantities/Length.cs b/quantities/quantities/Length.cs index bf6de1e1..d3261923 100644 --- a/quantities/quantities/Length.cs +++ b/quantities/quantities/Length.cs @@ -3,6 +3,7 @@ using Quantities.Measures; using Quantities.Measures.Transformations; using Quantities.Prefixes; +using Quantities.Quantities.Roots; using Quantities.Units.Imperial; using Quantities.Units.Si; @@ -16,7 +17,7 @@ namespace Quantities.Quantities; , IMultiplyOperators , IDivisionOperators { - private static readonly Creator create = new(); + private static readonly IRoot root = new UnitRoot(); private static readonly ICreate linear = new ToLinear(); private readonly Quant quant; internal Quant Quant => this.quant; @@ -63,7 +64,7 @@ internal static Length From(in Area area, in Length length) internal static Length From(in Velocity velocity, in Time time) { // ToDo: Recover length units form velocity - return new(MetricPrefix.Scale(velocity.Quant.SiMultiply(time.Quant), create)); + return new(MetricPrefix.Scale(velocity.Quant.SiMultiply(time.Quant), root)); } internal static Length From(in Volume volume, in Area area) { @@ -90,10 +91,4 @@ internal static Length From(in Volume volume, in Area area) public static Length operator /(Length left, Double scalar) => new(left.quant / scalar); public static Double operator /(Length left, Length right) => left.quant / right.quant; public static Velocity operator /(Length left, Time right) => Velocity.From(in left, in right); - - private sealed class Creator : IPrefixInject - { - public Quant Identity(in Double value) => value.As>(); - public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); - } } \ No newline at end of file diff --git a/quantities/quantities/Power.cs b/quantities/quantities/Power.cs index 1efbc71c..40279a58 100644 --- a/quantities/quantities/Power.cs +++ b/quantities/quantities/Power.cs @@ -2,6 +2,7 @@ using Quantities.Dimensions; using Quantities.Measures; using Quantities.Prefixes; +using Quantities.Quantities.Roots; using Quantities.Units.Imperial; using Quantities.Units.Si; using Quantities.Units.Si.Derived; @@ -18,7 +19,7 @@ namespace Quantities.Quantities; , IDivisionOperators , IDivisionOperators { - private static readonly Creator create = new(); + private static readonly IRoot root = new UnitRoot(); private readonly Quant quant; internal Quant Quant => this.quant; private Power(in Quant quant) => this.quant = quant; @@ -79,15 +80,15 @@ public static Power Metric(in Double value) internal static Power From(in ElectricPotential potential, in ElectricCurrent current) { - return new(MetricPrefix.ScaleThree(potential.Quant.SiMultiply(current.Quant), create)); + return new(MetricPrefix.ScaleThree(potential.Quant.SiMultiply(current.Quant), root)); } internal static Power From(in Force force, in Velocity velocity) { - return new(MetricPrefix.ScaleThree(force.Quant.SiMultiply(velocity.Quant), create)); + return new(MetricPrefix.ScaleThree(force.Quant.SiMultiply(velocity.Quant), root)); } internal static Power From(in Energy energy, in Time time) { - return new(MetricPrefix.ScaleThree(energy.Quant.SiDivide(time.Quant), create)); + return new(MetricPrefix.ScaleThree(energy.Quant.SiDivide(time.Quant), root)); } public Boolean Equals(Power other) => this.quant.Equals(other.quant); @@ -111,10 +112,4 @@ internal static Power From(in Energy energy, in Time time) public static Velocity operator /(Power power, Force force) => Velocity.From(in power, in force); public static Force operator /(Power power, Velocity velocity) => Force.From(in power, in velocity); public static Energy operator *(Power left, Time right) => Energy.From(in left, in right); - - private sealed class Creator : IPrefixInject - { - public Quant Identity(in Double value) => value.As>(); - public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); - } } diff --git a/quantities/quantities/Time.cs b/quantities/quantities/Time.cs index 359e83f1..f8a0ceae 100644 --- a/quantities/quantities/Time.cs +++ b/quantities/quantities/Time.cs @@ -2,6 +2,7 @@ using Quantities.Dimensions; using Quantities.Measures; using Quantities.Prefixes; +using Quantities.Quantities.Roots; using Quantities.Units.Si; namespace Quantities.Quantities; @@ -12,7 +13,7 @@ namespace Quantities.Quantities; , IMultiplyOperators // ToDo: Can't apply ISi, or INoSystem interfaces... { - private static readonly Creator create = new(); + private static readonly IRoot root = new UnitRoot(); private readonly Quant quant; internal Quant Quant => this.quant; private Time(in Quant quant) => this.quant = quant; @@ -45,7 +46,7 @@ public static Time In(in Double value) internal static Time From(in Energy energy, in Power power) { // ToDo: Extract the time component! - return new(MetricPrefix.ScaleThree(energy.Quant.SiDivide(power.Quant), create)); + return new(MetricPrefix.ScaleThree(energy.Quant.SiDivide(power.Quant), root)); } public Boolean Equals(Time other) => this.quant.Equals(other.quant); @@ -67,10 +68,4 @@ internal static Time From(in Energy energy, in Power power) public static Length operator *(Time left, Velocity right) => Length.From(in right, in left); public static Data operator *(Time left, DataRate right) => Data.From(in left, in right); - - private sealed class Creator : IPrefixInject - { - public Quant Identity(in Double value) => value.As>(); - public Quant Inject(in Double value) where TPrefix : IPrefix => value.As>(); - } } \ No newline at end of file diff --git a/quantities/quantities/Velocity.cs b/quantities/quantities/Velocity.cs index ee2efa54..f209385f 100644 --- a/quantities/quantities/Velocity.cs +++ b/quantities/quantities/Velocity.cs @@ -3,6 +3,7 @@ using Quantities.Measures; using Quantities.Prefixes; using Quantities.Quantities.Builders; +using Quantities.Quantities.Roots; using Quantities.Units.Imperial; using Quantities.Units.Si; @@ -12,7 +13,7 @@ namespace Quantities.Quantities; , IMultiplyOperators , IMultiplyOperators { - private static readonly Creator create = new(); + private static readonly IRoot root = new FractionalRoot(); private readonly Quant quant; internal Quant Quant => this.quant; internal Velocity(in Quant quant) => this.quant = quant; @@ -46,7 +47,7 @@ public static IBuilder Imperial(in Double value) } internal static Velocity From(in Power power, in Force force) { - return new(MetricPrefix.Scale(power.Quant.SiDivide(force.Quant), create)); + return new(MetricPrefix.Scale(power.Quant.SiDivide(force.Quant), root)); } internal static Velocity From(in Length length, in Time time) => new(length.Quant.Divide(time.Quant)); @@ -69,10 +70,4 @@ internal static Velocity From(in Power power, in Force force) public static Power operator *(Velocity velocity, Force force) => Power.From(in force, in velocity); public static Length operator *(Velocity left, Time right) => Length.From(in left, in right); - - private sealed class Creator : IPrefixInject - { - public Quant Identity(in Double value) => value.AsFraction, Si>(); - public Quant Inject(in Double value) where TPrefix : IPrefix => value.AsFraction, Si>(); - } } \ No newline at end of file diff --git a/quantities/quantities/roots/FractionalRoot.cs b/quantities/quantities/roots/FractionalRoot.cs new file mode 100644 index 00000000..5fe5c041 --- /dev/null +++ b/quantities/quantities/roots/FractionalRoot.cs @@ -0,0 +1,15 @@ +using Quantities.Measures; +using Quantities.Prefixes; +using Quantities.Units.Si; + +namespace Quantities.Quantities.Roots; + +internal sealed class FractionalRoot : IRoot + where TNominator : ISiUnit + where TDenominator : ISiUnit +{ + public static Quant One => throw new NotImplementedException(); + public static Quant Zero => throw new NotImplementedException(); + Quant IPrefixInject.Identity(in Double value) => value.AsFraction, Si>(); + Quant IPrefixInject.Inject(in Double value) => value.AsFraction, Si>(); +} diff --git a/quantities/quantities/roots/IRoot.cs b/quantities/quantities/roots/IRoot.cs new file mode 100644 index 00000000..6284c713 --- /dev/null +++ b/quantities/quantities/roots/IRoot.cs @@ -0,0 +1,11 @@ +using Quantities.Measures; +using Quantities.Prefixes; + +namespace Quantities.Quantities.Roots; + +// ToDo: Use the One & Zero properties to implement multiplicative and additive identities +internal interface IRoot : IPrefixInject +{ + public static abstract Quant One { get; } + public static abstract Quant Zero { get; } +} diff --git a/quantities/quantities/roots/UnitRoot.cs b/quantities/quantities/roots/UnitRoot.cs new file mode 100644 index 00000000..6e569527 --- /dev/null +++ b/quantities/quantities/roots/UnitRoot.cs @@ -0,0 +1,15 @@ +using Quantities.Measures; +using Quantities.Prefixes; +using Quantities.Units.Si; + +namespace Quantities.Quantities.Roots; + +// ToDo: This should be used as basis for some kind of root object to also be used +internal sealed class UnitRoot : IRoot + where TSiUnit : struct, ISiUnit +{ + public static Quant One { get; } = 1d.As>(); + public static Quant Zero { get; } = 0d.As>(); + Quant IPrefixInject.Identity(in Double value) => value.As>(); + Quant IPrefixInject.Inject(in Double value) => value.As>(); +} \ No newline at end of file From 76909eca85d3549958f82d107e2bb964bb7e5d13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=A4gi?= Date: Sun, 30 Apr 2023 07:36:46 +0200 Subject: [PATCH 04/30] Try out new instantiation pattern. --- quantities.benchmark/AddingQuantities.cs | 10 +-- quantities.benchmark/CreateQuantities.cs | 24 +++---- quantities.benchmark/MultiplyingQuantities.cs | 8 +-- quantities.test/AreaTest.cs | 18 ++--- quantities.test/LengthTest.cs | 71 ++++++++++--------- quantities.test/VelocityTest.cs | 6 +- quantities.test/VolumeTest.cs | 4 +- quantities/IQuantityFactory.cs | 1 - quantities/quantities/Length.cs | 24 ++----- quantities/systems/IFactory.cs | 38 ++++++++++ .../systems/{ISystem.cs => LinearSystem.cs} | 23 ++---- quantities/systems/SiSystem.cs | 18 +++++ .../Si/Metric/\303\205ngstr\303\266m.cs" | 11 +++ 13 files changed, 151 insertions(+), 105 deletions(-) create mode 100644 quantities/systems/IFactory.cs rename quantities/systems/{ISystem.cs => LinearSystem.cs} (67%) create mode 100644 quantities/systems/SiSystem.cs create mode 100644 "quantities/units/Si/Metric/\303\205ngstr\303\266m.cs" diff --git a/quantities.benchmark/AddingQuantities.cs b/quantities.benchmark/AddingQuantities.cs index 266d26c5..a99665b5 100644 --- a/quantities.benchmark/AddingQuantities.cs +++ b/quantities.benchmark/AddingQuantities.cs @@ -11,11 +11,11 @@ namespace Quantities.Benchmark; [MemoryDiagnoser] public class AddingQuantities { - private Length sameMetric = Length.Si(-7); - private Length largeMetric = Length.Si(3); - private Length smallMetric = Length.Si(23); - private Length largeImperial = Length.Imperial(-3); - private Length smallImperial = Length.Imperial(55); + private Length sameMetric = Length.Of(-7).Si(); + private Length largeMetric = Length.Of(3).Si(); + private Length smallMetric = Length.Of(23).Si(); + private Length largeImperial = Length.Of(-3).Imperial(); + private Length smallImperial = Length.Of(55).Imperial(); private Trivial largeTrivial = Trivial.Si(Prefix.Kilo, 3); private Trivial smallTrivial = Trivial.Si(Prefix.Micro, 12); diff --git a/quantities.benchmark/CreateQuantities.cs b/quantities.benchmark/CreateQuantities.cs index 15a9ff64..e1a9f51b 100644 --- a/quantities.benchmark/CreateQuantities.cs +++ b/quantities.benchmark/CreateQuantities.cs @@ -38,7 +38,7 @@ public class CreateQuantities public DummyStruct CreateStruct() => new DummyStruct(this.value); [Benchmark] - public Length CreateLength() => Length.Si(in this.value); + public Length CreateLength() => Length.Of(in this.value).Si(); [Benchmark] public Velocity CreateVelocity() => Velocity.Si(in this.value).Per(); @@ -47,18 +47,18 @@ public class CreateQuantities /* // * Summary * -BenchmarkDotNet=v0.12.1, OS=arch +BenchmarkDotNet=v0.13.2, OS=arch Intel Core i7-8565U CPU 1.80GHz (Whiskey Lake), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=7.0.100 - [Host] : .NET Core 7.0.0 (CoreCLR 7.0.22.56001, CoreFX 7.0.22.56001), X64 RyuJIT - DefaultJob : .NET Core 7.0.0 (CoreCLR 7.0.22.56001, CoreFX 7.0.22.56001), X64 RyuJIT +.NET SDK=7.0.103 + [Host] : .NET 7.0.3 (7.0.323.12801), X64 RyuJIT AVX2 + DefaultJob : .NET 7.0.3 (7.0.323.12801), X64 RyuJIT AVX2 -| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | -|--------------- |-----------:|----------:|----------:|------:|--------:|-------:|------:|------:|----------:| -| CreateObject | 6.6147 ns | 0.0908 ns | 0.0805 ns | 1.000 | 0.00 | 0.0057 | - | - | 24 B | -| CreateObjectIn | 6.0880 ns | 0.0495 ns | 0.0463 ns | 0.921 | 0.01 | 0.0057 | - | - | 24 B | -| CreateStruct | 0.0547 ns | 0.0147 ns | 0.0138 ns | 0.008 | 0.00 | - | - | - | - | -| CreateLength | 4.2311 ns | 0.0568 ns | 0.0504 ns | 0.640 | 0.01 | - | - | - | - | -| CreateVelocity | 10.0543 ns | 0.0173 ns | 0.0135 ns | 1.522 | 0.02 | 0.0057 | - | - | 24 B | +| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio | +|--------------- |-----------:|----------:|----------:|------:|--------:|-------:|----------:|------------:| +| CreateObject | 6.1821 ns | 0.1096 ns | 0.1025 ns | 1.00 | 0.00 | 0.0057 | 24 B | 1.00 | +| CreateObjectIn | 6.7297 ns | 0.0760 ns | 0.0711 ns | 1.09 | 0.03 | 0.0057 | 24 B | 1.00 | +| CreateStruct | 0.3338 ns | 0.0049 ns | 0.0043 ns | 0.05 | 0.00 | - | - | 0.00 | +| CreateLength | 4.3623 ns | 0.0216 ns | 0.0192 ns | 0.71 | 0.01 | - | - | 0.00 | +| CreateVelocity | 10.5074 ns | 0.0638 ns | 0.0597 ns | 1.70 | 0.03 | 0.0057 | 24 B | 1.00 | */ diff --git a/quantities.benchmark/MultiplyingQuantities.cs b/quantities.benchmark/MultiplyingQuantities.cs index 3f15b986..3c4e1a17 100644 --- a/quantities.benchmark/MultiplyingQuantities.cs +++ b/quantities.benchmark/MultiplyingQuantities.cs @@ -12,10 +12,10 @@ namespace Quantities.Benchmark; [MemoryDiagnoser] public class MultiplyingQuantities { - private Length largeMetric = Length.Si(3); - private Length smallMetric = Length.Si(23); - private Length largeImperial = Length.Imperial(-3); - private Length smallImperial = Length.Imperial(55); + private Length largeMetric = Length.Of(3).Si(); + private Length smallMetric = Length.Of(23).Si(); + private Length largeImperial = Length.Of(-3).Imperial(); + private Length smallImperial = Length.Of(55).Imperial(); private ElectricCurrent current = ElectricCurrent.Si(200); private ElectricalResistance resistance = ElectricalResistance.Si(734); private Trivial largeTrivial = Trivial.Si(Prefix.Kilo, 3); diff --git a/quantities.test/AreaTest.cs b/quantities.test/AreaTest.cs index bfc8cbf7..0a8e342f 100644 --- a/quantities.test/AreaTest.cs +++ b/quantities.test/AreaTest.cs @@ -56,8 +56,8 @@ public void SquareYardToSquareFeet() public void SquareMetresDividedByMetre() { Area area = Area.Square(48.40); - Length length = Length.Si(605); - Length expected = Length.Si(0.8); + Length length = Length.Of(605).Si(); + Length expected = Length.Of(0.8).Si(); Length actual = area / length; @@ -67,8 +67,8 @@ public void SquareMetresDividedByMetre() public void PureArealDimensionDividedByLength() { Area area = Area.Imperial(2); - Length length = Length.Imperial(1815); - Length expected = Length.Imperial(16); + Length length = Length.Of(1815).Imperial(); + Length expected = Length.Of(16).Imperial(); Length actual = area / length; @@ -78,8 +78,8 @@ public void PureArealDimensionDividedByLength() public void SquareYardsDividedByFeet() { Area area = Area.SquareImperial(27); - Length length = Length.Imperial(1); - Length expected = Length.Imperial(9); + Length length = Length.Of(1).Imperial(); + Length expected = Length.Of(9).Imperial(); Length actual = area / length; @@ -98,7 +98,7 @@ public void AcreDividedBySquareFeet() public void SquareMetersTimesMetres() { Area area = Area.Square(27); - Length length = Length.Si(30); + Length length = Length.Of(30).Si(); Volume expected = Volume.Cubic(81); Volume actual = area * length; @@ -109,7 +109,7 @@ public void SquareMetersTimesMetres() public void SquareFeetTimesYards() { Area area = Area.SquareImperial(27); - Length length = Length.Imperial(2); + Length length = Length.Of(2).Imperial(); Volume expected = Volume.CubicImperial(162); Volume actual = area * length; @@ -151,7 +151,7 @@ public void MorgenToHectare() public void AreTimesMeterIsCubicMetre() { Area area = Area.Metric(1); - Length length = Length.Si(10); + Length length = Length.Of(10).Si(); Volume expected = Volume.Cubic(10 * 10 * 10); Volume actual = area * length; diff --git a/quantities.test/LengthTest.cs b/quantities.test/LengthTest.cs index f3cc97d6..ee98e54b 100644 --- a/quantities.test/LengthTest.cs +++ b/quantities.test/LengthTest.cs @@ -4,13 +4,13 @@ namespace Quantities.Test; public sealed class LengthTest { - private const Double MILES_IN_KILOMETRE = 1.609344d; - private const Double KILOMETRE_IN_MILES = 1d / MILES_IN_KILOMETRE; + private const Double miles_in_kilometre = 1.609344d; + private const Double kilometre_in_miles = 1d / miles_in_kilometre; [Fact] public void MetreToKilometre() { - Length metres = Length.Si(1000); + Length metres = Length.Of(1000).Si(); Length kilometres = metres.To(); PrecisionIsBounded(1d, kilometres); } @@ -18,15 +18,23 @@ public void MetreToKilometre() [Fact] public void MetreToMillimetre() { - Length metres = Length.Si(1); + Length metres = Length.Of(1).Si(); Length millimetres = metres.To(); PrecisionIsBounded(1000d, millimetres); } + [Fact] + public void ÅngströmToNanoMetre() + { + Length ångström = Length.Of(10).Metric<Ångström>(); + Length nanoMetres = ångström.To(); + PrecisionIsBounded(1d, nanoMetres); + } + [Fact] public void MillimetreToKilometre() { - Length millimetres = Length.Si(2e6); + Length millimetres = Length.Of(2e6).Si(); Length kilometres = millimetres.To(); PrecisionIsBounded(2d, kilometres); } @@ -34,7 +42,7 @@ public void MillimetreToKilometre() [Fact] public void MileToKilometre() { - Length miles = Length.Imperial(1); + Length miles = Length.Of(1).Imperial(); Length kilometres = miles.To(); PrecisionIsBounded(1.609344, kilometres); } @@ -42,15 +50,15 @@ public void MileToKilometre() [Fact] public void KilometreToMile() { - Length kilometres = Length.Si(1.609344); + Length kilometres = Length.Of(1.609344).Si(); Length miles = kilometres.ToImperial(); PrecisionIsBounded(1d, miles); } [Fact] public void FootToMile() { - Length feet = Length.Imperial(5280); - Length expected = Length.Imperial(1); + Length feet = Length.Of(5280).Imperial(); + Length expected = Length.Of(1).Imperial(); Length actual = feet.ToImperial(); actual.Matches(expected); } @@ -58,49 +66,48 @@ public void FootToMile() [Fact] public void AddMetresToKiloMetres() { - Length kilometres = Length.Si(10); - Length metres = Length.Si(20); + Length kilometres = Length.Of(10).Si(); + Length metres = Length.Of(20).Si(); Length result = kilometres + metres; PrecisionIsBounded(10.02, result); } [Fact] public void AddKilometresToMiles() { - Length kilometres = Length.Si(1); - Length miles = Length.Imperial(1); + Length kilometres = Length.Of(1).Si(); + Length miles = Length.Of(1).Imperial(); Length result = miles + kilometres; - PrecisionIsBounded(1 + KILOMETRE_IN_MILES, result); + PrecisionIsBounded(1 + kilometre_in_miles, result); } [Fact] public void AddMilesToKilometres() { - Length kilometres = Length.Si(1); - Length miles = Length.Imperial(1); + Length kilometres = Length.Of(1).Si(); + Length miles = Length.Of(1).Imperial(); Length result = kilometres + miles; PrecisionIsBounded(2.609344, result); } [Fact] public void SubtractKilometresFromMetres() { - Length metres = Length.Si(2000); - Length kilometres = Length.Si(0.5); + Length metres = Length.Of(2000).Si(); + Length kilometres = Length.Of(0.5).Si(); Length result = metres - kilometres; PrecisionIsBounded(1500d, result); } - [Fact] public void SubtractMilesFromKilometres() { - Length kilometres = Length.Si(2.609344); - Length miles = Length.Imperial(1); + Length kilometres = Length.Of(2.609344).Si(); + Length miles = Length.Of(1).Imperial(); Length result = kilometres - miles; PrecisionIsBounded(1d, result); } [Fact] public void OneMileInYards() { - Length length = Length.Imperial(1); - Length expected = Length.Imperial(1760); + Length length = Length.Of(1).Imperial(); + Length expected = Length.Of(1760).Imperial(); Length actual = length.ToImperial(); @@ -109,8 +116,8 @@ public void OneMileInYards() [Fact] public void SiLengthBySiLengthIsSiArea() { - Length length = Length.Si(2); - Length width = Length.Si(1); + Length length = Length.Of(2).Si(); + Length width = Length.Of(1).Si(); Area expected = Area.Square(0.2); Area actual = length * width; @@ -120,8 +127,8 @@ public void SiLengthBySiLengthIsSiArea() [Fact] public void ImperialLengthByImperialLengthIsImperialArea() { - Length length = Length.Imperial(2); - Length width = Length.Imperial(1760 / 2); + Length length = Length.Of(2).Imperial(); + Length width = Length.Of(1760 / 2).Imperial(); Area expected = Area.SquareImperial(1); Area actual = length * width; @@ -133,7 +140,7 @@ public void LengthByDivisionIsEqualToLengthByConstruction() { Volume volume = Volume.Metric(300); Area area = Area.Square(6); - Length expected = Length.Si(5); + Length expected = Length.Of(5).Si(); Length actual = volume / area; @@ -143,7 +150,7 @@ public void LengthByDivisionIsEqualToLengthByConstruction() [Fact] public void SiLengthBySiTimeIsVelocity() { - Length distance = Length.Si(100); + Length distance = Length.Of(100).Si(); Time duration = Time.Seconds(20); Velocity expected = Velocity.Si(5).PerSecond(); @@ -154,7 +161,7 @@ public void SiLengthBySiTimeIsVelocity() [Fact] public void SiLengthByMetricTimeIsVelocity() { - Length distance = Length.Si(120); + Length distance = Length.Of(120).Si(); Time duration = Time.In(10); Velocity expected = Velocity.Si(12).Per(); @@ -165,7 +172,7 @@ public void SiLengthByMetricTimeIsVelocity() [Fact] public void ImperialLengthByTimeIsVelocity() { - Length distance = Length.Imperial(70); + Length distance = Length.Of(70).Imperial(); Time duration = Time.In(2); Velocity expected = Velocity.Imperial(35).Per(); @@ -179,7 +186,7 @@ public void VelocityTimesTimeIsLength() Time duration = Time.In(12); Velocity velocity = Velocity.Imperial(350).Per(); // Miles are not yet preserved across multiplication... - Length expected = Length.Si(350 * 12 * MILES_IN_KILOMETRE / 60); + Length expected = Length.Of(350 * 12 * miles_in_kilometre / 60).Si(); Length actual = velocity * duration; diff --git a/quantities.test/VelocityTest.cs b/quantities.test/VelocityTest.cs index 1166cda3..2783eeaa 100644 --- a/quantities.test/VelocityTest.cs +++ b/quantities.test/VelocityTest.cs @@ -70,7 +70,7 @@ public void MetresPerSecondToMilesPerHourTo() [Fact] public void VelocityFromDivisionOfLengthWithTime_SiUnits() { - Length length = Length.Si(12); + Length length = Length.Of(12).Si(); Time time = Time.Seconds(2); Velocity expected = Velocity.Si(6).PerSecond(); @@ -81,7 +81,7 @@ public void VelocityFromDivisionOfLengthWithTime_SiUnits() [Fact] public void VelocityFromDivisionOfLengthWithTime_ImperialUnits() { - Length length = Length.Imperial(18); + Length length = Length.Of(18).Imperial(); Time time = Time.In(2); Velocity expected = Velocity.Imperial(9).Per(); @@ -94,7 +94,7 @@ public void VelocityFromDivisionOfLengthWithTime_ImperialUnits() [Fact] public void VelocityFromDivision_Equal_DirectVelocity() { - Length length = Length.Imperial(18); + Length length = Length.Of(18).Imperial(); Time time = Time.In(2); Velocity expected = Velocity.Imperial(9).Per(); diff --git a/quantities.test/VolumeTest.cs b/quantities.test/VolumeTest.cs index 5faabade..94bc0078 100644 --- a/quantities.test/VolumeTest.cs +++ b/quantities.test/VolumeTest.cs @@ -107,7 +107,7 @@ public void FromMillilitreToImperialFluidOunce() public void DivideCubicMetreByMetre() { Volume volume = Volume.Cubic(81); - Length length = Length.Si(3); + Length length = Length.Of(3).Si(); Area expected = Area.Square(27); Area actual = volume / length; @@ -118,7 +118,7 @@ public void DivideCubicMetreByMetre() public void DividePureVolumeByLength() { Volume volume = Volume.Metric(300); - Length length = Length.Si(5); + Length length = Length.Of(5).Si(); Area expected = Area.Square(6); Area actual = volume / length; diff --git a/quantities/IQuantityFactory.cs b/quantities/IQuantityFactory.cs index 0bbf9d59..f597e0d1 100644 --- a/quantities/IQuantityFactory.cs +++ b/quantities/IQuantityFactory.cs @@ -6,6 +6,5 @@ public interface IQuantityFactory where TDimension : Dimensions.IDimension where TSelf : struct, IQuantity, TDimension { - internal Quant Quant { get; } internal static abstract TSelf Create(in Quant quant); } diff --git a/quantities/quantities/Length.cs b/quantities/quantities/Length.cs index d3261923..b74e7d2b 100644 --- a/quantities/quantities/Length.cs +++ b/quantities/quantities/Length.cs @@ -4,6 +4,7 @@ using Quantities.Measures.Transformations; using Quantities.Prefixes; using Quantities.Quantities.Roots; +using Quantities.Systems; using Quantities.Units.Imperial; using Quantities.Units.Si; @@ -11,8 +12,7 @@ namespace Quantities.Quantities; public readonly struct Length : IQuantity, ILength , IQuantityFactory - , ISi - , IImperial + , IFactory> , IMultiplyOperators , IMultiplyOperators , IDivisionOperators @@ -21,7 +21,6 @@ namespace Quantities.Quantities; private static readonly ICreate linear = new ToLinear(); private readonly Quant quant; internal Quant Quant => this.quant; - Quant IQuantityFactory.Quant => this.quant; private Length(in Quant quant) => this.quant = quant; public Length To() where TUnit : ISiUnit, ILength @@ -40,22 +39,9 @@ public Length ToImperial() return new(this.quant.As>()); } static Length IQuantityFactory.Create(in Quant quant) => new(in quant); - public static Length Si(in Double value) - where TUnit : ISiUnit, ILength - { - return new(value.As>()); - } - public static Length Si(in Double value) - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, ILength - { - return new(value.As>()); - } - public static Length Imperial(in Double value) - where TUnit : IImperial, ILength - { - return new(value.As>()); - } + + public static LinearSystem Of(in Double value) => new(in value); + internal static Length From(in Area area, in Length length) { var pseudoArea = area.Quant.Transform(in linear); diff --git a/quantities/systems/IFactory.cs b/quantities/systems/IFactory.cs new file mode 100644 index 00000000..ea0a6cfc --- /dev/null +++ b/quantities/systems/IFactory.cs @@ -0,0 +1,38 @@ +using Quantities.Dimensions; +using Quantities.Prefixes; +using Quantities.Units.Imperial; +using Quantities.Units.NonStandard; +using Quantities.Units.Si; + +namespace Quantities.Systems; + +public interface IFactory { /* marker interface */ } + +public interface IFactory : IFactory + where TFactory : IFactory +{ + public static abstract TFactory Of(in Double value); +} +public interface ISiFactory : IFactory + where TDimension : IDimension, ILinear +{ + public TSelf Si() where TUnit : ISiUnit, TDimension; + public TSelf Si() where TPrefix : IMetricPrefix where TUnit : ISiUnit, TDimension; +} + +public interface IMetricFactory : IFactory + where TDimension : IDimension, ILinear +{ + public TSelf Metric() where TUnit : IMetricUnit, TDimension; + public TSelf Metric() where TPrefix : IMetricPrefix where TUnit : IMetricUnit, TDimension; +} + +public interface IImperialFactory +{ + public TSelf Imperial() where TUnit : IImperial, TDimension; +} + +public interface INonStandardFactory +{ + public TSelf NonStandard() where TUnit : INoSystem, TDimension; +} \ No newline at end of file diff --git a/quantities/systems/ISystem.cs b/quantities/systems/LinearSystem.cs similarity index 67% rename from quantities/systems/ISystem.cs rename to quantities/systems/LinearSystem.cs index 59179969..f6262aa9 100644 --- a/quantities/systems/ISystem.cs +++ b/quantities/systems/LinearSystem.cs @@ -1,5 +1,3 @@ - - using Quantities.Dimensions; using Quantities.Measures; using Quantities.Prefixes; @@ -9,27 +7,17 @@ namespace Quantities.Systems; -public interface ISystem -{ - -} - -public interface IQuantityBuilder - where TSystem : ISystem -{ - public static abstract TSystem Of(in Double value); -} - -public readonly struct Linear : ISystem +public readonly struct LinearSystem + : ISiFactory, IMetricFactory, IImperialFactory, INonStandardFactory where TDimension : Dimensions.IDimension, ILinear where TSelf : struct, IQuantity, IQuantityFactory, TDimension { private readonly Double value; - internal Linear(in Double value) => this.value = value; - public TSelf Si() where TUnit : ISiBaseUnit, TDimension => TSelf.Create(this.value.As>()); + internal LinearSystem(in Double value) => this.value = value; + public TSelf Si() where TUnit : ISiUnit, TDimension => TSelf.Create(this.value.As>()); public TSelf Si() where TPrefix : IMetricPrefix - where TUnit : ISiBaseUnit, TDimension => TSelf.Create(this.value.As>()); + where TUnit : ISiUnit, TDimension => TSelf.Create(this.value.As>()); public TSelf Metric() where TUnit : IMetricUnit, TDimension => TSelf.Create(this.value.As>()); public TSelf Metric() where TPrefix : IMetricPrefix @@ -37,6 +25,5 @@ public TSelf Metric() public TSelf Imperial() where TUnit : IImperial, TDimension => TSelf.Create(this.value.As>()); public TSelf NonStandard() where TUnit : INoSystem, TDimension => TSelf.Create(this.value.As>()); - } diff --git a/quantities/systems/SiSystem.cs b/quantities/systems/SiSystem.cs new file mode 100644 index 00000000..f64178d2 --- /dev/null +++ b/quantities/systems/SiSystem.cs @@ -0,0 +1,18 @@ +using Quantities.Dimensions; +using Quantities.Measures; +using Quantities.Prefixes; +using Quantities.Units.Si; + +namespace Quantities.Systems; + +public readonly struct SiSystem : ISiFactory + where TDimension : Dimensions.IDimension, ILinear + where TSelf : struct, IQuantity, IQuantityFactory, TDimension +{ + private readonly Double value; + internal SiSystem(in Double value) => this.value = value; + public TSelf Si() where TUnit : ISiUnit, TDimension => TSelf.Create(this.value.As>()); + public TSelf Si() + where TPrefix : IMetricPrefix + where TUnit : ISiUnit, TDimension => TSelf.Create(this.value.As>()); +} diff --git "a/quantities/units/Si/Metric/\303\205ngstr\303\266m.cs" "b/quantities/units/Si/Metric/\303\205ngstr\303\266m.cs" new file mode 100644 index 00000000..d8164a3d --- /dev/null +++ "b/quantities/units/Si/Metric/\303\205ngstr\303\266m.cs" @@ -0,0 +1,11 @@ +using Quantities.Dimensions; + +namespace Quantities.Units.Si.Metric; + +public class Ångström : IMetricUnit, ILength +{ + internal const Double MetreToÅngström = 1e10; // m -> Å + public static Double ToSi(in Double value) => value / MetreToÅngström; + public static Double FromSi(in Double value) => value * MetreToÅngström; + public static String Representation => "Å"; +} From bce81964c02d1d5c173a9ec199154a2c3842bd5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=A4gi?= Date: Sun, 30 Apr 2023 10:40:09 +0200 Subject: [PATCH 05/30] Use new instantiation on ElectricPotential. --- quantities.benchmark/DividingQuantities.cs | 2 +- quantities.test/ElectricCurrentTest.cs | 8 ++++---- quantities.test/ElectricPotentialTest.cs | 18 +++++++++--------- quantities.test/ElectricalResistanceTest.cs | 4 ++-- quantities.test/PowerTest.cs | 6 +++--- quantities/IQuantityFactory.cs | 1 + quantities/dimensions/ElectricalDimesions.cs | 4 ++-- quantities/quantities/ElectricPotential.cs | 18 ++++++------------ quantities/quantities/Length.cs | 1 + 9 files changed, 29 insertions(+), 33 deletions(-) diff --git a/quantities.benchmark/DividingQuantities.cs b/quantities.benchmark/DividingQuantities.cs index bad43814..dec710b4 100644 --- a/quantities.benchmark/DividingQuantities.cs +++ b/quantities.benchmark/DividingQuantities.cs @@ -20,7 +20,7 @@ public class DividingQuantities private Area imperialPureArea = Area.Imperial(23); private Volume imperialVolume = Volume.CubicImperial(-3); private Area imperialArea = Area.SquareImperial(55); - private ElectricPotential potential = ElectricPotential.Si(33); + private ElectricPotential potential = ElectricPotential.Of(33).Si(); private ElectricCurrent current = ElectricCurrent.Si(98); private Trivial largeTrivial = Trivial.Si(Prefix.Kilo, 3); private Trivial smallTrivial = Trivial.Si(Prefix.Micro, 12); diff --git a/quantities.test/ElectricCurrentTest.cs b/quantities.test/ElectricCurrentTest.cs index 631fced5..6701ce6b 100644 --- a/quantities.test/ElectricCurrentTest.cs +++ b/quantities.test/ElectricCurrentTest.cs @@ -13,7 +13,7 @@ public sealed class ElectricCurrentTest [Fact] public void OhmsLawInBaseUnits() { - ElectricPotential volts = ElectricPotential.Si(12); + ElectricPotential volts = ElectricPotential.Of(12).Si(); ElectricalResistance ohm = ElectricalResistance.Si(3); ElectricCurrent expected = ElectricCurrent.Si(4); @@ -24,7 +24,7 @@ public void OhmsLawInBaseUnits() [Fact] public void OhmsLawInPrefixedUnits() { - ElectricPotential volts = ElectricPotential.Si(12); + ElectricPotential volts = ElectricPotential.Of(12).Si(); ElectricalResistance ohm = ElectricalResistance.Si(3); ElectricCurrent expected = ElectricCurrent.Si(4); @@ -36,7 +36,7 @@ public void OhmsLawInPrefixedUnits() public void PowerLawInBaseUnits() { Power watts = Power.Si(1380); - ElectricPotential volts = ElectricPotential.Si(230); + ElectricPotential volts = ElectricPotential.Of(230).Si(); ElectricCurrent expected = ElectricCurrent.Si(6); ElectricCurrent current = watts / volts; @@ -47,7 +47,7 @@ public void PowerLawInBaseUnits() public void PowerLawInPrefixedUnits() { Power watts = Power.Si(9); - ElectricPotential volts = ElectricPotential.Si(15); + ElectricPotential volts = ElectricPotential.Of(15).Si(); ElectricCurrent expected = ElectricCurrent.Si(600); ElectricCurrent current = watts / volts; diff --git a/quantities.test/ElectricPotentialTest.cs b/quantities.test/ElectricPotentialTest.cs index cb45d480..946709e7 100644 --- a/quantities.test/ElectricPotentialTest.cs +++ b/quantities.test/ElectricPotentialTest.cs @@ -5,17 +5,17 @@ namespace Quantities.Test; public sealed class ElectricPotentialTest { [Fact] - public void VoltToString() => FormattingMatches(v => ElectricPotential.Si(v), "V"); + public void VoltToString() => FormattingMatches(v => ElectricPotential.Of(v).Si(), "V"); [Fact] - public void MegaVoltToString() => FormattingMatches(v => ElectricPotential.Si(v), "MV"); + public void MegaVoltToString() => FormattingMatches(v => ElectricPotential.Of(v).Si(), "MV"); [Fact] - public void MilliVoltToString() => FormattingMatches(v => ElectricPotential.Si(v), "mV"); + public void MilliVoltToString() => FormattingMatches(v => ElectricPotential.Of(v).Si(), "mV"); [Fact] public void OhmsLawInBaseUnits() { ElectricalResistance ohm = ElectricalResistance.Si(7); ElectricCurrent ampere = ElectricCurrent.Si(3); - ElectricPotential expected = ElectricPotential.Si(21); + ElectricPotential expected = ElectricPotential.Of(21).Si(); ElectricPotential potential = ohm * ampere; @@ -26,7 +26,7 @@ public void OhmsLawInPrefixedUnits() { ElectricalResistance ohm = ElectricalResistance.Si(7); ElectricCurrent ampere = ElectricCurrent.Si(3); - ElectricPotential expected = ElectricPotential.Si(21); + ElectricPotential expected = ElectricPotential.Of(21).Si(); ElectricPotential potential = ohm * ampere; @@ -39,7 +39,7 @@ public void OhmsLawInPrefixedUnitsWithInBetweenVirtualPrefix() ElectricCurrent ampere = ElectricCurrent.Si(3); // 7e1Ω * 3e3A = 21e4V, since e4 is no prefix: expect 210e3 V - ElectricPotential expected = ElectricPotential.Si(210); + ElectricPotential expected = ElectricPotential.Of(210).Si(); ElectricPotential potential = ohm * ampere; @@ -50,7 +50,7 @@ public void PowerLawInBaseUnits() { Power watts = Power.Si(1380); ElectricCurrent ampere = ElectricCurrent.Si(6); - ElectricPotential expected = ElectricPotential.Si(230); + ElectricPotential expected = ElectricPotential.Of(230).Si(); ElectricPotential potential = watts / ampere; @@ -60,11 +60,11 @@ public void PowerLawInBaseUnits() public void PowerLawInPrefixedUnits() { Power watts = Power.Si(9); - _ = ElectricPotential.Si(15); + _ = ElectricPotential.Of(15).Si(); ElectricCurrent ampere = ElectricCurrent.Si(600); // ToDo: Implement rounding based on value! - ElectricPotential expected = ElectricPotential.Si(15); + ElectricPotential expected = ElectricPotential.Of(15).Si(); ElectricPotential potential = watts / ampere; diff --git a/quantities.test/ElectricalResistanceTest.cs b/quantities.test/ElectricalResistanceTest.cs index 91433aec..182c8967 100644 --- a/quantities.test/ElectricalResistanceTest.cs +++ b/quantities.test/ElectricalResistanceTest.cs @@ -13,7 +13,7 @@ public sealed class ElectricalResistanceTest [Fact] public void OhmsLawInBaseUnits() { - ElectricPotential volts = ElectricPotential.Si(12); + ElectricPotential volts = ElectricPotential.Of(12).Si(); ElectricCurrent ampere = ElectricCurrent.Si(3); ElectricalResistance expected = ElectricalResistance.Si(4); @@ -24,7 +24,7 @@ public void OhmsLawInBaseUnits() [Fact] public void OhmsLawInPrefixedUnits() { - ElectricPotential volts = ElectricPotential.Si(12); + ElectricPotential volts = ElectricPotential.Of(12).Si(); ElectricCurrent ampere = ElectricCurrent.Si(3); ElectricalResistance expected = ElectricalResistance.Si(4); diff --git a/quantities.test/PowerTest.cs b/quantities.test/PowerTest.cs index 63306ce8..f96f6cd0 100644 --- a/quantities.test/PowerTest.cs +++ b/quantities.test/PowerTest.cs @@ -14,7 +14,7 @@ public sealed class PowerTest [Fact] public void PowerLawInBaseUnits() { - ElectricPotential volts = ElectricPotential.Si(12); + ElectricPotential volts = ElectricPotential.Of(12).Si(); ElectricCurrent ampere = ElectricCurrent.Si(3); Power expected = Power.Si(36); @@ -25,7 +25,7 @@ public void PowerLawInBaseUnits() [Fact] public void OhmsLawInPrefixedUnits() { - ElectricPotential volts = ElectricPotential.Si(70); + ElectricPotential volts = ElectricPotential.Of(70).Si(); ElectricCurrent ampere = ElectricCurrent.Si(300); Power expected = Power.Si(21); @@ -36,7 +36,7 @@ public void OhmsLawInPrefixedUnits() [Fact] public void OhmsLawSquarePotentialPerResistance() { - ElectricPotential volts = ElectricPotential.Si(0.6); + ElectricPotential volts = ElectricPotential.Of(0.6).Si(); ElectricalResistance ohm = ElectricalResistance.Si(3); Power expected = Power.Si(120); diff --git a/quantities/IQuantityFactory.cs b/quantities/IQuantityFactory.cs index f597e0d1..0bbf9d59 100644 --- a/quantities/IQuantityFactory.cs +++ b/quantities/IQuantityFactory.cs @@ -6,5 +6,6 @@ public interface IQuantityFactory where TDimension : Dimensions.IDimension where TSelf : struct, IQuantity, TDimension { + internal Quant Quant { get; } internal static abstract TSelf Create(in Quant quant); } diff --git a/quantities/dimensions/ElectricalDimesions.cs b/quantities/dimensions/ElectricalDimesions.cs index 87160d5c..0beac3bb 100644 --- a/quantities/dimensions/ElectricalDimesions.cs +++ b/quantities/dimensions/ElectricalDimesions.cs @@ -1,6 +1,6 @@ namespace Quantities.Dimensions; -public interface IElectricPotential : IDimension { /* marker interface */ } -public interface IElectricalResistance : IDimension { /* marker interface */ } +public interface IElectricPotential : IDimension, ILinear { /* marker interface */ } +public interface IElectricalResistance : IDimension, ILinear { /* marker interface */ } public interface IAmountOfInformation : IDimension, ILinear { /* marker interface */ } public interface IInformationRate : IPer { /* marker interface */ } diff --git a/quantities/quantities/ElectricPotential.cs b/quantities/quantities/ElectricPotential.cs index 725d9c0a..0d118c6e 100644 --- a/quantities/quantities/ElectricPotential.cs +++ b/quantities/quantities/ElectricPotential.cs @@ -3,13 +3,15 @@ using Quantities.Measures; using Quantities.Prefixes; using Quantities.Quantities.Roots; +using Quantities.Systems; using Quantities.Units.Si; using Quantities.Units.Si.Derived; namespace Quantities.Quantities; public readonly struct ElectricPotential : IQuantity, IElectricPotential - , ISi + , IQuantityFactory + , IFactory> , IMultiplyOperators , IDivisionOperators , IDivisionOperators @@ -17,6 +19,7 @@ namespace Quantities.Quantities; private static readonly IRoot root = new UnitRoot(); private readonly Quant quant; internal Quant Quant => this.quant; + Quant IQuantityFactory.Quant => this.quant; private ElectricPotential(in Quant quant) => this.quant = quant; public ElectricPotential To() where TUnit : ISiUnit, IElectricPotential @@ -29,17 +32,8 @@ public ElectricPotential To() { return new(this.quant.As>()); } - public static ElectricPotential Si(in Double value) - where TUnit : ISiUnit, IElectricPotential - { - return new(value.As>()); - } - public static ElectricPotential Si(in Double value) - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, IElectricPotential - { - return new(value.As>()); - } + static ElectricPotential IQuantityFactory.Create(in Quant quant) => new(in quant); + public static SiSystem Of(in Double value) => new(in value); public Boolean Equals(ElectricPotential other) => this.quant.Equals(other.quant); public String ToString(String? format, IFormatProvider? provider) => this.quant.ToString(format, provider); diff --git a/quantities/quantities/Length.cs b/quantities/quantities/Length.cs index b74e7d2b..83b62da3 100644 --- a/quantities/quantities/Length.cs +++ b/quantities/quantities/Length.cs @@ -21,6 +21,7 @@ namespace Quantities.Quantities; private static readonly ICreate linear = new ToLinear(); private readonly Quant quant; internal Quant Quant => this.quant; + Quant IQuantityFactory.Quant => this.quant; private Length(in Quant quant) => this.quant = quant; public Length To() where TUnit : ISiUnit, ILength From 66cfabb82def128ed1f47f7928b726ef26eac5d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=A4gi?= Date: Mon, 1 May 2023 09:53:54 +0200 Subject: [PATCH 06/30] Clean up quantity factories. --- quantities/dimensions/IDimension.cs | 1 + quantities/factories/Factories.cs | 33 ++++++++++++++++ quantities/factories/ICompoundFactory.cs | 10 +++++ quantities/factories/IFactory.cs | 10 +++++ quantities/factories/LinearCreateFactory.cs | 28 ++++++++++++++ .../SiCreateFactory.cs} | 6 +-- quantities/measures/Build.cs | 2 +- quantities/quantities/ElectricPotential.cs | 6 +-- quantities/quantities/Length.cs | 6 +-- quantities/systems/IFactory.cs | 38 ------------------- quantities/systems/LinearSystem.cs | 29 -------------- 11 files changed, 92 insertions(+), 77 deletions(-) create mode 100644 quantities/factories/Factories.cs create mode 100644 quantities/factories/ICompoundFactory.cs create mode 100644 quantities/factories/IFactory.cs create mode 100644 quantities/factories/LinearCreateFactory.cs rename quantities/{systems/SiSystem.cs => factories/SiCreateFactory.cs} (75%) delete mode 100644 quantities/systems/IFactory.cs delete mode 100644 quantities/systems/LinearSystem.cs diff --git a/quantities/dimensions/IDimension.cs b/quantities/dimensions/IDimension.cs index 09b097c8..644c6858 100644 --- a/quantities/dimensions/IDimension.cs +++ b/quantities/dimensions/IDimension.cs @@ -1,5 +1,6 @@ namespace Quantities.Dimensions; +// ToDo: rethink the utility of these dimensions! public interface IDimension { /* marker interface */ } public interface ILinear { /* marker interface */ } diff --git a/quantities/factories/Factories.cs b/quantities/factories/Factories.cs new file mode 100644 index 00000000..637bcb09 --- /dev/null +++ b/quantities/factories/Factories.cs @@ -0,0 +1,33 @@ +using Quantities.Dimensions; +using Quantities.Prefixes; +using Quantities.Units.Imperial; +using Quantities.Units.NonStandard; +using Quantities.Units.Si; + +namespace Quantities.Factories; + +public interface ISiFactory : IFactory + where TDimension : IDimension +{ + public TQuantity Si() where TUnit : ISiUnit, TDimension; + public TQuantity Si() where TPrefix : IMetricPrefix where TUnit : ISiUnit, TDimension; +} + +public interface IMetricFactory : IFactory + where TDimension : IDimension +{ + public TQuantity Metric() where TUnit : IMetricUnit, TDimension; + public TQuantity Metric() where TPrefix : IMetricPrefix where TUnit : IMetricUnit, TDimension; +} + +public interface IImperialFactory + where TDimension : IDimension +{ + public TQuantity Imperial() where TUnit : IImperial, TDimension; +} + +public interface INonStandardFactory + where TDimension : IDimension +{ + public TQuantity NonStandard() where TUnit : INoSystem, TDimension; +} diff --git a/quantities/factories/ICompoundFactory.cs b/quantities/factories/ICompoundFactory.cs new file mode 100644 index 00000000..ea596794 --- /dev/null +++ b/quantities/factories/ICompoundFactory.cs @@ -0,0 +1,10 @@ +using Quantities.Dimensions; + +namespace Quantities.Factories; + +public interface ICompoundFactory + : ISiFactory, IMetricFactory, IImperialFactory, INonStandardFactory + where TDimension : IDimension +{ + +} diff --git a/quantities/factories/IFactory.cs b/quantities/factories/IFactory.cs new file mode 100644 index 00000000..3f456589 --- /dev/null +++ b/quantities/factories/IFactory.cs @@ -0,0 +1,10 @@ +namespace Quantities.Factories; + +public interface IFactory { /* marker interface */ } + +public interface IFactory : IFactory + where TFactory : IFactory +{ + public static abstract TFactory Of(in Double value); +} + diff --git a/quantities/factories/LinearCreateFactory.cs b/quantities/factories/LinearCreateFactory.cs new file mode 100644 index 00000000..1cae5bd1 --- /dev/null +++ b/quantities/factories/LinearCreateFactory.cs @@ -0,0 +1,28 @@ +using Quantities.Dimensions; +using Quantities.Measures; +using Quantities.Prefixes; +using Quantities.Units.Imperial; +using Quantities.Units.NonStandard; +using Quantities.Units.Si; + +namespace Quantities.Factories; + +public readonly struct LinearCreateFactory : ICompoundFactory + where TDimension : Dimensions.IDimension, ILinear + where TQuantity : struct, IQuantity, IQuantityFactory, TDimension +{ + private readonly Double value; + internal LinearCreateFactory(in Double builder) => this.value = builder; + public TQuantity Si() where TUnit : ISiUnit, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity Si() + where TPrefix : IMetricPrefix + where TUnit : ISiUnit, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity Metric() where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity Metric() + where TPrefix : IMetricPrefix + where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); + + public TQuantity Imperial() where TUnit : IImperial, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity NonStandard() where TUnit : INoSystem, TDimension => TQuantity.Create(this.value.As>()); +} + diff --git a/quantities/systems/SiSystem.cs b/quantities/factories/SiCreateFactory.cs similarity index 75% rename from quantities/systems/SiSystem.cs rename to quantities/factories/SiCreateFactory.cs index f64178d2..92f79dbe 100644 --- a/quantities/systems/SiSystem.cs +++ b/quantities/factories/SiCreateFactory.cs @@ -3,14 +3,14 @@ using Quantities.Prefixes; using Quantities.Units.Si; -namespace Quantities.Systems; +namespace Quantities.Factories; -public readonly struct SiSystem : ISiFactory +public readonly struct SiCreateFactory : ISiFactory where TDimension : Dimensions.IDimension, ILinear where TSelf : struct, IQuantity, IQuantityFactory, TDimension { private readonly Double value; - internal SiSystem(in Double value) => this.value = value; + internal SiCreateFactory(in Double value) => this.value = value; public TSelf Si() where TUnit : ISiUnit, TDimension => TSelf.Create(this.value.As>()); public TSelf Si() where TPrefix : IMetricPrefix diff --git a/quantities/measures/Build.cs b/quantities/measures/Build.cs index f2e8c0c5..2394dbaf 100644 --- a/quantities/measures/Build.cs +++ b/quantities/measures/Build.cs @@ -12,7 +12,7 @@ internal static class Build where TMeasure : IMeasure public static Quant With(in Double value) where TInjector : IInjector, new() { - return new(value, in MapPool.Item); + return new(in value, in MapPool.Item); } public static Quant With(in Quant value) { diff --git a/quantities/quantities/ElectricPotential.cs b/quantities/quantities/ElectricPotential.cs index 0d118c6e..38ca1baa 100644 --- a/quantities/quantities/ElectricPotential.cs +++ b/quantities/quantities/ElectricPotential.cs @@ -1,9 +1,9 @@ using System.Numerics; using Quantities.Dimensions; +using Quantities.Factories; using Quantities.Measures; using Quantities.Prefixes; using Quantities.Quantities.Roots; -using Quantities.Systems; using Quantities.Units.Si; using Quantities.Units.Si.Derived; @@ -11,7 +11,7 @@ namespace Quantities.Quantities; public readonly struct ElectricPotential : IQuantity, IElectricPotential , IQuantityFactory - , IFactory> + , IFactory> , IMultiplyOperators , IDivisionOperators , IDivisionOperators @@ -33,7 +33,7 @@ public ElectricPotential To() return new(this.quant.As>()); } static ElectricPotential IQuantityFactory.Create(in Quant quant) => new(in quant); - public static SiSystem Of(in Double value) => new(in value); + public static SiCreateFactory Of(in Double value) => new(in value); public Boolean Equals(ElectricPotential other) => this.quant.Equals(other.quant); public String ToString(String? format, IFormatProvider? provider) => this.quant.ToString(format, provider); diff --git a/quantities/quantities/Length.cs b/quantities/quantities/Length.cs index 83b62da3..6b22530d 100644 --- a/quantities/quantities/Length.cs +++ b/quantities/quantities/Length.cs @@ -1,10 +1,10 @@ using System.Numerics; using Quantities.Dimensions; +using Quantities.Factories; using Quantities.Measures; using Quantities.Measures.Transformations; using Quantities.Prefixes; using Quantities.Quantities.Roots; -using Quantities.Systems; using Quantities.Units.Imperial; using Quantities.Units.Si; @@ -12,7 +12,7 @@ namespace Quantities.Quantities; public readonly struct Length : IQuantity, ILength , IQuantityFactory - , IFactory> + , IFactory> , IMultiplyOperators , IMultiplyOperators , IDivisionOperators @@ -41,7 +41,7 @@ public Length ToImperial() } static Length IQuantityFactory.Create(in Quant quant) => new(in quant); - public static LinearSystem Of(in Double value) => new(in value); + public static LinearCreateFactory Of(in Double value) => new(in value); internal static Length From(in Area area, in Length length) { diff --git a/quantities/systems/IFactory.cs b/quantities/systems/IFactory.cs deleted file mode 100644 index ea0a6cfc..00000000 --- a/quantities/systems/IFactory.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Quantities.Dimensions; -using Quantities.Prefixes; -using Quantities.Units.Imperial; -using Quantities.Units.NonStandard; -using Quantities.Units.Si; - -namespace Quantities.Systems; - -public interface IFactory { /* marker interface */ } - -public interface IFactory : IFactory - where TFactory : IFactory -{ - public static abstract TFactory Of(in Double value); -} -public interface ISiFactory : IFactory - where TDimension : IDimension, ILinear -{ - public TSelf Si() where TUnit : ISiUnit, TDimension; - public TSelf Si() where TPrefix : IMetricPrefix where TUnit : ISiUnit, TDimension; -} - -public interface IMetricFactory : IFactory - where TDimension : IDimension, ILinear -{ - public TSelf Metric() where TUnit : IMetricUnit, TDimension; - public TSelf Metric() where TPrefix : IMetricPrefix where TUnit : IMetricUnit, TDimension; -} - -public interface IImperialFactory -{ - public TSelf Imperial() where TUnit : IImperial, TDimension; -} - -public interface INonStandardFactory -{ - public TSelf NonStandard() where TUnit : INoSystem, TDimension; -} \ No newline at end of file diff --git a/quantities/systems/LinearSystem.cs b/quantities/systems/LinearSystem.cs deleted file mode 100644 index f6262aa9..00000000 --- a/quantities/systems/LinearSystem.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Quantities.Dimensions; -using Quantities.Measures; -using Quantities.Prefixes; -using Quantities.Units.Imperial; -using Quantities.Units.NonStandard; -using Quantities.Units.Si; - -namespace Quantities.Systems; - -public readonly struct LinearSystem - : ISiFactory, IMetricFactory, IImperialFactory, INonStandardFactory - where TDimension : Dimensions.IDimension, ILinear - where TSelf : struct, IQuantity, IQuantityFactory, TDimension -{ - private readonly Double value; - internal LinearSystem(in Double value) => this.value = value; - public TSelf Si() where TUnit : ISiUnit, TDimension => TSelf.Create(this.value.As>()); - public TSelf Si() - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, TDimension => TSelf.Create(this.value.As>()); - public TSelf Metric() where TUnit : IMetricUnit, TDimension => TSelf.Create(this.value.As>()); - public TSelf Metric() - where TPrefix : IMetricPrefix - where TUnit : IMetricUnit, TDimension => TSelf.Create(this.value.As>()); - - public TSelf Imperial() where TUnit : IImperial, TDimension => TSelf.Create(this.value.As>()); - public TSelf NonStandard() where TUnit : INoSystem, TDimension => TSelf.Create(this.value.As>()); -} - From a66562ae307e4b0c22e92ae71990ac9b56daef7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=A4gi?= Date: Mon, 1 May 2023 12:27:35 +0200 Subject: [PATCH 07/30] Use "To" and "Of" factories on Length & El. P. --- quantities.test/LengthTest.cs | 16 ++++---- quantities/IQuantFactory.cs | 8 ++++ quantities/IQuantityFactory.cs | 11 ----- quantities/factories/IFactory.cs | 10 +++-- quantities/factories/LinearCreateFactory.cs | 28 ------------- quantities/factories/LinearFactories.cs | 45 +++++++++++++++++++++ quantities/factories/SiCreateFactory.cs | 18 --------- quantities/factories/SiFactories.cs | 29 +++++++++++++ quantities/quantities/ElectricPotential.cs | 21 +++------- quantities/quantities/Length.cs | 29 +++---------- 10 files changed, 106 insertions(+), 109 deletions(-) create mode 100644 quantities/IQuantFactory.cs delete mode 100644 quantities/IQuantityFactory.cs delete mode 100644 quantities/factories/LinearCreateFactory.cs create mode 100644 quantities/factories/LinearFactories.cs delete mode 100644 quantities/factories/SiCreateFactory.cs create mode 100644 quantities/factories/SiFactories.cs diff --git a/quantities.test/LengthTest.cs b/quantities.test/LengthTest.cs index ee98e54b..a0c70e70 100644 --- a/quantities.test/LengthTest.cs +++ b/quantities.test/LengthTest.cs @@ -11,7 +11,7 @@ public sealed class LengthTest public void MetreToKilometre() { Length metres = Length.Of(1000).Si(); - Length kilometres = metres.To(); + Length kilometres = metres.To.Si(); PrecisionIsBounded(1d, kilometres); } @@ -19,7 +19,7 @@ public void MetreToKilometre() public void MetreToMillimetre() { Length metres = Length.Of(1).Si(); - Length millimetres = metres.To(); + Length millimetres = metres.To.Si(); PrecisionIsBounded(1000d, millimetres); } @@ -27,7 +27,7 @@ public void MetreToMillimetre() public void ÅngströmToNanoMetre() { Length ångström = Length.Of(10).Metric<Ångström>(); - Length nanoMetres = ångström.To(); + Length nanoMetres = ångström.To.Si(); PrecisionIsBounded(1d, nanoMetres); } @@ -35,7 +35,7 @@ public void ÅngströmToNanoMetre() public void MillimetreToKilometre() { Length millimetres = Length.Of(2e6).Si(); - Length kilometres = millimetres.To(); + Length kilometres = millimetres.To.Si(); PrecisionIsBounded(2d, kilometres); } @@ -43,7 +43,7 @@ public void MillimetreToKilometre() public void MileToKilometre() { Length miles = Length.Of(1).Imperial(); - Length kilometres = miles.To(); + Length kilometres = miles.To.Si(); PrecisionIsBounded(1.609344, kilometres); } @@ -51,7 +51,7 @@ public void MileToKilometre() public void KilometreToMile() { Length kilometres = Length.Of(1.609344).Si(); - Length miles = kilometres.ToImperial(); + Length miles = kilometres.To.Imperial(); PrecisionIsBounded(1d, miles); } [Fact] @@ -59,7 +59,7 @@ public void FootToMile() { Length feet = Length.Of(5280).Imperial(); Length expected = Length.Of(1).Imperial(); - Length actual = feet.ToImperial(); + Length actual = feet.To.Imperial(); actual.Matches(expected); } @@ -109,7 +109,7 @@ public void OneMileInYards() Length length = Length.Of(1).Imperial(); Length expected = Length.Of(1760).Imperial(); - Length actual = length.ToImperial(); + Length actual = length.To.Imperial(); actual.Matches(expected); } diff --git a/quantities/IQuantFactory.cs b/quantities/IQuantFactory.cs new file mode 100644 index 00000000..8f74edae --- /dev/null +++ b/quantities/IQuantFactory.cs @@ -0,0 +1,8 @@ +using Quantities.Measures; + +namespace Quantities; + +public interface IQuantFactory +{ + internal static abstract TSelf Create(in Quant quant); +} diff --git a/quantities/IQuantityFactory.cs b/quantities/IQuantityFactory.cs deleted file mode 100644 index 0bbf9d59..00000000 --- a/quantities/IQuantityFactory.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Quantities.Measures; - -namespace Quantities; - -public interface IQuantityFactory - where TDimension : Dimensions.IDimension - where TSelf : struct, IQuantity, TDimension -{ - internal Quant Quant { get; } - internal static abstract TSelf Create(in Quant quant); -} diff --git a/quantities/factories/IFactory.cs b/quantities/factories/IFactory.cs index 3f456589..a96e1b7c 100644 --- a/quantities/factories/IFactory.cs +++ b/quantities/factories/IFactory.cs @@ -2,9 +2,11 @@ namespace Quantities.Factories; public interface IFactory { /* marker interface */ } -public interface IFactory : IFactory +public interface IFactory : IFactory where TFactory : IFactory + where TTo : TFactory + where TCreate : TFactory { - public static abstract TFactory Of(in Double value); -} - + public TTo To { get; } + public static abstract TCreate Of(in Double value); +} \ No newline at end of file diff --git a/quantities/factories/LinearCreateFactory.cs b/quantities/factories/LinearCreateFactory.cs deleted file mode 100644 index 1cae5bd1..00000000 --- a/quantities/factories/LinearCreateFactory.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Quantities.Dimensions; -using Quantities.Measures; -using Quantities.Prefixes; -using Quantities.Units.Imperial; -using Quantities.Units.NonStandard; -using Quantities.Units.Si; - -namespace Quantities.Factories; - -public readonly struct LinearCreateFactory : ICompoundFactory - where TDimension : Dimensions.IDimension, ILinear - where TQuantity : struct, IQuantity, IQuantityFactory, TDimension -{ - private readonly Double value; - internal LinearCreateFactory(in Double builder) => this.value = builder; - public TQuantity Si() where TUnit : ISiUnit, TDimension => TQuantity.Create(this.value.As>()); - public TQuantity Si() - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, TDimension => TQuantity.Create(this.value.As>()); - public TQuantity Metric() where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); - public TQuantity Metric() - where TPrefix : IMetricPrefix - where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); - - public TQuantity Imperial() where TUnit : IImperial, TDimension => TQuantity.Create(this.value.As>()); - public TQuantity NonStandard() where TUnit : INoSystem, TDimension => TQuantity.Create(this.value.As>()); -} - diff --git a/quantities/factories/LinearFactories.cs b/quantities/factories/LinearFactories.cs new file mode 100644 index 00000000..bea3d421 --- /dev/null +++ b/quantities/factories/LinearFactories.cs @@ -0,0 +1,45 @@ +using Quantities.Dimensions; +using Quantities.Measures; +using Quantities.Prefixes; +using Quantities.Units.Imperial; +using Quantities.Units.NonStandard; +using Quantities.Units.Si; + +namespace Quantities.Factories; + +public readonly struct LinearTo : ICompoundFactory + where TDimension : Dimensions.IDimension, ILinear + where TQuantity : IQuantFactory +{ + private readonly Quant value; + internal LinearTo(in Quant value) => this.value = value; + public TQuantity Si() where TUnit : ISiUnit, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity Si() + where TPrefix : IMetricPrefix + where TUnit : ISiUnit, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity Metric() where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity Metric() + where TPrefix : IMetricPrefix + where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); + + public TQuantity Imperial() where TUnit : IImperial, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity NonStandard() where TUnit : INoSystem, TDimension => TQuantity.Create(this.value.As>()); +} +public readonly struct LinearCreate : ICompoundFactory + where TDimension : Dimensions.IDimension, ILinear + where TQuantity : IQuantFactory +{ + private readonly Double value; + internal LinearCreate(in Double value) => this.value = value; + public TQuantity Si() where TUnit : ISiUnit, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity Si() + where TPrefix : IMetricPrefix + where TUnit : ISiUnit, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity Metric() where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity Metric() + where TPrefix : IMetricPrefix + where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); + + public TQuantity Imperial() where TUnit : IImperial, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity NonStandard() where TUnit : INoSystem, TDimension => TQuantity.Create(this.value.As>()); +} diff --git a/quantities/factories/SiCreateFactory.cs b/quantities/factories/SiCreateFactory.cs deleted file mode 100644 index 92f79dbe..00000000 --- a/quantities/factories/SiCreateFactory.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Quantities.Dimensions; -using Quantities.Measures; -using Quantities.Prefixes; -using Quantities.Units.Si; - -namespace Quantities.Factories; - -public readonly struct SiCreateFactory : ISiFactory - where TDimension : Dimensions.IDimension, ILinear - where TSelf : struct, IQuantity, IQuantityFactory, TDimension -{ - private readonly Double value; - internal SiCreateFactory(in Double value) => this.value = value; - public TSelf Si() where TUnit : ISiUnit, TDimension => TSelf.Create(this.value.As>()); - public TSelf Si() - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, TDimension => TSelf.Create(this.value.As>()); -} diff --git a/quantities/factories/SiFactories.cs b/quantities/factories/SiFactories.cs new file mode 100644 index 00000000..ed5985fb --- /dev/null +++ b/quantities/factories/SiFactories.cs @@ -0,0 +1,29 @@ +using Quantities.Dimensions; +using Quantities.Measures; +using Quantities.Prefixes; +using Quantities.Units.Si; + +namespace Quantities.Factories; + +public readonly struct SiTo : ISiFactory + where TDimension : Dimensions.IDimension, ILinear + where TQuantity : IQuantFactory +{ + private readonly Quant value; + internal SiTo(in Quant value) => this.value = value; + public TQuantity Si() where TUnit : ISiUnit, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity Si() + where TPrefix : IMetricPrefix + where TUnit : ISiUnit, TDimension => TQuantity.Create(this.value.As>()); +} +public readonly struct SiCreate : ISiFactory + where TDimension : Dimensions.IDimension, ILinear + where TQuantity : IQuantFactory +{ + private readonly Double value; + internal SiCreate(in Double value) => this.value = value; + public TQuantity Si() where TUnit : ISiUnit, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity Si() + where TPrefix : IMetricPrefix + where TUnit : ISiUnit, TDimension => TQuantity.Create(this.value.As>()); +} diff --git a/quantities/quantities/ElectricPotential.cs b/quantities/quantities/ElectricPotential.cs index 38ca1baa..606519a6 100644 --- a/quantities/quantities/ElectricPotential.cs +++ b/quantities/quantities/ElectricPotential.cs @@ -10,8 +10,8 @@ namespace Quantities.Quantities; public readonly struct ElectricPotential : IQuantity, IElectricPotential - , IQuantityFactory - , IFactory> + , IQuantFactory + , IFactory, SiTo, SiCreate> , IMultiplyOperators , IDivisionOperators , IDivisionOperators @@ -19,21 +19,10 @@ namespace Quantities.Quantities; private static readonly IRoot root = new UnitRoot(); private readonly Quant quant; internal Quant Quant => this.quant; - Quant IQuantityFactory.Quant => this.quant; + public SiTo To => new(in this.quant); private ElectricPotential(in Quant quant) => this.quant = quant; - public ElectricPotential To() - where TUnit : ISiUnit, IElectricPotential - { - return new(this.quant.As>()); - } - public ElectricPotential To() - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, IElectricPotential - { - return new(this.quant.As>()); - } - static ElectricPotential IQuantityFactory.Create(in Quant quant) => new(in quant); - public static SiCreateFactory Of(in Double value) => new(in value); + public static SiCreate Of(in Double value) => new(in value); + static ElectricPotential IQuantFactory.Create(in Quant quant) => new(in quant); public Boolean Equals(ElectricPotential other) => this.quant.Equals(other.quant); public String ToString(String? format, IFormatProvider? provider) => this.quant.ToString(format, provider); diff --git a/quantities/quantities/Length.cs b/quantities/quantities/Length.cs index 6b22530d..38a9e29b 100644 --- a/quantities/quantities/Length.cs +++ b/quantities/quantities/Length.cs @@ -5,14 +5,13 @@ using Quantities.Measures.Transformations; using Quantities.Prefixes; using Quantities.Quantities.Roots; -using Quantities.Units.Imperial; using Quantities.Units.Si; namespace Quantities.Quantities; public readonly struct Length : IQuantity, ILength - , IQuantityFactory - , IFactory> + , IQuantFactory + , IFactory, LinearTo, LinearCreate> , IMultiplyOperators , IMultiplyOperators , IDivisionOperators @@ -21,28 +20,10 @@ namespace Quantities.Quantities; private static readonly ICreate linear = new ToLinear(); private readonly Quant quant; internal Quant Quant => this.quant; - Quant IQuantityFactory.Quant => this.quant; + public LinearTo To => new(in this.quant); private Length(in Quant quant) => this.quant = quant; - public Length To() - where TUnit : ISiUnit, ILength - { - return new(this.quant.As>()); - } - public Length To() - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, ILength - { - return new(this.quant.As>()); - } - public Length ToImperial() - where TUnit : IImperial, ILength - { - return new(this.quant.As>()); - } - static Length IQuantityFactory.Create(in Quant quant) => new(in quant); - - public static LinearCreateFactory Of(in Double value) => new(in value); - + public static LinearCreate Of(in Double value) => new(in value); + static Length IQuantFactory.Create(in Quant quant) => new(in quant); internal static Length From(in Area area, in Length length) { var pseudoArea = area.Quant.Transform(in linear); From 5f2cf2beb1e26126b688375ed695017c461fbbda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=A4gi?= Date: Mon, 1 May 2023 13:03:43 +0200 Subject: [PATCH 08/30] Use new "Of" and "To" members on Force and Mass. --- quantities.test/MassTest.cs | 110 ++++++++++---------- quantities/IFactory.cs | 8 ++ quantities/IQuantFactory.cs | 8 -- quantities/dimensions/CompoundDimensions.cs | 2 +- quantities/factories/LinearFactories.cs | 8 +- quantities/factories/SiFactories.cs | 4 +- quantities/quantities/ElectricPotential.cs | 4 +- quantities/quantities/Force.cs | 77 ++------------ quantities/quantities/Length.cs | 4 +- quantities/quantities/Mass.cs | 66 ++---------- 10 files changed, 86 insertions(+), 205 deletions(-) create mode 100644 quantities/IFactory.cs delete mode 100644 quantities/IQuantFactory.cs diff --git a/quantities.test/MassTest.cs b/quantities.test/MassTest.cs index 4e2ce654..223fa263 100644 --- a/quantities.test/MassTest.cs +++ b/quantities.test/MassTest.cs @@ -7,192 +7,192 @@ namespace Quantities.Test; public sealed class MassTest { private const Double gramsInPound = 453.59237; - private static readonly Mass onePound = Mass.Imperial(1); + private static readonly Mass onePound = Mass.Of(1).Imperial(); [Fact] - public void KilogramToString() => FormattingMatches(v => Mass.Si(v), "kg"); + public void KilogramToString() => FormattingMatches(v => Mass.Of(v).Si(), "kg"); [Fact] - public void GramToString() => FormattingMatches(v => Mass.Metric(v), "g"); + public void GramToString() => FormattingMatches(v => Mass.Of(v).Metric(), "g"); [Fact] - public void TonneToString() => FormattingMatches(v => Mass.Metric(v), "t"); + public void TonneToString() => FormattingMatches(v => Mass.Of(v).Metric(), "t"); [Fact] - public void KiloGramToString() => FormattingMatches(v => Mass.Metric(v), "Kg"); + public void KiloGramToString() => FormattingMatches(v => Mass.Of(v).Metric(), "Kg"); [Fact] - public void MicroGramToString() => FormattingMatches(v => Mass.Metric(v), "μg"); + public void MicroGramToString() => FormattingMatches(v => Mass.Of(v).Metric(), "μg"); [Fact] - public void KiloTonneToString() => FormattingMatches(v => Mass.Metric(v), "Kt"); + public void KiloTonneToString() => FormattingMatches(v => Mass.Of(v).Metric(), "Kt"); [Fact] - public void MegaTonneToString() => FormattingMatches(v => Mass.Metric(v), "Mt"); + public void MegaTonneToString() => FormattingMatches(v => Mass.Of(v).Metric(), "Mt"); [Fact] public void KilogramKiloGramEquivalence() { - Mass siKilogram = Mass.Si(0.3251); - Mass pseudoKiloGram = Mass.Metric(0.3251); + Mass siKilogram = Mass.Of(0.3251).Si(); + Mass pseudoKiloGram = Mass.Of(0.3251).Metric(); Assert.Equal(siKilogram, pseudoKiloGram); } [Fact] public void GramToKilogram() { - Mass mass = Mass.Metric(1600); - Mass expected = Mass.Si(1.6); + Mass mass = Mass.Of(1600).Metric(); + Mass expected = Mass.Of(1.6).Si(); - Mass actual = mass.To(); + Mass actual = mass.To.Si(); actual.Matches(expected); } [Fact] public void KilogramToGram() { - Mass mass = Mass.Si(0.8); - Mass expected = Mass.Metric(800); + Mass mass = Mass.Of(0.8).Si(); + Mass expected = Mass.Of(800).Metric(); - Mass actual = mass.ToMetric(); + Mass actual = mass.To.Metric(); actual.Matches(expected); } [Fact] public void TonneToKilogram() { - Mass mass = Mass.Metric(0.2); - Mass expected = Mass.Si(200); + Mass mass = Mass.Of(0.2).Metric(); + Mass expected = Mass.Of(200).Si(); - Mass actual = mass.To(); + Mass actual = mass.To.Si(); actual.Matches(expected); } [Fact] public void KilogramToTonne() { - Mass mass = Mass.Si(1200); - Mass expected = Mass.Metric(1.2); + Mass mass = Mass.Of(1200).Si(); + Mass expected = Mass.Of(1.2).Metric(); - Mass actual = mass.ToMetric(); + Mass actual = mass.To.Metric(); actual.Matches(expected); } [Fact] public void GramToTonne() { - Mass mass = Mass.Metric(1500); - Mass expected = Mass.Metric(1.5); + Mass mass = Mass.Of(1500).Metric(); + Mass expected = Mass.Of(1.5).Metric(); - Mass actual = mass.ToMetric(); + Mass actual = mass.To.Metric(); actual.Matches(expected); } [Fact] public void TonneToGram() { - Mass mass = Mass.Metric(0.003); - Mass expected = Mass.Metric(3000); + Mass mass = Mass.Of(0.003).Metric(); + Mass expected = Mass.Of(3000).Metric(); - Mass actual = mass.ToMetric(); + Mass actual = mass.To.Metric(); actual.Matches(expected); } [Fact] public void GramToPound() { - Mass mass = Mass.Metric(3d * gramsInPound); - Mass expected = Mass.Imperial(3); + Mass mass = Mass.Of(3d * gramsInPound).Metric(); + Mass expected = Mass.Of(3).Imperial(); - Mass actual = mass.ToImperial(); + Mass actual = mass.To.Imperial(); actual.Matches(expected, MediumPrecision); } [Fact] public void PoundToGram() { - Mass mass = Mass.Imperial(2); - Mass expected = Mass.Metric(2d * gramsInPound); + Mass mass = Mass.Of(2).Imperial(); + Mass expected = Mass.Of(2d * gramsInPound).Metric(); - Mass actual = mass.ToMetric(); + Mass actual = mass.To.Metric(); actual.Matches(expected); } [Fact] public void PoundToStone() { - Mass mass = Mass.Imperial(28); - Mass expected = Mass.Imperial(2); + Mass mass = Mass.Of(28).Imperial(); + Mass expected = Mass.Of(2).Imperial(); - Mass actual = mass.ToImperial(); + Mass actual = mass.To.Imperial(); actual.Matches(expected); } [Fact] public void StoneToPound() { - Mass mass = Mass.Imperial(0.5); - Mass expected = Mass.Imperial(7); + Mass mass = Mass.Of(0.5).Imperial(); + Mass expected = Mass.Of(7).Imperial(); - Mass actual = mass.ToImperial(); + Mass actual = mass.To.Imperial(); actual.Matches(expected); } [Fact] public void PoundToOunce() { - Mass mass = Mass.Imperial(4); - Mass expected = Mass.Imperial(64); + Mass mass = Mass.Of(4).Imperial(); + Mass expected = Mass.Of(64).Imperial(); - Mass actual = mass.ToImperial(); + Mass actual = mass.To.Imperial(); actual.Matches(expected); } [Fact] public void OunceToPound() { - Mass mass = Mass.Imperial(4); - Mass expected = Mass.Imperial(0.25); + Mass mass = Mass.Of(4).Imperial(); + Mass expected = Mass.Of(0.25).Imperial(); - Mass actual = mass.ToImperial(); + Mass actual = mass.To.Imperial(); actual.Matches(expected); } [Fact] public void DefinitionOfGrainHolds() { - Assert.Equal(onePound, Mass.Imperial(7000)); + Assert.Equal(onePound, Mass.Of(7000).Imperial()); } [Fact] public void DefinitionOfDrachmHolds() { - Assert.Equal(onePound, Mass.Imperial(256)); + Assert.Equal(onePound, Mass.Of(256).Imperial()); } [Fact] public void DefinitionOfOunceHolds() { - Assert.Equal(onePound, Mass.Imperial(16)); + Assert.Equal(onePound, Mass.Of(16).Imperial()); } [Fact] public void DefinitionOfPoundHolds() { - Assert.Equal(Mass.Si(1), Mass.Imperial(1000d / gramsInPound)); + Assert.Equal(Mass.Of(1).Si(), Mass.Of(1000d / gramsInPound).Imperial()); } [Fact] public void DefinitionOfStoneHolds() { - Assert.Equal(Mass.Imperial(14), Mass.Imperial(1)); + Assert.Equal(Mass.Of(14).Imperial(), Mass.Of(1).Imperial()); } [Fact] public void DefinitionOfQuarterHolds() { - Assert.Equal(Mass.Imperial(28), Mass.Imperial(1)); + Assert.Equal(Mass.Of(28).Imperial(), Mass.Of(1).Imperial()); } [Fact] public void DefinitionOfHundredweightHolds() { - Assert.Equal(Mass.Imperial(112), Mass.Imperial(1)); + Assert.Equal(Mass.Of(112).Imperial(), Mass.Of(1).Imperial()); } [Fact] public void DefinitionOfTonHolds() { - Assert.Equal(Mass.Imperial(2240), Mass.Imperial(1)); + Assert.Equal(Mass.Of(2240).Imperial(), Mass.Of(1).Imperial()); } [Fact] public void DefinitionOfSlugHolds() { - Assert.Equal(Mass.Si(14.59390294), Mass.Imperial(1)); + Assert.Equal(Mass.Of(14.59390294).Si(), Mass.Of(1).Imperial()); } } diff --git a/quantities/IFactory.cs b/quantities/IFactory.cs new file mode 100644 index 00000000..993895f5 --- /dev/null +++ b/quantities/IFactory.cs @@ -0,0 +1,8 @@ +using Quantities.Measures; + +namespace Quantities; + +public interface IFactory +{ + internal static abstract TResult Create(in Quant quant); +} diff --git a/quantities/IQuantFactory.cs b/quantities/IQuantFactory.cs deleted file mode 100644 index 8f74edae..00000000 --- a/quantities/IQuantFactory.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Quantities.Measures; - -namespace Quantities; - -public interface IQuantFactory -{ - internal static abstract TSelf Create(in Quant quant); -} diff --git a/quantities/dimensions/CompoundDimensions.cs b/quantities/dimensions/CompoundDimensions.cs index d8c9a439..658e6ce1 100644 --- a/quantities/dimensions/CompoundDimensions.cs +++ b/quantities/dimensions/CompoundDimensions.cs @@ -11,7 +11,7 @@ public interface IVelocity : IPer, IVelo where TLength : ILength where TTime : ITime { /* marker interface */ } -public interface IForce : IDimension { /* marker interface */ } +public interface IForce : IDimension, ILinear { /* marker interface */ } public interface IForce : IPer, ISquare>, IForce where TMass : IMass where TLength : ILength diff --git a/quantities/factories/LinearFactories.cs b/quantities/factories/LinearFactories.cs index bea3d421..f6b117e6 100644 --- a/quantities/factories/LinearFactories.cs +++ b/quantities/factories/LinearFactories.cs @@ -9,7 +9,7 @@ namespace Quantities.Factories; public readonly struct LinearTo : ICompoundFactory where TDimension : Dimensions.IDimension, ILinear - where TQuantity : IQuantFactory + where TQuantity : IFactory { private readonly Quant value; internal LinearTo(in Quant value) => this.value = value; @@ -20,14 +20,14 @@ public TQuantity Si() public TQuantity Metric() where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); public TQuantity Metric() where TPrefix : IMetricPrefix - where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); + where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); public TQuantity Imperial() where TUnit : IImperial, TDimension => TQuantity.Create(this.value.As>()); public TQuantity NonStandard() where TUnit : INoSystem, TDimension => TQuantity.Create(this.value.As>()); } public readonly struct LinearCreate : ICompoundFactory where TDimension : Dimensions.IDimension, ILinear - where TQuantity : IQuantFactory + where TQuantity : IFactory { private readonly Double value; internal LinearCreate(in Double value) => this.value = value; @@ -38,7 +38,7 @@ public TQuantity Si() public TQuantity Metric() where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); public TQuantity Metric() where TPrefix : IMetricPrefix - where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); + where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); public TQuantity Imperial() where TUnit : IImperial, TDimension => TQuantity.Create(this.value.As>()); public TQuantity NonStandard() where TUnit : INoSystem, TDimension => TQuantity.Create(this.value.As>()); diff --git a/quantities/factories/SiFactories.cs b/quantities/factories/SiFactories.cs index ed5985fb..fc53d181 100644 --- a/quantities/factories/SiFactories.cs +++ b/quantities/factories/SiFactories.cs @@ -7,7 +7,7 @@ namespace Quantities.Factories; public readonly struct SiTo : ISiFactory where TDimension : Dimensions.IDimension, ILinear - where TQuantity : IQuantFactory + where TQuantity : IFactory { private readonly Quant value; internal SiTo(in Quant value) => this.value = value; @@ -18,7 +18,7 @@ public TQuantity Si() } public readonly struct SiCreate : ISiFactory where TDimension : Dimensions.IDimension, ILinear - where TQuantity : IQuantFactory + where TQuantity : IFactory { private readonly Double value; internal SiCreate(in Double value) => this.value = value; diff --git a/quantities/quantities/ElectricPotential.cs b/quantities/quantities/ElectricPotential.cs index 606519a6..44be672e 100644 --- a/quantities/quantities/ElectricPotential.cs +++ b/quantities/quantities/ElectricPotential.cs @@ -10,7 +10,7 @@ namespace Quantities.Quantities; public readonly struct ElectricPotential : IQuantity, IElectricPotential - , IQuantFactory + , IFactory , IFactory, SiTo, SiCreate> , IMultiplyOperators , IDivisionOperators @@ -22,7 +22,7 @@ namespace Quantities.Quantities; public SiTo To => new(in this.quant); private ElectricPotential(in Quant quant) => this.quant = quant; public static SiCreate Of(in Double value) => new(in value); - static ElectricPotential IQuantFactory.Create(in Quant quant) => new(in quant); + static ElectricPotential IFactory.Create(in Quant quant) => new(in quant); public Boolean Equals(ElectricPotential other) => this.quant.Equals(other.quant); public String ToString(String? format, IFormatProvider? provider) => this.quant.ToString(format, provider); diff --git a/quantities/quantities/Force.cs b/quantities/quantities/Force.cs index fc36d274..18f89a4e 100644 --- a/quantities/quantities/Force.cs +++ b/quantities/quantities/Force.cs @@ -1,90 +1,25 @@ using System.Numerics; using Quantities.Dimensions; +using Quantities.Factories; using Quantities.Measures; using Quantities.Prefixes; using Quantities.Quantities.Roots; -using Quantities.Units.Imperial; -using Quantities.Units.NonStandard; -using Quantities.Units.Si; using Quantities.Units.Si.Derived; namespace Quantities.Quantities; public readonly struct Force : IQuantity, IForce - , ISi - , IImperial - , IMetric - , INoSystem + , IFactory + , IFactory, LinearTo, LinearCreate> , IMultiplyOperators { private static readonly IRoot root = new UnitRoot(); private readonly Quant quant; internal Quant Quant => this.quant; + public LinearTo To => new(in this.quant); private Force(in Quant quant) => this.quant = quant; - public Force To() - where TUnit : ISiUnit, IForce - { - return new(this.quant.As>()); - } - public Force To() - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, IForce - { - return new(this.quant.As>()); - } - public Force ToMetric() where TUnit : IMetricUnit, IForce - { - return new(this.quant.As>()); - } - public Force ToMetric() - where TPrefix : IMetricPrefix - where TUnit : IMetricUnit, IForce - { - return new(this.quant.As>()); - } - public Force ToImperial() - where TUnit : IImperial, IForce - { - return new(this.quant.As>()); - } - public Force ToNonStandard() - where TUnit : INoSystem, IForce - { - return new(this.quant.As>()); - } - public static Force Si(in Double value) - where TUnit : ISiUnit, IForce - { - return new(value.As>()); - } - public static Force Si(in Double value) - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, IForce - { - return new(value.As>()); - } - public static Force Metric(in Double value) where TUnit : IMetricUnit, IForce - { - return new(value.As>()); - } - - public static Force Metric(in Double value) - where TPrefix : IMetricPrefix - where TUnit : IMetricUnit, IForce - { - return new(value.As>()); - } - public static Force Imperial(in Double value) - where TUnit : IImperial, IForce - { - return new(value.As>()); - } - public static Force NonStandard(in Double value) - where TUnit : INoSystem, IForce - { - return new(value.As>()); - } - + public static LinearCreate Of(in Double value) => new(in value); + static Force IFactory.Create(in Quant quant) => new(in quant); internal static Force From(in Power power, in Velocity velocity) { return new(MetricPrefix.ScaleThree(power.Quant.SiDivide(velocity.Quant), root)); diff --git a/quantities/quantities/Length.cs b/quantities/quantities/Length.cs index 38a9e29b..1bb1f455 100644 --- a/quantities/quantities/Length.cs +++ b/quantities/quantities/Length.cs @@ -10,7 +10,7 @@ namespace Quantities.Quantities; public readonly struct Length : IQuantity, ILength - , IQuantFactory + , IFactory , IFactory, LinearTo, LinearCreate> , IMultiplyOperators , IMultiplyOperators @@ -23,7 +23,7 @@ namespace Quantities.Quantities; public LinearTo To => new(in this.quant); private Length(in Quant quant) => this.quant = quant; public static LinearCreate Of(in Double value) => new(in value); - static Length IQuantFactory.Create(in Quant quant) => new(in quant); + static Length IFactory.Create(in Quant quant) => new(in quant); internal static Length From(in Area area, in Length length) { var pseudoArea = area.Quant.Transform(in linear); diff --git a/quantities/quantities/Mass.cs b/quantities/quantities/Mass.cs index 0a693693..93caf523 100644 --- a/quantities/quantities/Mass.cs +++ b/quantities/quantities/Mass.cs @@ -1,75 +1,21 @@ using Quantities.Dimensions; +using Quantities.Factories; using Quantities.Measures; -using Quantities.Prefixes; -using Quantities.Units.Imperial; -using Quantities.Units.Si; namespace Quantities.Quantities; public readonly struct Mass : IQuantity, IMass - , ISi - , IMetric - , IImperial + , IFactory + , IFactory, LinearTo, LinearCreate> { private readonly Quant quant; + public LinearTo To => new(in this.quant); private Mass(in Quant quant) => this.quant = quant; - public Mass To() - where TUnit : ISiUnit, IMass - { - return new(this.quant.As>()); - } - public Mass To() - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, IMass - { - return new(this.quant.As>()); - } - public Mass ToMetric() where TUnit : IMetricUnit, IMass - { - return new(this.quant.As>()); - } - public Mass ToMetric() - where TPrefix : IMetricPrefix - where TUnit : IMetricUnit, IMass - { - return new(this.quant.As>()); - } - public Mass ToImperial() - where TUnit : IImperial, IMass - { - return new(this.quant.As>()); - } - public static Mass Si(in Double value) - where TUnit : ISiUnit, IMass - { - return new(value.As>()); - } - public static Mass Si(in Double value) - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, IMass - { - return new(value.As>()); - } - public static Mass Metric(in Double value) where TUnit : IMetricUnit, IMass - { - return new(value.As>()); - } - public static Mass Metric(in Double value) - where TPrefix : IMetricPrefix - where TUnit : IMetricUnit, IMass - { - return new(value.As>()); - } - public static Mass Imperial(in Double value) - where TUnit : IImperial, IMass - { - return new(value.As>()); - } + public static LinearCreate Of(in Double value) => new(in value); + static Mass IFactory.Create(in Quant quant) => new(in quant); public Boolean Equals(Mass other) => this.quant.Equals(other.quant); - public override Boolean Equals(Object? obj) => obj is Mass mass && Equals(mass); - public override Int32 GetHashCode() => this.quant.GetHashCode(); public override String ToString() => this.quant.ToString(); public String ToString(String? format, IFormatProvider? provider) => this.quant.ToString(format, provider); From 597fdd42158621a4670034101da17c6ddadedfc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=A4gi?= Date: Mon, 1 May 2023 13:29:48 +0200 Subject: [PATCH 09/30] Use "Of" and "To" members on temperature. --- quantities.test/TemperatureTest.cs | 166 ++++++++++++++------------- quantities/quantities/Temperature.cs | 63 +--------- 2 files changed, 90 insertions(+), 139 deletions(-) diff --git a/quantities.test/TemperatureTest.cs b/quantities.test/TemperatureTest.cs index c440e445..b4d97ac9 100644 --- a/quantities.test/TemperatureTest.cs +++ b/quantities.test/TemperatureTest.cs @@ -1,5 +1,7 @@ using Quantities.Units.Imperial.Temperature; using Quantities.Units.NonStandard.Temperature; +using Quantities.Units.Si.Derived; +using Newton = Quantities.Units.NonStandard.Temperature.Newton; namespace Quantities.Test; @@ -7,30 +9,30 @@ namespace Quantities.Test; public sealed class TemperatureTest { [Fact] - public void KelvinToString() => FormattingMatches(v => Temperature.Si(v), "K"); + public void KelvinToString() => FormattingMatches(v => Temperature.Of(v).Si(), "K"); [Fact] - public void CelsiusToString() => FormattingMatches(v => Temperature.Celsius(v), "°C"); + public void CelsiusToString() => FormattingMatches(v => Temperature.Of(v).Metric(), "°C"); [Fact] - public void DelisleToString() => FormattingMatches(v => Temperature.NonStandard(v), "°De"); + public void DelisleToString() => FormattingMatches(v => Temperature.Of(v).NonStandard(), "°De"); [Fact] - public void NewtonToString() => FormattingMatches(v => Temperature.NonStandard(v), "°N"); + public void NewtonToString() => FormattingMatches(v => Temperature.Of(v).NonStandard(), "°N"); [Fact] - public void RéaumurToString() => FormattingMatches(v => Temperature.NonStandard(v), "°Ré"); + public void RéaumurToString() => FormattingMatches(v => Temperature.Of(v).NonStandard(), "°Ré"); [Fact] - public void RømerToString() => FormattingMatches(v => Temperature.NonStandard(v), "°Rø"); + public void RømerToString() => FormattingMatches(v => Temperature.Of(v).NonStandard(), "°Rø"); [Fact] - public void FahrenheitToString() => FormattingMatches(v => Temperature.Imperial(v), "°F"); + public void FahrenheitToString() => FormattingMatches(v => Temperature.Of(v).Imperial(), "°F"); [Fact] - public void RankineToString() => FormattingMatches(v => Temperature.Imperial(v), "°R"); + public void RankineToString() => FormattingMatches(v => Temperature.Of(v).Imperial(), "°R"); [Fact] - public void GasMarkToString() => FormattingMatches(v => Temperature.Imperial(v), "GM"); + public void GasMarkToString() => FormattingMatches(v => Temperature.Of(v).Imperial(), "GM"); [Fact] public void AddThreeTemperatures() { - Temperature a = Temperature.Celsius(-40); - Temperature b = Temperature.Imperial(-40); - Temperature c = Temperature.Si(363.15); - Temperature expected = Temperature.Celsius(10); + Temperature a = Temperature.Of(-40).Metric(); + Temperature b = Temperature.Of(-40).Imperial(); + Temperature c = Temperature.Of(363.15).Si(); + Temperature expected = Temperature.Of(10).Metric(); Temperature actual = a + b + c; @@ -39,9 +41,9 @@ public void AddThreeTemperatures() [Fact] public void SubtractTemperatures() { - Temperature a = Temperature.Celsius(70); - Temperature b = Temperature.Si(273.15 + 28); - Temperature expected = Temperature.Celsius(42); + Temperature a = Temperature.Of(70).Metric(); + Temperature b = Temperature.Of(273.15 + 28).Si(); + Temperature expected = Temperature.Of(42).Metric(); Temperature actual = a - b; @@ -51,70 +53,70 @@ public void SubtractTemperatures() [Fact] public void KelvinToCelsius() { - Temperature temperature = Temperature.Si(36 + 273.15); - Temperature expected = Temperature.Celsius(36); + Temperature temperature = Temperature.Of(36 + 273.15).Si(); + Temperature expected = Temperature.Of(36).Metric(); - Temperature actual = temperature.ToCelsius(); + Temperature actual = temperature.To.Metric(); actual.Matches(expected); } [Fact] public void KelvinToFahrenheit() { - Temperature temperature = Temperature.Si(364); - Temperature expected = Temperature.Imperial(195.53); + Temperature temperature = Temperature.Of(364).Si(); + Temperature expected = Temperature.Of(195.53).Imperial(); - Temperature actual = temperature.ToImperial(); + Temperature actual = temperature.To.Imperial(); actual.Matches(expected); } [Fact] public void CelsiusToKelvin() { - Temperature temperature = Temperature.Celsius(312 - 273.15); - Temperature expected = Temperature.Si(312); + Temperature temperature = Temperature.Of(312 - 273.15).Metric(); + Temperature expected = Temperature.Of(312).Si(); - Temperature actual = temperature.To(); + Temperature actual = temperature.To.Si(); actual.Matches(expected); } [Fact] public void CelsiusToMilliKelvin() { - Temperature temperature = Temperature.Celsius(-273.13534324); - Temperature expected = Temperature.Si(14.65676); + Temperature temperature = Temperature.Of(-273.13534324).Metric(); + Temperature expected = Temperature.Of(14.65676).Si(); - Temperature actual = temperature.To(); + Temperature actual = temperature.To.Si(); actual.Matches(expected); } [Fact] public void CelsiusToFahrenheit() { - Temperature temperature = Temperature.Celsius(37.0); - Temperature expected = Temperature.Imperial(98.6); + Temperature temperature = Temperature.Of(37.0).Metric(); + Temperature expected = Temperature.Of(98.6).Imperial(); - Temperature actual = temperature.ToImperial(); + Temperature actual = temperature.To.Imperial(); actual.Matches(expected); } [Fact] public void FahrenheitToKelvin() { - Temperature temperature = Temperature.Imperial(-40); - Temperature expected = Temperature.Si(233.15); + Temperature temperature = Temperature.Of(-40).Imperial(); + Temperature expected = Temperature.Of(233.15).Si(); - Temperature actual = temperature.To(); + Temperature actual = temperature.To.Si(); actual.Matches(expected); } [Fact] public void CelsiusToGasMark() { - Temperature temperature = Temperature.Celsius(218d + (1d / 3d)); - Temperature expected = Temperature.Imperial(7); + Temperature temperature = Temperature.Of(218d + (1d / 3d)).Metric(); + Temperature expected = Temperature.Of(7).Imperial(); - Temperature actual = temperature.ToImperial(); + Temperature actual = temperature.To.Imperial(); actual.Matches(expected, VeryLowPrecision); } @@ -122,150 +124,150 @@ public void CelsiusToGasMark() [Fact] public void FahrenheitToGasMark() { - Temperature temperature = Temperature.Imperial(350); - Temperature expected = Temperature.Imperial(4); + Temperature temperature = Temperature.Of(350).Imperial(); + Temperature expected = Temperature.Of(4).Imperial(); - Temperature actual = temperature.ToImperial(); + Temperature actual = temperature.To.Imperial(); actual.Matches(expected, VeryLowPrecision); } [Fact] public void GasMarkToFahrenheit() { - Temperature temperature = Temperature.Imperial(1); - Temperature expected = Temperature.Imperial(275); + Temperature temperature = Temperature.Of(1).Imperial(); + Temperature expected = Temperature.Of(275).Imperial(); - Temperature actual = temperature.ToImperial(); + Temperature actual = temperature.To.Imperial(); actual.Matches(expected); } [Fact] public void GasMarkToKelvin() { - Temperature temperature = Temperature.Imperial(1); - Temperature expected = Temperature.Si(408.15); + Temperature temperature = Temperature.Of(1).Imperial(); + Temperature expected = Temperature.Of(408.15).Si(); - Temperature actual = temperature.To(); + Temperature actual = temperature.To.Si(); actual.Matches(expected); } [Fact] public void KelvinToGasMark() { - Temperature temperature = Temperature.Si(475); - Temperature expected = Temperature.Imperial(5.8132); + Temperature temperature = Temperature.Of(475).Si(); + Temperature expected = Temperature.Of(5.8132).Imperial(); - Temperature actual = temperature.ToImperial(); + Temperature actual = temperature.To.Imperial(); actual.Matches(expected); } [Fact] public void KelvinToRankine() { - Temperature temperature = Temperature.Si(255.37); - Temperature expected = Temperature.Imperial(459.666); + Temperature temperature = Temperature.Of(255.37).Si(); + Temperature expected = Temperature.Of(459.666).Imperial(); - Temperature actual = temperature.ToImperial(); + Temperature actual = temperature.To.Imperial(); actual.Matches(expected); } [Fact] public void RankineToKelvin() { - Temperature temperature = Temperature.Imperial(671.64102); - Temperature expected = Temperature.Si(373.1339); + Temperature temperature = Temperature.Of(671.64102).Imperial(); + Temperature expected = Temperature.Of(373.1339).Si(); - Temperature actual = temperature.To(); + Temperature actual = temperature.To.Si(); actual.Matches(expected); } [Fact] public void FahrenheitToRankine() { - Temperature temperature = Temperature.Imperial(32); - Temperature expected = Temperature.Imperial(491.67); + Temperature temperature = Temperature.Of(32).Imperial(); + Temperature expected = Temperature.Of(491.67).Imperial(); - Temperature actual = temperature.ToImperial(); + Temperature actual = temperature.To.Imperial(); actual.Matches(expected); } [Fact] public void KelvinToDelisle() { - Temperature temperature = Temperature.Si(273.16); - Temperature expected = Temperature.NonStandard(149.985); + Temperature temperature = Temperature.Of(273.16).Si(); + Temperature expected = Temperature.Of(149.985).NonStandard(); - Temperature actual = temperature.ToNonStandard(); + Temperature actual = temperature.To.NonStandard(); actual.Matches(expected); } [Fact] public void DelisleToKelvin() { - Temperature temperature = Temperature.NonStandard(176.67); - Temperature expected = Temperature.Si(255.37); + Temperature temperature = Temperature.Of(176.67).NonStandard(); + Temperature expected = Temperature.Of(255.37).Si(); - Temperature actual = temperature.To(); + Temperature actual = temperature.To.Si(); actual.Matches(expected); } [Fact] public void KelvinToNewton() { - Temperature temperature = Temperature.Si(373.15); - Temperature expected = Temperature.NonStandard(33); + Temperature temperature = Temperature.Of(373.15).Si(); + Temperature expected = Temperature.Of(33).NonStandard(); - Temperature actual = temperature.ToNonStandard(); + Temperature actual = temperature.To.NonStandard(); actual.Matches(expected); } [Fact] public void NewtonToKelvin() { - Temperature temperature = Temperature.NonStandard(0); - Temperature expected = Temperature.Si(273.15); + Temperature temperature = Temperature.Of(0).NonStandard(); + Temperature expected = Temperature.Of(273.15).Si(); - Temperature actual = temperature.To(); + Temperature actual = temperature.To.Si(); actual.Matches(expected); } [Fact] public void KelvinToRéaumur() { - Temperature temperature = Temperature.Si(1941); - Temperature expected = Temperature.NonStandard(1334.28); + Temperature temperature = Temperature.Of(1941).Si(); + Temperature expected = Temperature.Of(1334.28).NonStandard(); - Temperature actual = temperature.ToNonStandard(); + Temperature actual = temperature.To.NonStandard(); actual.Matches(expected); } [Fact] public void RéaumurToKelvin() { - Temperature temperature = Temperature.NonStandard(-14.22); - Temperature expected = Temperature.Si(255.375); + Temperature temperature = Temperature.Of(-14.22).NonStandard(); + Temperature expected = Temperature.Of(255.375).Si(); - Temperature actual = temperature.To(); + Temperature actual = temperature.To.Si(); actual.Matches(expected); } [Fact] public void KelvinToRømer() { - Temperature temperature = Temperature.Si(255.37); - Temperature expected = Temperature.NonStandard(-1.8345); + Temperature temperature = Temperature.Of(255.37).Si(); + Temperature expected = Temperature.Of(-1.8345).NonStandard(); - Temperature actual = temperature.ToNonStandard(); + Temperature actual = temperature.To.NonStandard(); actual.Matches(expected); } [Fact] public void RømerToKelvin() { - Temperature temperature = Temperature.NonStandard(7.50525); - Temperature expected = Temperature.Si(273.16); + Temperature temperature = Temperature.Of(7.50525).NonStandard(); + Temperature expected = Temperature.Of(273.16).Si(); - Temperature actual = temperature.To(); + Temperature actual = temperature.To.Si(); actual.Matches(expected); } diff --git a/quantities/quantities/Temperature.cs b/quantities/quantities/Temperature.cs index 7397b9d7..d8c3ab8c 100644 --- a/quantities/quantities/Temperature.cs +++ b/quantities/quantities/Temperature.cs @@ -1,73 +1,22 @@ using Quantities.Dimensions; +using Quantities.Factories; using Quantities.Measures; -using Quantities.Prefixes; -using Quantities.Units.Imperial; -using Quantities.Units.NonStandard; -using Quantities.Units.Si; -using Quantities.Units.Si.Derived; namespace Quantities.Quantities; public readonly struct Temperature : IQuantity, ITemperature - , ISi - , IImperial - , INoSystem + , IFactory + , IFactory, LinearTo, LinearCreate> { private readonly Quant quant; internal Quant Quant => this.quant; + public LinearTo To => new(in this.quant); private Temperature(in Quant quant) => this.quant = quant; - public Temperature To() - where TUnit : ISiUnit, ITemperature - { - return new(this.quant.As>()); - } - public Temperature To() - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, ITemperature - { - return new(this.quant.As>()); - } - public Temperature ToCelsius() => new(this.quant.As>()); - public Temperature ToImperial() - where TUnit : IImperial, ITemperature - { - return new(this.quant.As>()); - } - public Temperature ToNonStandard() - where TUnit : INoSystem, ITemperature - { - return new(this.quant.As>()); - } - public static Temperature Si(in Double value) - where TUnit : ISiUnit, ITemperature - { - return new(value.As>()); - } - public static Temperature Si(in Double value) - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, ITemperature - { - return new(value.As>()); - } - public static Temperature Celsius(in Double value) - { - return new(value.As>()); - } - public static Temperature Imperial(in Double value) - where TUnit : IImperial, ITemperature - { - return new(value.As>()); - } - public static Temperature NonStandard(in Double value) - where TUnit : INoSystem, ITemperature - { - return new(value.As>()); - } + public static LinearCreate Of(in Double value) => new(in value); + static Temperature IFactory.Create(in Quant quant) => new(in quant); public Boolean Equals(Temperature other) => this.quant.Equals(other.quant); - public override Boolean Equals(Object? obj) => obj is Temperature temperature && Equals(temperature); - public override Int32 GetHashCode() => this.quant.GetHashCode(); public override String ToString() => this.quant.ToString(); public String ToString(String? format, IFormatProvider? provider) => this.quant.ToString(format, provider); From f8150c7e885fd0cf4d78d8350d4c699c7091a0a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=A4gi?= Date: Mon, 1 May 2023 16:18:54 +0200 Subject: [PATCH 10/30] Use "Of" and "To" on Area, also fix IImperial{Unit} --- quantities.benchmark/DividingQuantities.cs | 30 +++---- quantities.test/AreaTest.cs | 58 ++++++------ quantities.test/LengthTest.cs | 6 +- quantities.test/VolumeTest.cs | 4 +- quantities/IImperial.cs | 4 +- quantities/INoSystem.cs | 4 +- quantities/factories/Factories.cs | 4 +- quantities/factories/IPowerCreate.cs | 12 +++ quantities/factories/IPowerFactory.cs | 28 ++++++ quantities/factories/LinearFactories.cs | 8 +- quantities/factories/PowerFactory.cs | 29 ++++++ quantities/factories/SquareCreate.cs | 21 +++++ quantities/factories/SquareFactory.cs | 38 ++++++++ quantities/measures/IMeasure.cs | 4 +- quantities/measures/Measures.cs | 4 +- quantities/quantities/Area.cs | 90 ++----------------- quantities/quantities/Energy.cs | 4 +- quantities/quantities/Power.cs | 4 +- quantities/quantities/Velocity.cs | 4 +- quantities/quantities/Volume.cs | 8 +- quantities/units/IInjectUnit.cs | 4 +- quantities/units/Imperial/Area/Acre.cs | 2 +- quantities/units/Imperial/Area/Perch.cs | 2 +- quantities/units/Imperial/Area/Rood.cs | 2 +- quantities/units/Imperial/IImperial.cs | 3 - quantities/units/Imperial/IImperialUnit.cs | 3 + quantities/units/Imperial/Length/Chain.cs | 2 +- quantities/units/Imperial/Length/Foot.cs | 2 +- quantities/units/Imperial/Length/Furlong.cs | 2 +- quantities/units/Imperial/Length/Inch.cs | 2 +- quantities/units/Imperial/Length/Mile.cs | 2 +- quantities/units/Imperial/Length/Yard.cs | 2 +- quantities/units/Imperial/Mass/Drachm.cs | 2 +- quantities/units/Imperial/Mass/Grain.cs | 2 +- .../units/Imperial/Mass/Hundredweight.cs | 2 +- quantities/units/Imperial/Mass/Ounce.cs | 2 +- quantities/units/Imperial/Mass/Pound.cs | 2 +- quantities/units/Imperial/Mass/Quarter.cs | 2 +- quantities/units/Imperial/Mass/Slug.cs | 2 +- quantities/units/Imperial/Mass/Stone.cs | 2 +- quantities/units/Imperial/Mass/Ton.cs | 2 +- quantities/units/Imperial/Power/HorsePower.cs | 2 +- .../units/Imperial/Temperature/Farenheit.cs | 2 +- .../units/Imperial/Temperature/GasMark.cs | 2 +- .../units/Imperial/Temperature/Rankine.cs | 2 +- .../units/Imperial/Volume/FluidOunce.cs | 2 +- quantities/units/Imperial/Volume/Gallon.cs | 2 +- quantities/units/Imperial/Volume/Gill.cs | 2 +- quantities/units/Imperial/Volume/Pint.cs | 2 +- quantities/units/Imperial/Volume/Quart.cs | 2 +- quantities/units/NonStandard/Area/Morgen.cs | 2 +- .../{INoSystem.cs => INoSystemUnit.cs} | 2 +- .../units/NonStandard/Temperature/Delisle.cs | 2 +- .../units/NonStandard/Temperature/Newton.cs | 2 +- .../Temperature/R\303\251aumur.cs" | 2 +- .../NonStandard/Temperature/R\303\270mer.cs" | 2 +- 56 files changed, 247 insertions(+), 193 deletions(-) create mode 100644 quantities/factories/IPowerCreate.cs create mode 100644 quantities/factories/IPowerFactory.cs create mode 100644 quantities/factories/PowerFactory.cs create mode 100644 quantities/factories/SquareCreate.cs create mode 100644 quantities/factories/SquareFactory.cs delete mode 100644 quantities/units/Imperial/IImperial.cs create mode 100644 quantities/units/Imperial/IImperialUnit.cs rename quantities/units/NonStandard/{INoSystem.cs => INoSystemUnit.cs} (68%) diff --git a/quantities.benchmark/DividingQuantities.cs b/quantities.benchmark/DividingQuantities.cs index dec710b4..7fae079c 100644 --- a/quantities.benchmark/DividingQuantities.cs +++ b/quantities.benchmark/DividingQuantities.cs @@ -16,10 +16,10 @@ public class DividingQuantities { private Volume metricVolume = Volume.Cubic(3); private Volume metricAcceptedVolume = Volume.Metric(3); - private Area metricArea = Area.Square(23); - private Area imperialPureArea = Area.Imperial(23); + private Area metricArea = Area.Of(23).Square.Si(); + private Area imperialPureArea = Area.Of(23).Imperial(); private Volume imperialVolume = Volume.CubicImperial(-3); - private Area imperialArea = Area.SquareImperial(55); + private Area imperialArea = Area.Of(55).Square.Imperial(); private ElectricPotential potential = ElectricPotential.Of(33).Si(); private ElectricCurrent current = ElectricCurrent.Si(98); private Trivial largeTrivial = Trivial.Si(Prefix.Kilo, 3); @@ -47,19 +47,19 @@ public class DividingQuantities /* // * Summary * -BenchmarkDotNet=v0.12.1, OS=arch +BenchmarkDotNet=v0.13.2, OS=arch Intel Core i7-8565U CPU 1.80GHz (Whiskey Lake), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=7.0.100 - [Host] : .NET Core 7.0.0 (CoreCLR 7.0.22.56001, CoreFX 7.0.22.56001), X64 RyuJIT - DefaultJob : .NET Core 7.0.0 (CoreCLR 7.0.22.56001, CoreFX 7.0.22.56001), X64 RyuJIT +.NET SDK=7.0.103 + [Host] : .NET 7.0.3 (7.0.323.12801), X64 RyuJIT AVX2 + DefaultJob : .NET 7.0.3 (7.0.323.12801), X64 RyuJIT AVX2 -| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | -|--------------- |---------:|---------:|---------:|------:|------:|------:|------:|----------:| -| Trivial | 16.06 ns | 0.043 ns | 0.036 ns | 1.00 | - | - | - | - | -| DivideSi | 30.35 ns | 0.061 ns | 0.057 ns | 1.89 | - | - | - | - | -| DivideImperial | 27.27 ns | 0.054 ns | 0.048 ns | 1.70 | - | - | - | - | -| DivideMixed | 27.91 ns | 0.013 ns | 0.011 ns | 1.74 | - | - | - | - | -| DivideAliased | 38.82 ns | 0.072 ns | 0.063 ns | 2.42 | - | - | - | - | -| DividePureSi | 12.48 ns | 0.048 ns | 0.045 ns | 0.78 | - | - | - | - | +| Method | Mean | Error | StdDev | Ratio | RatioSD | Allocated | Alloc Ratio | +|--------------- |---------:|---------:|---------:|------:|--------:|----------:|------------:| +| Trivial | 16.57 ns | 0.127 ns | 0.112 ns | 1.00 | 0.00 | - | NA | +| DivideSi | 31.98 ns | 0.642 ns | 0.569 ns | 1.93 | 0.03 | - | NA | +| DivideImperial | 30.06 ns | 0.195 ns | 0.173 ns | 1.81 | 0.02 | - | NA | +| DivideMixed | 28.86 ns | 0.117 ns | 0.103 ns | 1.74 | 0.01 | - | NA | +| DivideAliased | 42.24 ns | 0.478 ns | 0.447 ns | 2.55 | 0.03 | - | NA | +| DividePureSi | 11.35 ns | 0.043 ns | 0.038 ns | 0.69 | 0.00 | - | NA | */ diff --git a/quantities.test/AreaTest.cs b/quantities.test/AreaTest.cs index 0a8e342f..4773705e 100644 --- a/quantities.test/AreaTest.cs +++ b/quantities.test/AreaTest.cs @@ -10,33 +10,33 @@ public class AreaTest [Fact] public void AddSquareMetres() { - Area left = Area.Square(20); - Area right = Area.Square(10); + Area left = Area.Of(20).Square.Si(); + Area right = Area.Of(10).Square.Si(); Area result = left + right; PrecisionIsBounded(30d, result); } [Fact] public void AddSquareHectoMetresToSquareKiloMetres() { - Area left = Area.Square(2); - Area right = Area.Square(50); + Area left = Area.Of(2).Square.Si(); + Area right = Area.Of(50).Square.Si(); Area result = left + right; PrecisionIsBounded(2.5d, result); } [Fact] public void SquareMetresToSquareKilometers() { - Area squareMetres = Area.Square(1000); - Area squareKilometres = squareMetres.ToSquare(); + Area squareMetres = Area.Of(1000).Square.Si(); + Area squareKilometres = squareMetres.To.Square.Si(); PrecisionIsBounded(1e-3d, squareKilometres); } [Fact] public void SquareMilesToSquareKilometers() { - Area squareMiles = Area.SquareImperial(2); - Area expected = Area.Square(2 * SQUARE_MILE_IN_SQUARE_KILOMETRES); + Area squareMiles = Area.Of(2).Square.Imperial(); + Area expected = Area.Of(2 * SQUARE_MILE_IN_SQUARE_KILOMETRES).Square.Si(); - Area actual = squareMiles.ToSquare(); + Area actual = squareMiles.To.Square.Si(); actual.Matches(expected); } @@ -44,10 +44,10 @@ public void SquareMilesToSquareKilometers() [Fact] public void SquareYardToSquareFeet() { - Area squareYards = Area.SquareImperial(3); - Area expected = Area.SquareImperial(27); + Area squareYards = Area.Of(3).Square.Imperial(); + Area expected = Area.Of(27).Square.Imperial(); - Area actual = squareYards.ToSquareImperial(); + Area actual = squareYards.To.Square.Imperial(); actual.Matches(expected, MediumPrecision - 1); } @@ -55,7 +55,7 @@ public void SquareYardToSquareFeet() [Fact] public void SquareMetresDividedByMetre() { - Area area = Area.Square(48.40); + Area area = Area.Of(48.40).Square.Si(); Length length = Length.Of(605).Si(); Length expected = Length.Of(0.8).Si(); @@ -66,7 +66,7 @@ public void SquareMetresDividedByMetre() [Fact] public void PureArealDimensionDividedByLength() { - Area area = Area.Imperial(2); + Area area = Area.Of(2).Imperial(); Length length = Length.Of(1815).Imperial(); Length expected = Length.Of(16).Imperial(); @@ -77,7 +77,7 @@ public void PureArealDimensionDividedByLength() [Fact] public void SquareYardsDividedByFeet() { - Area area = Area.SquareImperial(27); + Area area = Area.Of(27).Square.Imperial(); Length length = Length.Of(1).Imperial(); Length expected = Length.Of(9).Imperial(); @@ -89,15 +89,15 @@ public void SquareYardsDividedByFeet() [Fact] public void AcreDividedBySquareFeet() { - Area acres = Area.Imperial(2); - Area squareFeet = Area.SquareImperial(2 * 43560); + Area acres = Area.Of(2).Imperial(); + Area squareFeet = Area.Of(2 * 43560).Square.Imperial(); Assert.Equal(acres, squareFeet); } [Fact] public void SquareMetersTimesMetres() { - Area area = Area.Square(27); + Area area = Area.Of(27).Square.Si(); Length length = Length.Of(30).Si(); Volume expected = Volume.Cubic(81); @@ -108,7 +108,7 @@ public void SquareMetersTimesMetres() [Fact] public void SquareFeetTimesYards() { - Area area = Area.SquareImperial(27); + Area area = Area.Of(27).Square.Imperial(); Length length = Length.Of(2).Imperial(); Volume expected = Volume.CubicImperial(162); @@ -120,37 +120,37 @@ public void SquareFeetTimesYards() [Fact] public void AreToSiDefinition() { - Area are = Area.Metric(1); - Area expected = Area.Square(100); + Area are = Area.Of(1).Metric(); + Area expected = Area.Of(100).Square.Si(); - Area actual = are.ToSquare(); + Area actual = are.To.Square.Si(); actual.Matches(expected); } [Fact] public void AreToHectare() { - Area are = Area.Metric(100); - Area expected = Area.Metric(1); + Area are = Area.Of(100).Metric(); + Area expected = Area.Of(1).Metric(); - Area actual = are.ToMetric(); + Area actual = are.To.Metric(); actual.Matches(expected); } [Fact] public void MorgenToHectare() { - Area morgen = Area.NonStandard(2); - Area expected = Area.Square(5000); + Area morgen = Area.Of(2).NonStandard(); + Area expected = Area.Of(5000).Square.Si(); - Area actual = morgen.ToSquare(); + Area actual = morgen.To.Square.Si(); actual.Matches(expected); } [Fact] public void AreTimesMeterIsCubicMetre() { - Area area = Area.Metric(1); + Area area = Area.Of(1).Metric(); Length length = Length.Of(10).Si(); Volume expected = Volume.Cubic(10 * 10 * 10); diff --git a/quantities.test/LengthTest.cs b/quantities.test/LengthTest.cs index a0c70e70..2310f12c 100644 --- a/quantities.test/LengthTest.cs +++ b/quantities.test/LengthTest.cs @@ -118,7 +118,7 @@ public void SiLengthBySiLengthIsSiArea() { Length length = Length.Of(2).Si(); Length width = Length.Of(1).Si(); - Area expected = Area.Square(0.2); + Area expected = Area.Of(0.2).Square.Si(); Area actual = length * width; @@ -129,7 +129,7 @@ public void ImperialLengthByImperialLengthIsImperialArea() { Length length = Length.Of(2).Imperial(); Length width = Length.Of(1760 / 2).Imperial(); - Area expected = Area.SquareImperial(1); + Area expected = Area.Of(1).Square.Imperial(); Area actual = length * width; @@ -139,7 +139,7 @@ public void ImperialLengthByImperialLengthIsImperialArea() public void LengthByDivisionIsEqualToLengthByConstruction() { Volume volume = Volume.Metric(300); - Area area = Area.Square(6); + Area area = Area.Of(6).Square.Si(); Length expected = Length.Of(5).Si(); Length actual = volume / area; diff --git a/quantities.test/VolumeTest.cs b/quantities.test/VolumeTest.cs index 94bc0078..17a7947c 100644 --- a/quantities.test/VolumeTest.cs +++ b/quantities.test/VolumeTest.cs @@ -108,7 +108,7 @@ public void DivideCubicMetreByMetre() { Volume volume = Volume.Cubic(81); Length length = Length.Of(3).Si(); - Area expected = Area.Square(27); + Area expected = Area.Of(27).Square.Si(); Area actual = volume / length; @@ -119,7 +119,7 @@ public void DividePureVolumeByLength() { Volume volume = Volume.Metric(300); Length length = Length.Of(5).Si(); - Area expected = Area.Square(6); + Area expected = Area.Of(6).Square.Si(); Area actual = volume / length; diff --git a/quantities/IImperial.cs b/quantities/IImperial.cs index 881a9c2a..456f1a0a 100644 --- a/quantities/IImperial.cs +++ b/quantities/IImperial.cs @@ -8,7 +8,7 @@ internal interface IImperial where TDimension : IDimension { public TSelf ToImperial() - where TUnit : IImperial, TDimension; + where TUnit : IImperialUnit, TDimension; public static abstract TSelf Imperial(in Double value) - where TUnit : IImperial, TDimension; + where TUnit : IImperialUnit, TDimension; } diff --git a/quantities/INoSystem.cs b/quantities/INoSystem.cs index f8daa078..a5a0aced 100644 --- a/quantities/INoSystem.cs +++ b/quantities/INoSystem.cs @@ -8,7 +8,7 @@ internal interface INoSystem where TDimension : IDimension { public TSelf ToNonStandard() - where TUnit : INoSystem, TDimension; + where TUnit : INoSystemUnit, TDimension; public static abstract TSelf NonStandard(in Double value) - where TUnit : INoSystem, TDimension; + where TUnit : INoSystemUnit, TDimension; } diff --git a/quantities/factories/Factories.cs b/quantities/factories/Factories.cs index 637bcb09..4dc7e563 100644 --- a/quantities/factories/Factories.cs +++ b/quantities/factories/Factories.cs @@ -23,11 +23,11 @@ public interface IMetricFactory : IFactory public interface IImperialFactory where TDimension : IDimension { - public TQuantity Imperial() where TUnit : IImperial, TDimension; + public TQuantity Imperial() where TUnit : IImperialUnit, TDimension; } public interface INonStandardFactory where TDimension : IDimension { - public TQuantity NonStandard() where TUnit : INoSystem, TDimension; + public TQuantity NonStandard() where TUnit : INoSystemUnit, TDimension; } diff --git a/quantities/factories/IPowerCreate.cs b/quantities/factories/IPowerCreate.cs new file mode 100644 index 00000000..312bfc14 --- /dev/null +++ b/quantities/factories/IPowerCreate.cs @@ -0,0 +1,12 @@ +using Quantities.Dimensions; +using Quantities.Measures; + +namespace Quantities.Factories; + +public interface IPowerCreate +{ + internal TQuantity Create() + where TMeasure : IMeasure, ILinear; + internal TQuantity Create() + where TMeasure : IMeasure, ILinear where TAlias : IInjector, new(); +} diff --git a/quantities/factories/IPowerFactory.cs b/quantities/factories/IPowerFactory.cs new file mode 100644 index 00000000..d4ad5102 --- /dev/null +++ b/quantities/factories/IPowerFactory.cs @@ -0,0 +1,28 @@ +using Quantities.Dimensions; +using Quantities.Prefixes; +using Quantities.Units; +using Quantities.Units.Imperial; +using Quantities.Units.NonStandard; +using Quantities.Units.Si; + +namespace Quantities.Factories; + +public interface ISquareFactory : IHighDimFactory + where TPower : IDimension + where TLinear : IDimension, ILinear + where TCompound : ICompoundFactory +{ + public TCompound Square { get; } +} + +public interface IHighDimFactory : IFactory + where TPower : IDimension + where TLinear : IDimension, ILinear +{ + public TQuantity Metric() where TUnit : IMetricUnit, TPower, IInjectUnit; + public TQuantity Metric() + where TPrefix : IMetricPrefix + where TUnit : IMetricUnit, TPower, IInjectUnit; + public TQuantity Imperial() where TUnit : IImperialUnit, TPower, IInjectUnit; + public TQuantity NonStandard() where TUnit : INoSystemUnit, TPower, IInjectUnit; +} diff --git a/quantities/factories/LinearFactories.cs b/quantities/factories/LinearFactories.cs index f6b117e6..c530a2f2 100644 --- a/quantities/factories/LinearFactories.cs +++ b/quantities/factories/LinearFactories.cs @@ -22,8 +22,8 @@ public TQuantity Metric() where TPrefix : IMetricPrefix where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); - public TQuantity Imperial() where TUnit : IImperial, TDimension => TQuantity.Create(this.value.As>()); - public TQuantity NonStandard() where TUnit : INoSystem, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity Imperial() where TUnit : IImperialUnit, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity NonStandard() where TUnit : INoSystemUnit, TDimension => TQuantity.Create(this.value.As>()); } public readonly struct LinearCreate : ICompoundFactory where TDimension : Dimensions.IDimension, ILinear @@ -40,6 +40,6 @@ public TQuantity Metric() where TPrefix : IMetricPrefix where TUnit : IMetricUnit, TDimension => TQuantity.Create(this.value.As>()); - public TQuantity Imperial() where TUnit : IImperial, TDimension => TQuantity.Create(this.value.As>()); - public TQuantity NonStandard() where TUnit : INoSystem, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity Imperial() where TUnit : IImperialUnit, TDimension => TQuantity.Create(this.value.As>()); + public TQuantity NonStandard() where TUnit : INoSystemUnit, TDimension => TQuantity.Create(this.value.As>()); } diff --git a/quantities/factories/PowerFactory.cs b/quantities/factories/PowerFactory.cs new file mode 100644 index 00000000..9ec72f8c --- /dev/null +++ b/quantities/factories/PowerFactory.cs @@ -0,0 +1,29 @@ +using Quantities.Dimensions; +using Quantities.Measures; +using Quantities.Prefixes; +using Quantities.Units.Imperial; +using Quantities.Units.NonStandard; +using Quantities.Units.Si; + +namespace Quantities.Factories; + +public readonly struct PowerFactory : ICompoundFactory, IPowerCreate + where TCreate : IPowerCreate + where TLinear : Dimensions.IDimension, ILinear +{ + private readonly TCreate creator; + internal PowerFactory(in TCreate value) => this.creator = value; + public TQuantity Si() where TUnit : ISiUnit, TLinear => this.creator.Create>(); + public TQuantity Si() + where TPrefix : IMetricPrefix + where TUnit : ISiUnit, TLinear => this.creator.Create>(); + public TQuantity Metric() where TUnit : IMetricUnit, TLinear => this.creator.Create>(); + public TQuantity Metric() + where TPrefix : IMetricPrefix + where TUnit : IMetricUnit, TLinear => this.creator.Create>(); + public TQuantity Imperial() where TUnit : IImperialUnit, TLinear => this.creator.Create>(); + public TQuantity NonStandard() where TUnit : INoSystemUnit, TLinear => this.creator.Create>(); + TQuantity IPowerCreate.Create() => this.creator.Create(); + TQuantity IPowerCreate.Create() => this.creator.Create(); + +} diff --git a/quantities/factories/SquareCreate.cs b/quantities/factories/SquareCreate.cs new file mode 100644 index 00000000..cbc8fe1b --- /dev/null +++ b/quantities/factories/SquareCreate.cs @@ -0,0 +1,21 @@ +using Quantities.Measures; + +namespace Quantities.Factories; + +public readonly struct SquareTo : IPowerCreate + where TQuantity : IFactory +{ + private readonly Quant value; + internal SquareTo(in Quant value) => this.value = value; + TQuantity IPowerCreate.Create() => TQuantity.Create(this.value.To()); + TQuantity IPowerCreate.Create() => TQuantity.Create(this.value.As()); +} + +public readonly struct SquareCreate : IPowerCreate + where TQuantity : IFactory +{ + private readonly Double value; + internal SquareCreate(in Double value) => this.value = value; + TQuantity IPowerCreate.Create() => TQuantity.Create(this.value.To()); + TQuantity IPowerCreate.Create() => TQuantity.Create(this.value.As()); +} diff --git a/quantities/factories/SquareFactory.cs b/quantities/factories/SquareFactory.cs new file mode 100644 index 00000000..18fe01b5 --- /dev/null +++ b/quantities/factories/SquareFactory.cs @@ -0,0 +1,38 @@ +using Quantities.Dimensions; +using Quantities.Measures; +using Quantities.Prefixes; +using Quantities.Units; +using Quantities.Units.Imperial; +using Quantities.Units.NonStandard; +using Quantities.Units.Si; + +namespace Quantities.Factories; + +public readonly struct SquareFactory : ISquareFactory + where TLinear : Dimensions.IDimension, ILinear + where TSquare : Dimensions.IDimension + where TCompound : ICompoundFactory, IPowerCreate + where TQuantity : IFactory +{ + private readonly TCompound squareFactory; + public TCompound Square => this.squareFactory; + internal SquareFactory(in TCompound compound) => this.squareFactory = compound; + public TQuantity Metric() where TUnit : IMetricUnit, TSquare, IInjectUnit + { + return this.squareFactory.Create, Alias>(); + } + public TQuantity Metric() + where TPrefix : IMetricPrefix + where TUnit : IMetricUnit, TSquare, IInjectUnit + { + return this.squareFactory.Create, Alias>(); + } + public TQuantity Imperial() where TUnit : IImperialUnit, TSquare, IInjectUnit + { + return this.squareFactory.Create, Alias>(); + } + public TQuantity NonStandard() where TUnit : INoSystemUnit, TSquare, IInjectUnit + { + return this.squareFactory.Create, Alias>(); + } +} diff --git a/quantities/measures/IMeasure.cs b/quantities/measures/IMeasure.cs index a938a237..9e9a3568 100644 --- a/quantities/measures/IMeasure.cs +++ b/quantities/measures/IMeasure.cs @@ -24,12 +24,12 @@ internal interface ISiAccepted : IMeasure /* marker interface*/ } internal interface IImperialMeasure : IMeasure - where TUnit : IImperial, ITransform, IRepresentable + where TUnit : IImperialUnit, ITransform, IRepresentable { /* marker interface*/ } internal interface INonStandardMeasure : IMeasure - where TUnit : INoSystem, ITransform, IRepresentable + where TUnit : INoSystemUnit, ITransform, IRepresentable { /* marker interface*/ } \ No newline at end of file diff --git a/quantities/measures/Measures.cs b/quantities/measures/Measures.cs index 62cf4dae..c7f7f8e8 100644 --- a/quantities/measures/Measures.cs +++ b/quantities/measures/Measures.cs @@ -37,14 +37,14 @@ namespace Quantities.Measures; public static String Representation { get; } = $"{TPrefix.Representation}{TUnit.Representation}"; } internal readonly struct Imperial : IImperialMeasure, ILinear - where TUnit : IImperial, ITransform, IRepresentable + where TUnit : IImperialUnit, ITransform, IRepresentable { public static Double ToSi(in Double value) => TUnit.ToSi(in value); public static Double FromSi(in Double value) => TUnit.FromSi(in value); public static String Representation => TUnit.Representation; } internal readonly struct NonStandard : INonStandardMeasure, ILinear - where TUnit : INoSystem, ITransform, IRepresentable + where TUnit : INoSystemUnit, ITransform, IRepresentable { public static Double ToSi(in Double value) => TUnit.ToSi(in value); public static Double FromSi(in Double value) => TUnit.FromSi(in value); diff --git a/quantities/quantities/Area.cs b/quantities/quantities/Area.cs index 293d4db0..238de904 100644 --- a/quantities/quantities/Area.cs +++ b/quantities/quantities/Area.cs @@ -1,16 +1,14 @@ using System.Numerics; using Quantities.Dimensions; +using Quantities.Factories; using Quantities.Measures; using Quantities.Measures.Transformations; -using Quantities.Prefixes; -using Quantities.Units; -using Quantities.Units.Imperial; -using Quantities.Units.NonStandard; -using Quantities.Units.Si; namespace Quantities.Quantities; -public readonly struct Area : IQuantity, IArea +public readonly struct Area : IQuantity, IArea + , IFactory + , IFactory, ILength>, IArea, ILength>, SquareFactory, ILength>, IArea, ILength>> , IMultiplyOperators , IDivisionOperators { @@ -18,81 +16,10 @@ namespace Quantities.Quantities; private static readonly ICreate linear = new ToLinear(); private readonly Quant quant; internal Quant Quant => this.quant; + public SquareFactory, ILength>, IArea, ILength> To => new(new PowerFactory, ILength>(new SquareTo(in this.quant))); private Area(in Quant quant) => this.quant = quant; - public Area ToSquare() - where TUnit : ISiUnit, ILength - { - return new(this.quant.To>()); - } - public Area ToSquare() - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, ILength - { - return new(this.quant.To>()); - } - public Area ToMetric() - where TArea : IMetricUnit, IArea, IInjectUnit - { - return new(this.quant.As, Alias>()); - } - public Area ToMetric() - where TPrefix : IMetricPrefix - where TArea : IMetricUnit, IArea, IInjectUnit - { - return new(this.quant.As, Alias>()); - } - public Area ToImperial() - where TArea : IImperial, IArea, IInjectUnit - { - return new(this.quant.As, Alias>()); - } - public Area ToSquareImperial() - where TLength : IImperial, ILength - { - return new(this.quant.To>()); - } - public Area ToNonStandard() - where TArea : INoSystem, IArea, IInjectUnit - { - return new(this.quant.As, Alias>()); - } - public static Area Square(in Double value) - where TUnit : ISiUnit, ILength - { - return new(value.To>()); - } - public static Area Square(in Double value) - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, ILength - { - return new(value.To>()); - } - public static Area Metric(in Double value) - where TArea : IMetricUnit, IArea, IInjectUnit - { - return new(value.As, Alias>()); - } - public static Area Metric(in Double value) - where TPrefix : IMetricPrefix - where TArea : IMetricUnit, IArea, IInjectUnit - { - return new(value.As, Alias>()); - } - public static Area SquareImperial(Double value) - where TLength : IImperial, ILength - { - return new(value.To>()); - } - public static Area Imperial(Double value) - where TArea : IImperial, IArea, IInjectUnit - { - return new(value.As, Alias>()); - } - public static Area NonStandard(Double value) - where TArea : INoSystem, IArea, IInjectUnit - { - return new(value.As, Alias>()); - } + public static SquareFactory, ILength>, IArea, ILength> Of(in Double value) => new(new PowerFactory, ILength>(new SquareCreate(in value))); + static Area IFactory.Create(in Quant quant) => new(in quant); internal static Area From(in Length left, in Length right) { var pseudoLength = left.Quant.PseudoMultiply(right.Quant); @@ -106,12 +33,11 @@ internal static Area From(in Volume volume, in Length length) } public Boolean Equals(Area other) => this.quant.Equals(other.quant); - public override Boolean Equals(Object? obj) => obj is Area Area && Equals(Area); - public override Int32 GetHashCode() => this.quant.GetHashCode(); public override String ToString() => this.quant.ToString(); public String ToString(String? format, IFormatProvider? provider) => this.quant.ToString(format, provider); + public static Boolean operator ==(Area left, Area right) => left.Equals(right); public static Boolean operator !=(Area left, Area right) => !left.Equals(right); public static implicit operator Double(Area Area) => Area.quant.Value; diff --git a/quantities/quantities/Energy.cs b/quantities/quantities/Energy.cs index 2337fcd1..68408f99 100644 --- a/quantities/quantities/Energy.cs +++ b/quantities/quantities/Energy.cs @@ -35,7 +35,7 @@ public Energy ToMetric() return new(this.quant.AsProduct, Metric>()); } public Energy ToImperial() - where TUnit : IImperial, IEnergy + where TUnit : IImperialUnit, IEnergy { return new(this.quant.As>()); } @@ -73,7 +73,7 @@ public static Energy Metric(in Double value) return new(value.AsProduct, Metric>()); } public static Energy Imperial(in Double value) - where TUnit : IImperial, IEnergy + where TUnit : IImperialUnit, IEnergy { return new(value.As>()); } diff --git a/quantities/quantities/Power.cs b/quantities/quantities/Power.cs index 40279a58..a2e8e5af 100644 --- a/quantities/quantities/Power.cs +++ b/quantities/quantities/Power.cs @@ -46,7 +46,7 @@ public Power ToMetric() return new(this.quant.As>()); } public Power ToImperial() - where TUnit : IImperial, IPower + where TUnit : IImperialUnit, IPower { return new(this.quant.As>()); } @@ -62,7 +62,7 @@ public static Power Si(in Double value) return new(value.As>()); } public static Power Imperial(in Double value) - where TUnit : IImperial, IPower + where TUnit : IImperialUnit, IPower { return new(value.As>()); } diff --git a/quantities/quantities/Velocity.cs b/quantities/quantities/Velocity.cs index f209385f..cb622314 100644 --- a/quantities/quantities/Velocity.cs +++ b/quantities/quantities/Velocity.cs @@ -28,7 +28,7 @@ public IBuilder To() return new Transform>(in this.quant); } public IBuilder ToImperial() - where TUnit : IImperial, ILength + where TUnit : IImperialUnit, ILength { return new Transform>(in this.quant); } @@ -41,7 +41,7 @@ public static IBuilder Si(in Double value) return new Builder>(in value); } public static IBuilder Imperial(in Double value) - where TUnit : IImperial, ILength + where TUnit : IImperialUnit, ILength { return new Builder>(in value); } diff --git a/quantities/quantities/Volume.cs b/quantities/quantities/Volume.cs index e4efe09d..6d2bb8fb 100644 --- a/quantities/quantities/Volume.cs +++ b/quantities/quantities/Volume.cs @@ -38,12 +38,12 @@ public Volume ToMetric() return new(this.quant.As, Alias>()); } public Volume ToImperial() - where TUnit : IImperial, IVolume, IInjectUnit + where TUnit : IImperialUnit, IVolume, IInjectUnit { return new(this.quant.As, Alias>()); } public Volume ToCubicImperial() - where TLength : IImperial, ILength + where TLength : IImperialUnit, ILength { return new(this.quant.To>()); } @@ -70,12 +70,12 @@ public static Volume Metric(Double value) return new(value.As, Alias>()); } public static Volume Imperial(Double value) - where TVolume : IImperial, IVolume, IInjectUnit + where TVolume : IImperialUnit, IVolume, IInjectUnit { return new(value.As, Alias>()); } public static Volume CubicImperial(Double value) - where TImperialUnit : IImperial, ILength + where TImperialUnit : IImperialUnit, ILength { return new(value.To>()); } diff --git a/quantities/units/IInjectUnit.cs b/quantities/units/IInjectUnit.cs index f6362a7d..b725ea37 100644 --- a/quantities/units/IInjectUnit.cs +++ b/quantities/units/IInjectUnit.cs @@ -24,11 +24,11 @@ public T Metric(in Double value) where TInjectedUnit : IMetricUni { return this.creator.Create>(in value); } - public T Imperial(in Double value) where TInjectedUnit : IImperial, ITransform, TAlias + public T Imperial(in Double value) where TInjectedUnit : IImperialUnit, ITransform, TAlias { return this.creator.Create>(in value); } - public T NonStandard(in Double value) where TInjectedUnit : INoSystem, ITransform, TAlias + public T NonStandard(in Double value) where TInjectedUnit : INoSystemUnit, ITransform, TAlias { return this.creator.Create>(in value); } diff --git a/quantities/units/Imperial/Area/Acre.cs b/quantities/units/Imperial/Area/Acre.cs index 1ad7f68e..b3c7b69e 100644 --- a/quantities/units/Imperial/Area/Acre.cs +++ b/quantities/units/Imperial/Area/Acre.cs @@ -4,7 +4,7 @@ namespace Quantities.Units.Imperial.Area; -public readonly struct Acre : IImperial, IArea, IInjectUnit +public readonly struct Acre : IImperialUnit, IArea, IInjectUnit { internal const Double ToSquareMetre = 4046.8564224; // ac -> m² private static readonly Transform transform = new(ToSquareMetre); diff --git a/quantities/units/Imperial/Area/Perch.cs b/quantities/units/Imperial/Area/Perch.cs index db66398a..8de7609b 100644 --- a/quantities/units/Imperial/Area/Perch.cs +++ b/quantities/units/Imperial/Area/Perch.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Area; -public readonly struct Perch : IImperial, IArea +public readonly struct Perch : IImperialUnit, IArea { private static readonly Transform transform = new(25.29285264 /* m² */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Area/Rood.cs b/quantities/units/Imperial/Area/Rood.cs index db2d6b81..a49c8e5b 100644 --- a/quantities/units/Imperial/Area/Rood.cs +++ b/quantities/units/Imperial/Area/Rood.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Area; -public readonly struct Rood : IImperial, IArea +public readonly struct Rood : IImperialUnit, IArea { private static readonly Transform transform = new(1011.7141056 /* m² */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/IImperial.cs b/quantities/units/Imperial/IImperial.cs deleted file mode 100644 index 379e0e8c..00000000 --- a/quantities/units/Imperial/IImperial.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Quantities.Units.Imperial; - -public interface IImperial : IUnit, ITransform { /* marker interface */ } diff --git a/quantities/units/Imperial/IImperialUnit.cs b/quantities/units/Imperial/IImperialUnit.cs new file mode 100644 index 00000000..5460ea41 --- /dev/null +++ b/quantities/units/Imperial/IImperialUnit.cs @@ -0,0 +1,3 @@ +namespace Quantities.Units.Imperial; + +public interface IImperialUnit : IUnit, ITransform { /* marker interface */ } diff --git a/quantities/units/Imperial/Length/Chain.cs b/quantities/units/Imperial/Length/Chain.cs index 51c6f5b1..f2c63749 100644 --- a/quantities/units/Imperial/Length/Chain.cs +++ b/quantities/units/Imperial/Length/Chain.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Length; -public readonly struct Chain : IImperial, ILength +public readonly struct Chain : IImperialUnit, ILength { private static readonly Transform transform = new(20.1168 /* m */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Length/Foot.cs b/quantities/units/Imperial/Length/Foot.cs index 950a8e8b..ed6b7690 100644 --- a/quantities/units/Imperial/Length/Foot.cs +++ b/quantities/units/Imperial/Length/Foot.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Length; -public readonly struct Foot : IImperial, ILength +public readonly struct Foot : IImperialUnit, ILength { internal const Double ToMetre = 0.3048; // ft -> m private static readonly Transform transform = new(ToMetre); diff --git a/quantities/units/Imperial/Length/Furlong.cs b/quantities/units/Imperial/Length/Furlong.cs index 2c25dab2..9d0b5edd 100644 --- a/quantities/units/Imperial/Length/Furlong.cs +++ b/quantities/units/Imperial/Length/Furlong.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Length; -public readonly struct Furlong : IImperial, ILength +public readonly struct Furlong : IImperialUnit, ILength { private static readonly Transform transform = new(201.168 /* m */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Length/Inch.cs b/quantities/units/Imperial/Length/Inch.cs index f9df3fa6..4e77b646 100644 --- a/quantities/units/Imperial/Length/Inch.cs +++ b/quantities/units/Imperial/Length/Inch.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Length; -public readonly struct Inch : IImperial, ILength +public readonly struct Inch : IImperialUnit, ILength { internal const Double ToMetre = 0.0254; // in -> m private static readonly Transform transform = new(ToMetre); diff --git a/quantities/units/Imperial/Length/Mile.cs b/quantities/units/Imperial/Length/Mile.cs index 2c52ab6e..b707489a 100644 --- a/quantities/units/Imperial/Length/Mile.cs +++ b/quantities/units/Imperial/Length/Mile.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Length; -public readonly struct Mile : IImperial, ILength +public readonly struct Mile : IImperialUnit, ILength { private static readonly Transform transform = new(1609.344 /* m */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Length/Yard.cs b/quantities/units/Imperial/Length/Yard.cs index 76cc5b8d..3df796db 100644 --- a/quantities/units/Imperial/Length/Yard.cs +++ b/quantities/units/Imperial/Length/Yard.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Length; -public readonly struct Yard : IImperial, ILength +public readonly struct Yard : IImperialUnit, ILength { private static readonly Transform transform = new(0.9144 /* m */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Mass/Drachm.cs b/quantities/units/Imperial/Mass/Drachm.cs index 8464b8f9..3673ece1 100644 --- a/quantities/units/Imperial/Mass/Drachm.cs +++ b/quantities/units/Imperial/Mass/Drachm.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Mass; -public readonly struct Drachm : IImperial, IMass +public readonly struct Drachm : IImperialUnit, IMass { private static readonly Transform transform = new(1.7718451953125e-3 /* kg */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Mass/Grain.cs b/quantities/units/Imperial/Mass/Grain.cs index ae000def..eb56036c 100644 --- a/quantities/units/Imperial/Mass/Grain.cs +++ b/quantities/units/Imperial/Mass/Grain.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Mass; -public readonly struct Grain : IImperial, IMass +public readonly struct Grain : IImperialUnit, IMass { private static readonly Transform transform = new(64.79891e-6 /* kg */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Mass/Hundredweight.cs b/quantities/units/Imperial/Mass/Hundredweight.cs index f6be957f..354eb348 100644 --- a/quantities/units/Imperial/Mass/Hundredweight.cs +++ b/quantities/units/Imperial/Mass/Hundredweight.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Mass; -public readonly struct Hundredweight : IImperial, IMass +public readonly struct Hundredweight : IImperialUnit, IMass { private static readonly Transform transform = new(50.80234544 /* kg */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Mass/Ounce.cs b/quantities/units/Imperial/Mass/Ounce.cs index 72aa81dd..7205927d 100644 --- a/quantities/units/Imperial/Mass/Ounce.cs +++ b/quantities/units/Imperial/Mass/Ounce.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Mass; -public readonly struct Ounce : IImperial, IMass +public readonly struct Ounce : IImperialUnit, IMass { private static readonly Transform transform = new(28.349523125e-3 /* kg */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Mass/Pound.cs b/quantities/units/Imperial/Mass/Pound.cs index 291b143e..319e547f 100644 --- a/quantities/units/Imperial/Mass/Pound.cs +++ b/quantities/units/Imperial/Mass/Pound.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Mass; -public readonly struct Pound : IImperial, IMass +public readonly struct Pound : IImperialUnit, IMass { private static readonly Transform transform = new(0.45359237 /* kg */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Mass/Quarter.cs b/quantities/units/Imperial/Mass/Quarter.cs index c2f2699f..c5832357 100644 --- a/quantities/units/Imperial/Mass/Quarter.cs +++ b/quantities/units/Imperial/Mass/Quarter.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Mass; -public readonly struct Quarter : IImperial, IMass +public readonly struct Quarter : IImperialUnit, IMass { private static readonly Transform transform = new(12.70058636 /* kg */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Mass/Slug.cs b/quantities/units/Imperial/Mass/Slug.cs index 0ad007c4..2b8500b3 100644 --- a/quantities/units/Imperial/Mass/Slug.cs +++ b/quantities/units/Imperial/Mass/Slug.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Mass; -public readonly struct Slug : IImperial, IMass +public readonly struct Slug : IImperialUnit, IMass { private static readonly Transform transform = new(14.59390294 /* kg */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Mass/Stone.cs b/quantities/units/Imperial/Mass/Stone.cs index 9dafb6b3..fad15481 100644 --- a/quantities/units/Imperial/Mass/Stone.cs +++ b/quantities/units/Imperial/Mass/Stone.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Mass; -public readonly struct Stone : IImperial, IMass +public readonly struct Stone : IImperialUnit, IMass { private static readonly Transform transform = new(6.35029318 /* kg */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Mass/Ton.cs b/quantities/units/Imperial/Mass/Ton.cs index 26c53116..87720a59 100644 --- a/quantities/units/Imperial/Mass/Ton.cs +++ b/quantities/units/Imperial/Mass/Ton.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Mass; -public readonly struct Ton : IImperial, IMass +public readonly struct Ton : IImperialUnit, IMass { private static readonly Transform transform = new(1016.0469088 /* kg */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Power/HorsePower.cs b/quantities/units/Imperial/Power/HorsePower.cs index e2ba66e5..a05bb530 100644 --- a/quantities/units/Imperial/Power/HorsePower.cs +++ b/quantities/units/Imperial/Power/HorsePower.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Power; // See: https://en.wikipedia.org/wiki/Horsepower -public readonly struct HorsePower : IImperial, IPower +public readonly struct HorsePower : IImperialUnit, IPower { internal const Double InWatt = 76.0402249 * 9.80665; // ~745.700 W in 1 hp public static Double FromSi(in Double value) => value / InWatt; diff --git a/quantities/units/Imperial/Temperature/Farenheit.cs b/quantities/units/Imperial/Temperature/Farenheit.cs index c2346963..95e9d825 100644 --- a/quantities/units/Imperial/Temperature/Farenheit.cs +++ b/quantities/units/Imperial/Temperature/Farenheit.cs @@ -4,7 +4,7 @@ namespace Quantities.Units.Imperial.Temperature; // [K] ≡ ([°F] + 459.67) × ​5⁄9 // See: https://en.wikipedia.org/wiki/Conversion_of_units#Temperature -public readonly struct Fahrenheit : IImperial, ITemperature +public readonly struct Fahrenheit : IImperialUnit, ITemperature { private const Decimal kelvinOffset = 459.67m; private const Decimal scaleFromKelvin = 9m / 5m; diff --git a/quantities/units/Imperial/Temperature/GasMark.cs b/quantities/units/Imperial/Temperature/GasMark.cs index ebcb8e75..bd59c779 100644 --- a/quantities/units/Imperial/Temperature/GasMark.cs +++ b/quantities/units/Imperial/Temperature/GasMark.cs @@ -5,7 +5,7 @@ namespace Quantities.Units.Imperial.Temperature; // [K] ≡ [GM] × ​125⁄9 + 394.261 // See: https://en.wikipedia.org/wiki/Conversion_of_units#Temperature -public readonly struct GasMark : IImperial, ITemperature +public readonly struct GasMark : IImperialUnit, ITemperature { private static readonly LinearTransform transform = new(125m, 9m, (5m * 218m / 9m) + 273.15m); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Temperature/Rankine.cs b/quantities/units/Imperial/Temperature/Rankine.cs index d57319f6..e391b7f8 100644 --- a/quantities/units/Imperial/Temperature/Rankine.cs +++ b/quantities/units/Imperial/Temperature/Rankine.cs @@ -4,7 +4,7 @@ namespace Quantities.Units.Imperial.Temperature; // [K] ≡ [°R] × 5/9 // See: https://en.wikipedia.org/wiki/Conversion_of_units#Temperature -public readonly struct Rankine : IImperial, ITemperature +public readonly struct Rankine : IImperialUnit, ITemperature { public static Double ToSi(in Double nonSiValue) => (Double)(5m * (Decimal)nonSiValue / 9m); public static Double FromSi(in Double siValue) => (Double)(9m * (Decimal)siValue / 5m); diff --git a/quantities/units/Imperial/Volume/FluidOunce.cs b/quantities/units/Imperial/Volume/FluidOunce.cs index 10ecc024..f5f62519 100644 --- a/quantities/units/Imperial/Volume/FluidOunce.cs +++ b/quantities/units/Imperial/Volume/FluidOunce.cs @@ -4,7 +4,7 @@ namespace Quantities.Units.Imperial.Volume; -public readonly struct FluidOunce : IImperial, IVolume, IInjectUnit +public readonly struct FluidOunce : IImperialUnit, IVolume, IInjectUnit { internal const Double ToCubicMeter = 0.0284130625e-3; // fl oz -> m³ private static readonly Transform transform = new(ToCubicMeter); diff --git a/quantities/units/Imperial/Volume/Gallon.cs b/quantities/units/Imperial/Volume/Gallon.cs index aa31262a..5082756c 100644 --- a/quantities/units/Imperial/Volume/Gallon.cs +++ b/quantities/units/Imperial/Volume/Gallon.cs @@ -4,7 +4,7 @@ namespace Quantities.Units.Imperial.Volume; -public readonly struct Gallon : IImperial, IVolume, IInjectUnit +public readonly struct Gallon : IImperialUnit, IVolume, IInjectUnit { internal const Double ToCubicMetre = 4.54609e-3; // gal -> m³ private static readonly Transform transform = new(ToCubicMetre); diff --git a/quantities/units/Imperial/Volume/Gill.cs b/quantities/units/Imperial/Volume/Gill.cs index 848d8205..9e1c7747 100644 --- a/quantities/units/Imperial/Volume/Gill.cs +++ b/quantities/units/Imperial/Volume/Gill.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Volume; -public readonly struct Gill : IImperial, IVolume +public readonly struct Gill : IImperialUnit, IVolume { private static readonly Transform transform = new(0.1420653125e-3 /* m³ */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/Imperial/Volume/Pint.cs b/quantities/units/Imperial/Volume/Pint.cs index b6331dbb..17dda4dd 100644 --- a/quantities/units/Imperial/Volume/Pint.cs +++ b/quantities/units/Imperial/Volume/Pint.cs @@ -4,7 +4,7 @@ namespace Quantities.Units.Imperial.Volume; -public readonly struct Pint : IImperial, IVolume, IInjectUnit +public readonly struct Pint : IImperialUnit, IVolume, IInjectUnit { internal const Double ToCubicMetre = 0.56826125e-3; // pt -> m³ private static readonly Transform transform = new(ToCubicMetre); diff --git a/quantities/units/Imperial/Volume/Quart.cs b/quantities/units/Imperial/Volume/Quart.cs index b03c9cf0..4d84740b 100644 --- a/quantities/units/Imperial/Volume/Quart.cs +++ b/quantities/units/Imperial/Volume/Quart.cs @@ -3,7 +3,7 @@ namespace Quantities.Units.Imperial.Volume; -public readonly struct Quart : IImperial, IVolume +public readonly struct Quart : IImperialUnit, IVolume { private static readonly Transform transform = new(1.1365225e-3 /* m³ */); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git a/quantities/units/NonStandard/Area/Morgen.cs b/quantities/units/NonStandard/Area/Morgen.cs index 0c191a4c..575d47dc 100644 --- a/quantities/units/NonStandard/Area/Morgen.cs +++ b/quantities/units/NonStandard/Area/Morgen.cs @@ -4,7 +4,7 @@ namespace Quantities.Units.NonStandard.Area; // See: https://de.wikipedia.org/wiki/Morgen_(Einheit) -public readonly struct Morgen : INoSystem, IArea, IInjectUnit +public readonly struct Morgen : INoSystemUnit, IArea, IInjectUnit { internal const Double ToSquareMetre = 2500; // Mg -> m² public static Double ToSi(in Double value) => ToSquareMetre * value; diff --git a/quantities/units/NonStandard/INoSystem.cs b/quantities/units/NonStandard/INoSystemUnit.cs similarity index 68% rename from quantities/units/NonStandard/INoSystem.cs rename to quantities/units/NonStandard/INoSystemUnit.cs index 9c46bc63..b9b5022d 100644 --- a/quantities/units/NonStandard/INoSystem.cs +++ b/quantities/units/NonStandard/INoSystemUnit.cs @@ -2,4 +2,4 @@ // There are units of measurement that don't belong to any system. // This is the marker interface for these types of units. -public interface INoSystem : IUnit, ITransform { /* marker interface */ } +public interface INoSystemUnit : IUnit, ITransform { /* marker interface */ } diff --git a/quantities/units/NonStandard/Temperature/Delisle.cs b/quantities/units/NonStandard/Temperature/Delisle.cs index 1be0cf0c..764e48fc 100644 --- a/quantities/units/NonStandard/Temperature/Delisle.cs +++ b/quantities/units/NonStandard/Temperature/Delisle.cs @@ -4,7 +4,7 @@ namespace Quantities.Units.NonStandard.Temperature; // [K] = 373.15 − [°De] × ​2⁄3 // See: https://en.wikipedia.org/wiki/Conversion_of_units#Temperature -public readonly struct Delisle : ITransform, INoSystem, ITemperature +public readonly struct Delisle : ITransform, INoSystemUnit, ITemperature { public static Double ToSi(in Double nonSiValue) => (Double)(373.15m - 2m * (Decimal)nonSiValue / 3m); public static Double FromSi(in Double siValue) => (Double)(-1.5m * ((Decimal)siValue - 373.15m)); diff --git a/quantities/units/NonStandard/Temperature/Newton.cs b/quantities/units/NonStandard/Temperature/Newton.cs index 3951f11f..aca7197f 100644 --- a/quantities/units/NonStandard/Temperature/Newton.cs +++ b/quantities/units/NonStandard/Temperature/Newton.cs @@ -5,7 +5,7 @@ namespace Quantities.Units.NonStandard.Temperature; // [K] = [°N] × ​100⁄33 + 273.15 // See: https://en.wikipedia.org/wiki/Conversion_of_units#Temperature -public readonly struct Newton : INoSystem, ITemperature +public readonly struct Newton : INoSystemUnit, ITemperature { private static readonly LinearTransform transform = new(100m, 33m, 273.15m); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git "a/quantities/units/NonStandard/Temperature/R\303\251aumur.cs" "b/quantities/units/NonStandard/Temperature/R\303\251aumur.cs" index 1236acb2..f1c13b8a 100644 --- "a/quantities/units/NonStandard/Temperature/R\303\251aumur.cs" +++ "b/quantities/units/NonStandard/Temperature/R\303\251aumur.cs" @@ -5,7 +5,7 @@ namespace Quantities.Units.NonStandard.Temperature; // [K] = [°Ré] × ​5⁄4 + 273.15 // See: https://en.wikipedia.org/wiki/Conversion_of_units#Temperature -public readonly struct Réaumur : INoSystem, ITemperature +public readonly struct Réaumur : INoSystemUnit, ITemperature { private static readonly LinearTransform transform = new(5m, 4m, 273.15m); public static Double ToSi(in Double nonSiValue) => transform.ToSi(in nonSiValue); diff --git "a/quantities/units/NonStandard/Temperature/R\303\270mer.cs" "b/quantities/units/NonStandard/Temperature/R\303\270mer.cs" index 28abd275..3f77ec74 100644 --- "a/quantities/units/NonStandard/Temperature/R\303\270mer.cs" +++ "b/quantities/units/NonStandard/Temperature/R\303\270mer.cs" @@ -4,7 +4,7 @@ namespace Quantities.Units.NonStandard.Temperature; // [K] = ([°Rø] − 7.5) × ​40⁄21 + 273.15 // See: https://en.wikipedia.org/wiki/Conversion_of_units#Temperature -public readonly struct Rømer : INoSystem, ITemperature +public readonly struct Rømer : INoSystemUnit, ITemperature { private const Decimal scaleFromSi = 21m / 40m; public static Double ToSi(in Double nonSiValue) => (Double)((40m * ((Decimal)nonSiValue - 7.5m) / 21m) + 273.15m); From 1ab56be32bb56f03bb67a75dcd55ea20fc1b1eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=A4gi?= Date: Thu, 4 May 2023 13:36:29 +0200 Subject: [PATCH 11/30] Clean up ICreate factories. --- .../{IPowerFactory.cs => IHighDimFactory.cs} | 0 quantities/factories/IPowerCreate.cs | 12 ------------ quantities/factories/PowerFactory.cs | 8 ++++---- quantities/factories/SquareCreate.cs | 12 ++++++------ quantities/factories/SquareFactory.cs | 2 +- quantities/measures/ICreate.cs | 18 ++++++++++++++++-- 6 files changed, 27 insertions(+), 25 deletions(-) rename quantities/factories/{IPowerFactory.cs => IHighDimFactory.cs} (100%) delete mode 100644 quantities/factories/IPowerCreate.cs diff --git a/quantities/factories/IPowerFactory.cs b/quantities/factories/IHighDimFactory.cs similarity index 100% rename from quantities/factories/IPowerFactory.cs rename to quantities/factories/IHighDimFactory.cs diff --git a/quantities/factories/IPowerCreate.cs b/quantities/factories/IPowerCreate.cs deleted file mode 100644 index 312bfc14..00000000 --- a/quantities/factories/IPowerCreate.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Quantities.Dimensions; -using Quantities.Measures; - -namespace Quantities.Factories; - -public interface IPowerCreate -{ - internal TQuantity Create() - where TMeasure : IMeasure, ILinear; - internal TQuantity Create() - where TMeasure : IMeasure, ILinear where TAlias : IInjector, new(); -} diff --git a/quantities/factories/PowerFactory.cs b/quantities/factories/PowerFactory.cs index 9ec72f8c..9a1d1ef9 100644 --- a/quantities/factories/PowerFactory.cs +++ b/quantities/factories/PowerFactory.cs @@ -7,8 +7,8 @@ namespace Quantities.Factories; -public readonly struct PowerFactory : ICompoundFactory, IPowerCreate - where TCreate : IPowerCreate +public readonly struct PowerFactory : ICompoundFactory, ILinearCreate, ILinearInjectCreate + where TCreate : ILinearCreate, ILinearInjectCreate where TLinear : Dimensions.IDimension, ILinear { private readonly TCreate creator; @@ -23,7 +23,7 @@ public TQuantity Metric() where TUnit : IMetricUnit, TLinear => this.creator.Create>(); public TQuantity Imperial() where TUnit : IImperialUnit, TLinear => this.creator.Create>(); public TQuantity NonStandard() where TUnit : INoSystemUnit, TLinear => this.creator.Create>(); - TQuantity IPowerCreate.Create() => this.creator.Create(); - TQuantity IPowerCreate.Create() => this.creator.Create(); + TQuantity ILinearCreate.Create() => this.creator.Create(); + TQuantity ILinearInjectCreate.Create() => this.creator.Create(); } diff --git a/quantities/factories/SquareCreate.cs b/quantities/factories/SquareCreate.cs index cbc8fe1b..bca86867 100644 --- a/quantities/factories/SquareCreate.cs +++ b/quantities/factories/SquareCreate.cs @@ -2,20 +2,20 @@ namespace Quantities.Factories; -public readonly struct SquareTo : IPowerCreate +public readonly struct SquareTo : ILinearCreate, ILinearInjectCreate where TQuantity : IFactory { private readonly Quant value; internal SquareTo(in Quant value) => this.value = value; - TQuantity IPowerCreate.Create() => TQuantity.Create(this.value.To()); - TQuantity IPowerCreate.Create() => TQuantity.Create(this.value.As()); + TQuantity ILinearCreate.Create() => TQuantity.Create(this.value.To()); + TQuantity ILinearInjectCreate.Create() => TQuantity.Create(this.value.As()); } -public readonly struct SquareCreate : IPowerCreate +public readonly struct SquareCreate : ILinearCreate, ILinearInjectCreate where TQuantity : IFactory { private readonly Double value; internal SquareCreate(in Double value) => this.value = value; - TQuantity IPowerCreate.Create() => TQuantity.Create(this.value.To()); - TQuantity IPowerCreate.Create() => TQuantity.Create(this.value.As()); + TQuantity ILinearCreate.Create() => TQuantity.Create(this.value.To()); + TQuantity ILinearInjectCreate.Create() => TQuantity.Create(this.value.As()); } diff --git a/quantities/factories/SquareFactory.cs b/quantities/factories/SquareFactory.cs index 18fe01b5..301009fa 100644 --- a/quantities/factories/SquareFactory.cs +++ b/quantities/factories/SquareFactory.cs @@ -11,7 +11,7 @@ namespace Quantities.Factories; public readonly struct SquareFactory : ISquareFactory where TLinear : Dimensions.IDimension, ILinear where TSquare : Dimensions.IDimension - where TCompound : ICompoundFactory, IPowerCreate + where TCompound : ICompoundFactory, ILinearInjectCreate where TQuantity : IFactory { private readonly TCompound squareFactory; diff --git a/quantities/measures/ICreate.cs b/quantities/measures/ICreate.cs index 0b1bec0c..d132a593 100644 --- a/quantities/measures/ICreate.cs +++ b/quantities/measures/ICreate.cs @@ -1,6 +1,20 @@ +using Quantities.Dimensions; + namespace Quantities.Measures; -internal interface ICreate +internal interface ICreate +{ + TResult Create(in Double value) where TMeasure : IMeasure; +} + +public interface ILinearCreate +{ + internal TResult Create() + where TMeasure : IMeasure, ILinear; +} + +public interface ILinearInjectCreate { - T Create(in Double value) where TMeasure : IMeasure; + internal TResult Create() + where TMeasure : IMeasure, ILinear where TAlias : IInjector, new(); } \ No newline at end of file From e6190a1568112112dd31a50aee4a1e026de8da6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=A4gi?= Date: Sat, 6 May 2023 09:24:20 +0200 Subject: [PATCH 12/30] Let ICreate return Quant instances. --- quantities.benchmark/CreateQuantities.cs | 31 +++++++------------ .../quantities.benchmark.csproj | 4 +-- quantities/factories/LinearFactories.cs | 7 +++-- quantities/factories/PowerFactory.cs | 21 +++++++------ .../{SiFactories.cs => SiFactory.cs} | 1 + quantities/factories/SquareCreate.cs | 14 ++++----- quantities/factories/SquareFactory.cs | 10 +++--- quantities/measures/ICreate.cs | 8 ++--- quantities/quantities/Area.cs | 6 ++-- 9 files changed, 47 insertions(+), 55 deletions(-) rename quantities/factories/{SiFactories.cs => SiFactory.cs} (99%) diff --git a/quantities.benchmark/CreateQuantities.cs b/quantities.benchmark/CreateQuantities.cs index e1a9f51b..d1974716 100644 --- a/quantities.benchmark/CreateQuantities.cs +++ b/quantities.benchmark/CreateQuantities.cs @@ -4,7 +4,6 @@ using Quantities.Prefixes; using Quantities.Quantities; using Quantities.Units.Si; -using Quantities.Units.Si.Metric; namespace Quantities.Benchmark; @@ -17,48 +16,40 @@ public sealed class DummyObject public readonly struct DummyStruct { private readonly Double value; - public DummyStruct(Double value) => this.value = value; + public DummyStruct(in Double value) => this.value = value; public static implicit operator Double(DummyStruct obj) => obj.value; } [MemoryDiagnoser] +//[EventPipeProfiler(EventPipeProfile.CpuSampling)] public class CreateQuantities { private static readonly Random random = new(); private Double value = random.NextDouble(); - [Benchmark(Baseline = true)] - public DummyObject CreateObject() => new DummyObject(this.value); - - [Benchmark] - public DummyObject CreateObjectIn() => new DummyObject(in this.value); - - [Benchmark] - public DummyStruct CreateStruct() => new DummyStruct(this.value); + public Double CreateObject() => new DummyObject(in this.value); [Benchmark] - public Length CreateLength() => Length.Of(in this.value).Si(); + public Double CreateStruct() => new DummyStruct(in this.value); [Benchmark] - public Velocity CreateVelocity() => Velocity.Si(in this.value).Per(); + public Double CreateLength() => Length.Of(in this.value).Si(); } /* // * Summary * -BenchmarkDotNet=v0.13.2, OS=arch +BenchmarkDotNet=v0.13.5, OS=arch Intel Core i7-8565U CPU 1.80GHz (Whiskey Lake), 1 CPU, 8 logical and 4 physical cores .NET SDK=7.0.103 [Host] : .NET 7.0.3 (7.0.323.12801), X64 RyuJIT AVX2 DefaultJob : .NET 7.0.3 (7.0.323.12801), X64 RyuJIT AVX2 -| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio | -|--------------- |-----------:|----------:|----------:|------:|--------:|-------:|----------:|------------:| -| CreateObject | 6.1821 ns | 0.1096 ns | 0.1025 ns | 1.00 | 0.00 | 0.0057 | 24 B | 1.00 | -| CreateObjectIn | 6.7297 ns | 0.0760 ns | 0.0711 ns | 1.09 | 0.03 | 0.0057 | 24 B | 1.00 | -| CreateStruct | 0.3338 ns | 0.0049 ns | 0.0043 ns | 0.05 | 0.00 | - | - | 0.00 | -| CreateLength | 4.3623 ns | 0.0216 ns | 0.0192 ns | 0.71 | 0.01 | - | - | 0.00 | -| CreateVelocity | 10.5074 ns | 0.0638 ns | 0.0597 ns | 1.70 | 0.03 | 0.0057 | 24 B | 1.00 | +| Method | Mean | Error | StdDev | Median | Ratio | Gen0 | Allocated | Alloc Ratio | +|------------- |----------:|----------:|----------:|----------:|------:|-------:|----------:|------------:| +| CreateObject | 4.5856 ns | 0.0727 ns | 0.0680 ns | 4.5781 ns | 1.000 | 0.0057 | 24 B | 1.00 | +| CreateStruct | 0.0086 ns | 0.0156 ns | 0.0167 ns | 0.0000 ns | 0.002 | - | - | 0.00 | +| CreateLength | 1.7952 ns | 0.0287 ns | 0.0224 ns | 1.7909 ns | 0.394 | - | - | 0.00 | */ diff --git a/quantities.benchmark/quantities.benchmark.csproj b/quantities.benchmark/quantities.benchmark.csproj index 34fc1a17..c540bcef 100644 --- a/quantities.benchmark/quantities.benchmark.csproj +++ b/quantities.benchmark/quantities.benchmark.csproj @@ -13,8 +13,8 @@ false - - + + diff --git a/quantities/factories/LinearFactories.cs b/quantities/factories/LinearFactories.cs index c530a2f2..6b2bd2bc 100644 --- a/quantities/factories/LinearFactories.cs +++ b/quantities/factories/LinearFactories.cs @@ -8,8 +8,8 @@ namespace Quantities.Factories; public readonly struct LinearTo : ICompoundFactory - where TDimension : Dimensions.IDimension, ILinear where TQuantity : IFactory + where TDimension : Dimensions.IDimension, ILinear { private readonly Quant value; internal LinearTo(in Quant value) => this.value = value; @@ -25,9 +25,10 @@ public TQuantity Metric() public TQuantity Imperial() where TUnit : IImperialUnit, TDimension => TQuantity.Create(this.value.As>()); public TQuantity NonStandard() where TUnit : INoSystemUnit, TDimension => TQuantity.Create(this.value.As>()); } + public readonly struct LinearCreate : ICompoundFactory - where TDimension : Dimensions.IDimension, ILinear where TQuantity : IFactory + where TDimension : Dimensions.IDimension, ILinear { private readonly Double value; internal LinearCreate(in Double value) => this.value = value; @@ -42,4 +43,4 @@ public TQuantity Metric() public TQuantity Imperial() where TUnit : IImperialUnit, TDimension => TQuantity.Create(this.value.As>()); public TQuantity NonStandard() where TUnit : INoSystemUnit, TDimension => TQuantity.Create(this.value.As>()); -} +} \ No newline at end of file diff --git a/quantities/factories/PowerFactory.cs b/quantities/factories/PowerFactory.cs index 9a1d1ef9..21a24e68 100644 --- a/quantities/factories/PowerFactory.cs +++ b/quantities/factories/PowerFactory.cs @@ -7,23 +7,24 @@ namespace Quantities.Factories; -public readonly struct PowerFactory : ICompoundFactory, ILinearCreate, ILinearInjectCreate - where TCreate : ILinearCreate, ILinearInjectCreate +public readonly struct PowerFactory : ICompoundFactory, ICreate, IInjectCreate + where TCreate : ICreate, IInjectCreate where TLinear : Dimensions.IDimension, ILinear + where TQuantity : IFactory { private readonly TCreate creator; internal PowerFactory(in TCreate value) => this.creator = value; - public TQuantity Si() where TUnit : ISiUnit, TLinear => this.creator.Create>(); + public TQuantity Si() where TUnit : ISiUnit, TLinear => TQuantity.Create(this.creator.Create>()); public TQuantity Si() where TPrefix : IMetricPrefix - where TUnit : ISiUnit, TLinear => this.creator.Create>(); - public TQuantity Metric() where TUnit : IMetricUnit, TLinear => this.creator.Create>(); + where TUnit : ISiUnit, TLinear => TQuantity.Create(this.creator.Create>()); + public TQuantity Metric() where TUnit : IMetricUnit, TLinear => TQuantity.Create(this.creator.Create>()); public TQuantity Metric() where TPrefix : IMetricPrefix - where TUnit : IMetricUnit, TLinear => this.creator.Create>(); - public TQuantity Imperial() where TUnit : IImperialUnit, TLinear => this.creator.Create>(); - public TQuantity NonStandard() where TUnit : INoSystemUnit, TLinear => this.creator.Create>(); - TQuantity ILinearCreate.Create() => this.creator.Create(); - TQuantity ILinearInjectCreate.Create() => this.creator.Create(); + where TUnit : IMetricUnit, TLinear => TQuantity.Create(this.creator.Create>()); + public TQuantity Imperial() where TUnit : IImperialUnit, TLinear => TQuantity.Create(this.creator.Create>()); + public TQuantity NonStandard() where TUnit : INoSystemUnit, TLinear => TQuantity.Create(this.creator.Create>()); + Quant ICreate.Create() => this.creator.Create(); + Quant IInjectCreate.Create() => this.creator.Create(); } diff --git a/quantities/factories/SiFactories.cs b/quantities/factories/SiFactory.cs similarity index 99% rename from quantities/factories/SiFactories.cs rename to quantities/factories/SiFactory.cs index fc53d181..4beaecde 100644 --- a/quantities/factories/SiFactories.cs +++ b/quantities/factories/SiFactory.cs @@ -16,6 +16,7 @@ public TQuantity Si() where TPrefix : IMetricPrefix where TUnit : ISiUnit, TDimension => TQuantity.Create(this.value.As>()); } + public readonly struct SiCreate : ISiFactory where TDimension : Dimensions.IDimension, ILinear where TQuantity : IFactory diff --git a/quantities/factories/SquareCreate.cs b/quantities/factories/SquareCreate.cs index bca86867..fdd96492 100644 --- a/quantities/factories/SquareCreate.cs +++ b/quantities/factories/SquareCreate.cs @@ -2,20 +2,18 @@ namespace Quantities.Factories; -public readonly struct SquareTo : ILinearCreate, ILinearInjectCreate - where TQuantity : IFactory +public readonly struct SquareTo : ICreate, IInjectCreate { private readonly Quant value; internal SquareTo(in Quant value) => this.value = value; - TQuantity ILinearCreate.Create() => TQuantity.Create(this.value.To()); - TQuantity ILinearInjectCreate.Create() => TQuantity.Create(this.value.As()); + Quant ICreate.Create() => this.value.To(); + Quant IInjectCreate.Create() => this.value.As(); } -public readonly struct SquareCreate : ILinearCreate, ILinearInjectCreate - where TQuantity : IFactory +public readonly struct SquareCreate : ICreate, IInjectCreate { private readonly Double value; internal SquareCreate(in Double value) => this.value = value; - TQuantity ILinearCreate.Create() => TQuantity.Create(this.value.To()); - TQuantity ILinearInjectCreate.Create() => TQuantity.Create(this.value.As()); + Quant ICreate.Create() => this.value.To(); + Quant IInjectCreate.Create() => this.value.As(); } diff --git a/quantities/factories/SquareFactory.cs b/quantities/factories/SquareFactory.cs index 301009fa..fd3f066e 100644 --- a/quantities/factories/SquareFactory.cs +++ b/quantities/factories/SquareFactory.cs @@ -11,7 +11,7 @@ namespace Quantities.Factories; public readonly struct SquareFactory : ISquareFactory where TLinear : Dimensions.IDimension, ILinear where TSquare : Dimensions.IDimension - where TCompound : ICompoundFactory, ILinearInjectCreate + where TCompound : ICompoundFactory, IInjectCreate where TQuantity : IFactory { private readonly TCompound squareFactory; @@ -19,20 +19,20 @@ namespace Quantities.Factories; internal SquareFactory(in TCompound compound) => this.squareFactory = compound; public TQuantity Metric() where TUnit : IMetricUnit, TSquare, IInjectUnit { - return this.squareFactory.Create, Alias>(); + return TQuantity.Create(this.squareFactory.Create, Alias>()); } public TQuantity Metric() where TPrefix : IMetricPrefix where TUnit : IMetricUnit, TSquare, IInjectUnit { - return this.squareFactory.Create, Alias>(); + return TQuantity.Create(this.squareFactory.Create, Alias>()); } public TQuantity Imperial() where TUnit : IImperialUnit, TSquare, IInjectUnit { - return this.squareFactory.Create, Alias>(); + return TQuantity.Create(this.squareFactory.Create, Alias>()); } public TQuantity NonStandard() where TUnit : INoSystemUnit, TSquare, IInjectUnit { - return this.squareFactory.Create, Alias>(); + return TQuantity.Create(this.squareFactory.Create, Alias>()); } } diff --git a/quantities/measures/ICreate.cs b/quantities/measures/ICreate.cs index d132a593..a449faf6 100644 --- a/quantities/measures/ICreate.cs +++ b/quantities/measures/ICreate.cs @@ -7,14 +7,14 @@ internal interface ICreate TResult Create(in Double value) where TMeasure : IMeasure; } -public interface ILinearCreate +public interface ICreate { - internal TResult Create() + internal Quant Create() where TMeasure : IMeasure, ILinear; } -public interface ILinearInjectCreate +public interface IInjectCreate { - internal TResult Create() + internal Quant Create() where TMeasure : IMeasure, ILinear where TAlias : IInjector, new(); } \ No newline at end of file diff --git a/quantities/quantities/Area.cs b/quantities/quantities/Area.cs index 238de904..f5f39de9 100644 --- a/quantities/quantities/Area.cs +++ b/quantities/quantities/Area.cs @@ -8,7 +8,7 @@ namespace Quantities.Quantities; public readonly struct Area : IQuantity, IArea , IFactory - , IFactory, ILength>, IArea, ILength>, SquareFactory, ILength>, IArea, ILength>> + , IFactory, IArea, ILength>, SquareFactory, IArea, ILength>> , IMultiplyOperators , IDivisionOperators { @@ -16,9 +16,9 @@ namespace Quantities.Quantities; private static readonly ICreate linear = new ToLinear(); private readonly Quant quant; internal Quant Quant => this.quant; - public SquareFactory, ILength>, IArea, ILength> To => new(new PowerFactory, ILength>(new SquareTo(in this.quant))); + public SquareFactory, IArea, ILength> To => new(new PowerFactory(new SquareTo(in this.quant))); private Area(in Quant quant) => this.quant = quant; - public static SquareFactory, ILength>, IArea, ILength> Of(in Double value) => new(new PowerFactory, ILength>(new SquareCreate(in value))); + public static SquareFactory, IArea, ILength> Of(in Double value) => new(new PowerFactory(new SquareCreate(in value))); static Area IFactory.Create(in Quant quant) => new(in quant); internal static Area From(in Length left, in Length right) { From dd7d8b742b2e127976b524fe921bb89afe667253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=A4gi?= Date: Sat, 6 May 2023 11:06:56 +0200 Subject: [PATCH 13/30] Complete remaining trivial To & Of conversions. --- quantities.benchmark/DividingQuantities.cs | 8 +- quantities.benchmark/MultiplyingQuantities.cs | 4 +- quantities.test/AreaTest.cs | 6 +- quantities.test/DataRateTest.cs | 2 +- quantities.test/DataTest.cs | 2 +- quantities.test/ElectricCurrentTest.cs | 18 ++-- quantities.test/ElectricPotentialTest.cs | 16 ++-- quantities.test/ElectricalResistanceTest.cs | 14 +-- quantities.test/EnergyTest.cs | 2 +- quantities.test/LengthTest.cs | 10 +-- quantities.test/PowerTest.cs | 12 +-- quantities.test/TimeTest.cs | 38 ++++----- quantities.test/VelocityTest.cs | 6 +- quantities.test/VolumeTest.cs | 68 +++++++-------- quantities/dimensions/IDimension.cs | 6 +- quantities/factories/CubicCreate.cs | 19 +++++ quantities/factories/CubicFactory.cs | 39 +++++++++ quantities/factories/IHighDimFactory.cs | 19 +++-- quantities/factories/SquareCreate.cs | 5 +- quantities/factories/SquareFactory.cs | 5 +- quantities/quantities/Area.cs | 2 +- quantities/quantities/ElectricCurrent.cs | 29 ++----- quantities/quantities/ElectricPotential.cs | 2 +- quantities/quantities/ElectricalResistance.cs | 31 ++----- quantities/quantities/Time.cs | 36 ++------ quantities/quantities/Volume.cs | 85 ++----------------- 26 files changed, 216 insertions(+), 268 deletions(-) create mode 100644 quantities/factories/CubicCreate.cs create mode 100644 quantities/factories/CubicFactory.cs diff --git a/quantities.benchmark/DividingQuantities.cs b/quantities.benchmark/DividingQuantities.cs index 7fae079c..b2b87d04 100644 --- a/quantities.benchmark/DividingQuantities.cs +++ b/quantities.benchmark/DividingQuantities.cs @@ -14,14 +14,14 @@ namespace Quantities.Benchmark; [MemoryDiagnoser] public class DividingQuantities { - private Volume metricVolume = Volume.Cubic(3); - private Volume metricAcceptedVolume = Volume.Metric(3); + private Volume metricVolume = Volume.Of(3).Cubic.Si(); + private Volume metricAcceptedVolume = Volume.Of(3).Metric(); private Area metricArea = Area.Of(23).Square.Si(); private Area imperialPureArea = Area.Of(23).Imperial(); - private Volume imperialVolume = Volume.CubicImperial(-3); + private Volume imperialVolume = Volume.Of(-3).Cubic.Imperial(); private Area imperialArea = Area.Of(55).Square.Imperial(); private ElectricPotential potential = ElectricPotential.Of(33).Si(); - private ElectricCurrent current = ElectricCurrent.Si(98); + private ElectricCurrent current = ElectricCurrent.Of(98).Si(); private Trivial largeTrivial = Trivial.Si(Prefix.Kilo, 3); private Trivial smallTrivial = Trivial.Si(Prefix.Micro, 12); diff --git a/quantities.benchmark/MultiplyingQuantities.cs b/quantities.benchmark/MultiplyingQuantities.cs index 3c4e1a17..3cdc483a 100644 --- a/quantities.benchmark/MultiplyingQuantities.cs +++ b/quantities.benchmark/MultiplyingQuantities.cs @@ -16,8 +16,8 @@ public class MultiplyingQuantities private Length smallMetric = Length.Of(23).Si(); private Length largeImperial = Length.Of(-3).Imperial(); private Length smallImperial = Length.Of(55).Imperial(); - private ElectricCurrent current = ElectricCurrent.Si(200); - private ElectricalResistance resistance = ElectricalResistance.Si(734); + private ElectricCurrent current = ElectricCurrent.Of(200).Si(); + private ElectricalResistance resistance = ElectricalResistance.Of(734).Si(); private Trivial largeTrivial = Trivial.Si(Prefix.Kilo, 3); private Trivial smallTrivial = Trivial.Si(Prefix.Micro, 12); diff --git a/quantities.test/AreaTest.cs b/quantities.test/AreaTest.cs index 4773705e..2ded12db 100644 --- a/quantities.test/AreaTest.cs +++ b/quantities.test/AreaTest.cs @@ -99,7 +99,7 @@ public void SquareMetersTimesMetres() { Area area = Area.Of(27).Square.Si(); Length length = Length.Of(30).Si(); - Volume expected = Volume.Cubic(81); + Volume expected = Volume.Of(81).Cubic.Si(); Volume actual = area * length; @@ -110,7 +110,7 @@ public void SquareFeetTimesYards() { Area area = Area.Of(27).Square.Imperial(); Length length = Length.Of(2).Imperial(); - Volume expected = Volume.CubicImperial(162); + Volume expected = Volume.Of(162).Cubic.Imperial(); Volume actual = area * length; @@ -152,7 +152,7 @@ public void AreTimesMeterIsCubicMetre() { Area area = Area.Of(1).Metric(); Length length = Length.Of(10).Si(); - Volume expected = Volume.Cubic(10 * 10 * 10); + Volume expected = Volume.Of(10 * 10 * 10).Cubic.Si(); Volume actual = area * length; diff --git a/quantities.test/DataRateTest.cs b/quantities.test/DataRateTest.cs index 72e7e751..3b458f57 100644 --- a/quantities.test/DataRateTest.cs +++ b/quantities.test/DataRateTest.cs @@ -101,7 +101,7 @@ public void KiloBytePerSecondToKiloBitPerSecond() [Fact] public void DataDividedByTimeIsDataRate() { - Time time = Time.Si(12); + Time time = Time.Of(12).Si(); Data data = Data.In(24); DataRate expected = DataRate.In(24 / 12).Per(); diff --git a/quantities.test/DataTest.cs b/quantities.test/DataTest.cs index 903362fd..6ac108f3 100644 --- a/quantities.test/DataTest.cs +++ b/quantities.test/DataTest.cs @@ -79,7 +79,7 @@ public void GigaByteToGibiByte() [Fact] public void DataRateTimesTimeIsAmountOfData() { - Time time = Time.Si(12); + Time time = Time.Of(12).Si(); DataRate rate = DataRate.In(32).PerSecond(); // Note that the units aren't preserved yet... Data expected = Data.In(12 * 32 / (8 * 1e3) * 1e6 / kibi); diff --git a/quantities.test/ElectricCurrentTest.cs b/quantities.test/ElectricCurrentTest.cs index 6701ce6b..046220f4 100644 --- a/quantities.test/ElectricCurrentTest.cs +++ b/quantities.test/ElectricCurrentTest.cs @@ -5,17 +5,17 @@ namespace Quantities.Test; public sealed class ElectricCurrentTest { [Fact] - public void AmpereToString() => FormattingMatches(v => ElectricCurrent.Si(v), "A"); + public void AmpereToString() => FormattingMatches(v => ElectricCurrent.Of(v).Si(), "A"); [Fact] - public void KiloAmpereToString() => FormattingMatches(v => ElectricCurrent.Si(v), "KA"); + public void KiloAmpereToString() => FormattingMatches(v => ElectricCurrent.Of(v).Si(), "KA"); [Fact] - public void MicroAmpereToString() => FormattingMatches(v => ElectricCurrent.Si(v), "μA"); + public void MicroAmpereToString() => FormattingMatches(v => ElectricCurrent.Of(v).Si(), "μA"); [Fact] public void OhmsLawInBaseUnits() { ElectricPotential volts = ElectricPotential.Of(12).Si(); - ElectricalResistance ohm = ElectricalResistance.Si(3); - ElectricCurrent expected = ElectricCurrent.Si(4); + ElectricalResistance ohm = ElectricalResistance.Of(3).Si(); + ElectricCurrent expected = ElectricCurrent.Of(4).Si(); ElectricCurrent current = volts / ohm; @@ -25,8 +25,8 @@ public void OhmsLawInBaseUnits() public void OhmsLawInPrefixedUnits() { ElectricPotential volts = ElectricPotential.Of(12).Si(); - ElectricalResistance ohm = ElectricalResistance.Si(3); - ElectricCurrent expected = ElectricCurrent.Si(4); + ElectricalResistance ohm = ElectricalResistance.Of(3).Si(); + ElectricCurrent expected = ElectricCurrent.Of(4).Si(); ElectricCurrent current = volts / ohm; @@ -37,7 +37,7 @@ public void PowerLawInBaseUnits() { Power watts = Power.Si(1380); ElectricPotential volts = ElectricPotential.Of(230).Si(); - ElectricCurrent expected = ElectricCurrent.Si(6); + ElectricCurrent expected = ElectricCurrent.Of(6).Si(); ElectricCurrent current = watts / volts; @@ -48,7 +48,7 @@ public void PowerLawInPrefixedUnits() { Power watts = Power.Si(9); ElectricPotential volts = ElectricPotential.Of(15).Si(); - ElectricCurrent expected = ElectricCurrent.Si(600); + ElectricCurrent expected = ElectricCurrent.Of(600).Si(); ElectricCurrent current = watts / volts; diff --git a/quantities.test/ElectricPotentialTest.cs b/quantities.test/ElectricPotentialTest.cs index 946709e7..57040108 100644 --- a/quantities.test/ElectricPotentialTest.cs +++ b/quantities.test/ElectricPotentialTest.cs @@ -13,8 +13,8 @@ public sealed class ElectricPotentialTest [Fact] public void OhmsLawInBaseUnits() { - ElectricalResistance ohm = ElectricalResistance.Si(7); - ElectricCurrent ampere = ElectricCurrent.Si(3); + ElectricalResistance ohm = ElectricalResistance.Of(7).Si(); + ElectricCurrent ampere = ElectricCurrent.Of(3).Si(); ElectricPotential expected = ElectricPotential.Of(21).Si(); ElectricPotential potential = ohm * ampere; @@ -24,8 +24,8 @@ public void OhmsLawInBaseUnits() [Fact] public void OhmsLawInPrefixedUnits() { - ElectricalResistance ohm = ElectricalResistance.Si(7); - ElectricCurrent ampere = ElectricCurrent.Si(3); + ElectricalResistance ohm = ElectricalResistance.Of(7).Si(); + ElectricCurrent ampere = ElectricCurrent.Of(3).Si(); ElectricPotential expected = ElectricPotential.Of(21).Si(); ElectricPotential potential = ohm * ampere; @@ -35,8 +35,8 @@ public void OhmsLawInPrefixedUnits() [Fact] public void OhmsLawInPrefixedUnitsWithInBetweenVirtualPrefix() { - ElectricalResistance ohm = ElectricalResistance.Si(7); - ElectricCurrent ampere = ElectricCurrent.Si(3); + ElectricalResistance ohm = ElectricalResistance.Of(7).Si(); + ElectricCurrent ampere = ElectricCurrent.Of(3).Si(); // 7e1Ω * 3e3A = 21e4V, since e4 is no prefix: expect 210e3 V ElectricPotential expected = ElectricPotential.Of(210).Si(); @@ -49,7 +49,7 @@ public void OhmsLawInPrefixedUnitsWithInBetweenVirtualPrefix() public void PowerLawInBaseUnits() { Power watts = Power.Si(1380); - ElectricCurrent ampere = ElectricCurrent.Si(6); + ElectricCurrent ampere = ElectricCurrent.Of(6).Si(); ElectricPotential expected = ElectricPotential.Of(230).Si(); ElectricPotential potential = watts / ampere; @@ -61,7 +61,7 @@ public void PowerLawInPrefixedUnits() { Power watts = Power.Si(9); _ = ElectricPotential.Of(15).Si(); - ElectricCurrent ampere = ElectricCurrent.Si(600); + ElectricCurrent ampere = ElectricCurrent.Of(600).Si(); // ToDo: Implement rounding based on value! ElectricPotential expected = ElectricPotential.Of(15).Si(); diff --git a/quantities.test/ElectricalResistanceTest.cs b/quantities.test/ElectricalResistanceTest.cs index 182c8967..473ce33f 100644 --- a/quantities.test/ElectricalResistanceTest.cs +++ b/quantities.test/ElectricalResistanceTest.cs @@ -5,17 +5,17 @@ namespace Quantities.Test; public sealed class ElectricalResistanceTest { [Fact] - public void OhmToString() => FormattingMatches(v => ElectricalResistance.Si(v), "Ω"); + public void OhmToString() => FormattingMatches(v => ElectricalResistance.Of(v).Si(), "Ω"); [Fact] - public void KiloOhmToString() => FormattingMatches(v => ElectricalResistance.Si(v), "KΩ"); + public void KiloOhmToString() => FormattingMatches(v => ElectricalResistance.Of(v).Si(), "KΩ"); [Fact] - public void MilliOhmToString() => FormattingMatches(v => ElectricalResistance.Si(v), "mΩ"); + public void MilliOhmToString() => FormattingMatches(v => ElectricalResistance.Of(v).Si(), "mΩ"); [Fact] public void OhmsLawInBaseUnits() { ElectricPotential volts = ElectricPotential.Of(12).Si(); - ElectricCurrent ampere = ElectricCurrent.Si(3); - ElectricalResistance expected = ElectricalResistance.Si(4); + ElectricCurrent ampere = ElectricCurrent.Of(3).Si(); + ElectricalResistance expected = ElectricalResistance.Of(4).Si(); ElectricalResistance resistance = volts / ampere; @@ -25,8 +25,8 @@ public void OhmsLawInBaseUnits() public void OhmsLawInPrefixedUnits() { ElectricPotential volts = ElectricPotential.Of(12).Si(); - ElectricCurrent ampere = ElectricCurrent.Si(3); - ElectricalResistance expected = ElectricalResistance.Si(4); + ElectricCurrent ampere = ElectricCurrent.Of(3).Si(); + ElectricalResistance expected = ElectricalResistance.Of(4).Si(); ElectricalResistance resistance = volts / ampere; diff --git a/quantities.test/EnergyTest.cs b/quantities.test/EnergyTest.cs index 58296559..34bd6b43 100644 --- a/quantities.test/EnergyTest.cs +++ b/quantities.test/EnergyTest.cs @@ -48,7 +48,7 @@ public void DefinitionOfKiloWattHour() [Fact] public void EnergyFromMultiplicationEqualsDirectCreation() { - var time = Time.In(2); + var time = Time.Of(2).Metric(); var power = Power.Si(3); var expected = Energy.Metric(6); diff --git a/quantities.test/LengthTest.cs b/quantities.test/LengthTest.cs index 2310f12c..cf77c507 100644 --- a/quantities.test/LengthTest.cs +++ b/quantities.test/LengthTest.cs @@ -138,7 +138,7 @@ public void ImperialLengthByImperialLengthIsImperialArea() [Fact] public void LengthByDivisionIsEqualToLengthByConstruction() { - Volume volume = Volume.Metric(300); + Volume volume = Volume.Of(300).Metric(); Area area = Area.Of(6).Square.Si(); Length expected = Length.Of(5).Si(); @@ -151,7 +151,7 @@ public void LengthByDivisionIsEqualToLengthByConstruction() public void SiLengthBySiTimeIsVelocity() { Length distance = Length.Of(100).Si(); - Time duration = Time.Seconds(20); + Time duration = Time.Of(20).Si(); Velocity expected = Velocity.Si(5).PerSecond(); Velocity actual = distance / duration; @@ -162,7 +162,7 @@ public void SiLengthBySiTimeIsVelocity() public void SiLengthByMetricTimeIsVelocity() { Length distance = Length.Of(120).Si(); - Time duration = Time.In(10); + Time duration = Time.Of(10).Metric(); Velocity expected = Velocity.Si(12).Per(); Velocity actual = distance / duration; @@ -173,7 +173,7 @@ public void SiLengthByMetricTimeIsVelocity() public void ImperialLengthByTimeIsVelocity() { Length distance = Length.Of(70).Imperial(); - Time duration = Time.In(2); + Time duration = Time.Of(2).Metric(); Velocity expected = Velocity.Imperial(35).Per(); Velocity actual = distance / duration; @@ -183,7 +183,7 @@ public void ImperialLengthByTimeIsVelocity() [Fact] public void VelocityTimesTimeIsLength() { - Time duration = Time.In(12); + Time duration = Time.Of(12).Metric(); Velocity velocity = Velocity.Imperial(350).Per(); // Miles are not yet preserved across multiplication... Length expected = Length.Of(350 * 12 * miles_in_kilometre / 60).Si(); diff --git a/quantities.test/PowerTest.cs b/quantities.test/PowerTest.cs index f96f6cd0..6349dc8b 100644 --- a/quantities.test/PowerTest.cs +++ b/quantities.test/PowerTest.cs @@ -15,7 +15,7 @@ public sealed class PowerTest public void PowerLawInBaseUnits() { ElectricPotential volts = ElectricPotential.Of(12).Si(); - ElectricCurrent ampere = ElectricCurrent.Si(3); + ElectricCurrent ampere = ElectricCurrent.Of(3).Si(); Power expected = Power.Si(36); Power power = volts * ampere; @@ -26,7 +26,7 @@ public void PowerLawInBaseUnits() public void OhmsLawInPrefixedUnits() { ElectricPotential volts = ElectricPotential.Of(70).Si(); - ElectricCurrent ampere = ElectricCurrent.Si(300); + ElectricCurrent ampere = ElectricCurrent.Of(300).Si(); Power expected = Power.Si(21); Power power = ampere * volts; @@ -37,7 +37,7 @@ public void OhmsLawInPrefixedUnits() public void OhmsLawSquarePotentialPerResistance() { ElectricPotential volts = ElectricPotential.Of(0.6).Si(); - ElectricalResistance ohm = ElectricalResistance.Si(3); + ElectricalResistance ohm = ElectricalResistance.Of(3).Si(); Power expected = Power.Si(120); Power power = volts * (volts / ohm); @@ -47,8 +47,8 @@ public void OhmsLawSquarePotentialPerResistance() [Fact] public void OhmsLawSquareCurrentTimesResistance() { - ElectricCurrent ampere = ElectricCurrent.Si(8); - ElectricalResistance ohm = ElectricalResistance.Si(2); + ElectricCurrent ampere = ElectricCurrent.Of(8).Si(); + ElectricalResistance ohm = ElectricalResistance.Of(2).Si(); Power expected = Power.Si(128); Power power = ohm * ampere * ampere; @@ -96,7 +96,7 @@ public void ImperialAndMetricHorsePowerUseSameRepresentation() public void PowerFromEnergyDividedByTime() { Energy energy = Energy.Metric(48); - Time time = Time.In(200); + Time time = Time.Of(200).Metric(); Power expected = Power.Si(10); Power actual = energy / time; diff --git a/quantities.test/TimeTest.cs b/quantities.test/TimeTest.cs index 6ceb1fe0..634e2d71 100644 --- a/quantities.test/TimeTest.cs +++ b/quantities.test/TimeTest.cs @@ -8,7 +8,7 @@ public sealed class TimeTest [Fact] public void SecondsToString() { - Time seconds = Time.Seconds(12); + Time seconds = Time.Of(12).Si(); Assert.Equal("12 s", seconds.ToString()); } @@ -16,9 +16,9 @@ public void SecondsToString() [Fact] public void SecondsToMinutes() { - Time seconds = Time.Seconds(12); - Time minutes = seconds.To(); - Time expected = Time.In(12d / 60); + Time seconds = Time.Of(12).Si(); + Time minutes = seconds.To.Metric(); + Time expected = Time.Of(12d / 60).Metric(); minutes.Matches(expected); } @@ -26,9 +26,9 @@ public void SecondsToMinutes() [Fact] public void MinutesToHours() { - Time seconds = Time.In(12); - Time hours = seconds.ToSeconds(); - Time expected = Time.Seconds(12 * 60); + Time seconds = Time.Of(12).Metric(); + Time hours = seconds.To.Si(); + Time expected = Time.Of(12 * 60).Si(); hours.Matches(expected); } @@ -36,9 +36,9 @@ public void MinutesToHours() [Fact] public void SecondsToMicroSeconds() { - Time seconds = Time.Seconds(12); - Time microSeconds = seconds.To(); - Time expected = Time.Si(12d * 1e6); + Time seconds = Time.Of(12).Si(); + Time microSeconds = seconds.To.Si(); + Time expected = Time.Of(12d * 1e6).Si(); microSeconds.Matches(expected); } @@ -46,18 +46,18 @@ public void SecondsToMicroSeconds() [Fact] public void WeekToHours() { - Time weeks = Time.In(2); - Time hours = weeks.To(); - Time expected = Time.In(2 * 7 * 24); + Time weeks = Time.Of(2).Metric(); + Time hours = weeks.To.Metric(); + Time expected = Time.Of(2 * 7 * 24).Metric(); hours.Matches(expected); } [Fact] public void MinuteToMilliSecond() { - Time minutes = Time.In(4); - Time milliSeconds = minutes.To(); - Time expected = Time.Si(4 * 60 * 1e3); + Time minutes = Time.Of(4).Metric(); + Time milliSeconds = minutes.To.Si(); + Time expected = Time.Of(4 * 60 * 1e3).Si(); milliSeconds.Matches(expected); } @@ -65,8 +65,8 @@ public void MinuteToMilliSecond() [Fact] public void PlusWorks() { - Time sum = Time.In(2) + Time.In(72) + Time.Seconds(30); - Time expected = Time.In(2d + 72d / 60 + 30d / 3600); + Time sum = Time.Of(2).Metric() + Time.Of(72).Metric() + Time.Of(30).Si(); + Time expected = Time.Of(2d + 72d / 60 + 30d / 3600).Metric(); sum.Matches(expected); } @@ -76,7 +76,7 @@ public void TimeFromEnergyDividedByPower() { Power power = Power.Si(3); Energy energy = Energy.Si(2.4); - Time expected = Time.Seconds(800); + Time expected = Time.Of(800).Si(); Time actual = energy / power; diff --git a/quantities.test/VelocityTest.cs b/quantities.test/VelocityTest.cs index 2783eeaa..563c9e93 100644 --- a/quantities.test/VelocityTest.cs +++ b/quantities.test/VelocityTest.cs @@ -71,7 +71,7 @@ public void MetresPerSecondToMilesPerHourTo() public void VelocityFromDivisionOfLengthWithTime_SiUnits() { Length length = Length.Of(12).Si(); - Time time = Time.Seconds(2); + Time time = Time.Of(2).Si(); Velocity expected = Velocity.Si(6).PerSecond(); Velocity actual = length / time; @@ -82,7 +82,7 @@ public void VelocityFromDivisionOfLengthWithTime_SiUnits() public void VelocityFromDivisionOfLengthWithTime_ImperialUnits() { Length length = Length.Of(18).Imperial(); - Time time = Time.In(2); + Time time = Time.Of(2).Metric(); Velocity expected = Velocity.Imperial(9).Per(); Velocity actual = length / time; @@ -95,7 +95,7 @@ public void VelocityFromDivisionOfLengthWithTime_ImperialUnits() public void VelocityFromDivision_Equal_DirectVelocity() { Length length = Length.Of(18).Imperial(); - Time time = Time.In(2); + Time time = Time.Of(2).Metric(); Velocity expected = Velocity.Imperial(9).Per(); Velocity actual = length / time; diff --git a/quantities.test/VolumeTest.cs b/quantities.test/VolumeTest.cs index 17a7947c..9369014b 100644 --- a/quantities.test/VolumeTest.cs +++ b/quantities.test/VolumeTest.cs @@ -8,105 +8,105 @@ public sealed class VolumeTest [Fact] public void AddCubicMetres() { - Volume left = Volume.Cubic(20); - Volume right = Volume.Cubic(10); + Volume left = Volume.Of(20).Cubic.Si(); + Volume right = Volume.Of(10).Cubic.Si(); Volume result = left + right; PrecisionIsBounded(30d, result); } [Fact] public void FromSiToLitre() { - Volume si = Volume.Cubic(1); - Volume expected = Volume.Metric(1000); + Volume si = Volume.Of(1).Cubic.Si(); + Volume expected = Volume.Of(1000).Metric(); - Volume actual = si.ToMetric(); + Volume actual = si.To.Metric(); Assert.Equal(expected, actual); } [Fact] public void FromSiToHectoLitre() { - Volume si = Volume.Cubic(1); - Volume expected = Volume.Metric(10); + Volume si = Volume.Of(1).Cubic.Si(); + Volume expected = Volume.Of(10).Metric(); - Volume actual = si.ToMetric(); + Volume actual = si.To.Metric(); Assert.Equal(expected, actual); } [Fact] public void FromMilliLitreToCubicCentimetre() { - Volume litre = Volume.Metric(1); - Volume expected = Volume.Cubic(1); + Volume litre = Volume.Of(1).Metric(); + Volume expected = Volume.Of(1).Cubic.Si(); - Volume actual = litre.ToCubic(); + Volume actual = litre.To.Cubic.Si(); Assert.Equal(expected, actual); } [Fact] public void FromCubicMillimetreToMicroLitre() { - Volume si = Volume.Cubic(5); - Volume expected = Volume.Metric(5); + Volume si = Volume.Of(5).Cubic.Si(); + Volume expected = Volume.Of(5).Metric(); - Volume actual = si.ToMetric(); + Volume actual = si.To.Metric(); Assert.Equal(expected, actual); } [Fact] public void FromLitreToSi() { - Volume litre = Volume.Metric(600); - Volume expected = Volume.Cubic(0.6); + Volume litre = Volume.Of(600).Metric(); + Volume expected = Volume.Of(0.6).Cubic.Si(); - Volume actual = litre.ToCubic(); + Volume actual = litre.To.Cubic.Si(); Assert.Equal(expected, actual); } [Fact] public void FromCubicDeciMetreToLitre() { - Volume si = Volume.Cubic(1); - Volume expected = Volume.Metric(1); + Volume si = Volume.Of(1).Cubic.Si(); + Volume expected = Volume.Of(1).Metric(); - Volume actual = si.ToMetric(); + Volume actual = si.To.Metric(); Assert.Equal(expected, actual); } [Fact] public void FromGallonToLitre() { - Volume si = Volume.Imperial(1); - Volume expected = Volume.Metric(4.54609); + Volume si = Volume.Of(1).Imperial(); + Volume expected = Volume.Of(4.54609).Metric(); - Volume actual = si.ToMetric(); + Volume actual = si.To.Metric(); Assert.Equal(expected, actual); } [Fact] public void FromLitreToPint() { - Volume si = Volume.Metric(0.56826125); - Volume expected = Volume.Imperial(1); + Volume si = Volume.Of(0.56826125).Metric(); + Volume expected = Volume.Of(1).Imperial(); - Volume actual = si.ToImperial(); + Volume actual = si.To.Imperial(); Assert.Equal(expected, actual); } [Fact] public void FromCubicFootToLitre() { - Volume imperial = Volume.CubicImperial(1); - Volume expected = Volume.Metric(28.316846592); + Volume imperial = Volume.Of(1).Cubic.Imperial(); + Volume expected = Volume.Of(28.316846592).Metric(); - Volume actual = imperial.ToMetric(); + Volume actual = imperial.To.Metric(); Assert.Equal(expected, actual); } [Fact] public void FromMillilitreToImperialFluidOunce() { - Volume si = Volume.Metric(2 * 28.4130625); - Volume expected = Volume.Imperial(2); + Volume si = Volume.Of(2 * 28.4130625).Metric(); + Volume expected = Volume.Of(2).Imperial(); - Volume actual = si.ToImperial(); + Volume actual = si.To.Imperial(); Assert.Equal(expected, actual); } [Fact] public void DivideCubicMetreByMetre() { - Volume volume = Volume.Cubic(81); + Volume volume = Volume.Of(81).Cubic.Si(); Length length = Length.Of(3).Si(); Area expected = Area.Of(27).Square.Si(); @@ -117,7 +117,7 @@ public void DivideCubicMetreByMetre() [Fact] public void DividePureVolumeByLength() { - Volume volume = Volume.Metric(300); + Volume volume = Volume.Of(300).Metric(); Length length = Length.Of(5).Si(); Area expected = Area.Of(6).Square.Si(); diff --git a/quantities/dimensions/IDimension.cs b/quantities/dimensions/IDimension.cs index 644c6858..4a1aa66a 100644 --- a/quantities/dimensions/IDimension.cs +++ b/quantities/dimensions/IDimension.cs @@ -4,12 +4,14 @@ public interface IDimension { /* marker interface */ } public interface ILinear { /* marker interface */ } +public interface ISquare { /* marker interface */ } +public interface ICubic { /* marker interface */ } -public interface ISquare : ITimes +public interface ISquare : ITimes, ISquare where TDimension : IDimension { } -public interface ICubic : ITimes, TDimension> +public interface ICubic : ITimes, TDimension>, ICubic where TDimension : IDimension { } diff --git a/quantities/factories/CubicCreate.cs b/quantities/factories/CubicCreate.cs new file mode 100644 index 00000000..009fcc56 --- /dev/null +++ b/quantities/factories/CubicCreate.cs @@ -0,0 +1,19 @@ +using Quantities.Measures; + +namespace Quantities.Factories; + +public readonly struct CubicTo : ICreate, IInjectCreate +{ + private readonly Quant value; + internal CubicTo(in Quant value) => this.value = value; + Quant ICreate.Create() => this.value.To(); + Quant IInjectCreate.Create() => this.value.As(); +} + +public readonly struct CubicCreate : ICreate, IInjectCreate +{ + private readonly Double value; + internal CubicCreate(in Double value) => this.value = value; + Quant ICreate.Create() => this.value.To(); + Quant IInjectCreate.Create() => this.value.As(); +} diff --git a/quantities/factories/CubicFactory.cs b/quantities/factories/CubicFactory.cs new file mode 100644 index 00000000..b83fd921 --- /dev/null +++ b/quantities/factories/CubicFactory.cs @@ -0,0 +1,39 @@ +using Quantities.Dimensions; +using Quantities.Measures; +using Quantities.Prefixes; +using Quantities.Units; +using Quantities.Units.Imperial; +using Quantities.Units.NonStandard; +using Quantities.Units.Si; + +namespace Quantities.Factories; + +public readonly struct CubicFactory : ICubicFactory + where TLinear : Dimensions.IDimension, ILinear + where TCubic : ICubic + where TCompound : ICompoundFactory, IInjectCreate + where TQuantity : IFactory +{ + private readonly TCompound cubicFactory; + public TCompound Cubic => this.cubicFactory; + ICompoundFactory ICubicFactory.Cubic => this.cubicFactory; + internal CubicFactory(in TCompound compound) => this.cubicFactory = compound; + public TQuantity Metric() where TUnit : IMetricUnit, TCubic, IInjectUnit + { + return TQuantity.Create(this.cubicFactory.Create, Alias>()); + } + public TQuantity Metric() + where TPrefix : IMetricPrefix + where TUnit : IMetricUnit, TCubic, IInjectUnit + { + return TQuantity.Create(this.cubicFactory.Create, Alias>()); + } + public TQuantity Imperial() where TUnit : IImperialUnit, TCubic, IInjectUnit + { + return TQuantity.Create(this.cubicFactory.Create, Alias>()); + } + public TQuantity NonStandard() where TUnit : INoSystemUnit, TCubic, IInjectUnit + { + return TQuantity.Create(this.cubicFactory.Create, Alias>()); + } +} diff --git a/quantities/factories/IHighDimFactory.cs b/quantities/factories/IHighDimFactory.cs index d4ad5102..545e96d2 100644 --- a/quantities/factories/IHighDimFactory.cs +++ b/quantities/factories/IHighDimFactory.cs @@ -7,16 +7,23 @@ namespace Quantities.Factories; -public interface ISquareFactory : IHighDimFactory - where TPower : IDimension +public interface ISquareFactory : IHighDimFactory, TLinear> + where TPower : ISquare where TLinear : IDimension, ILinear - where TCompound : ICompoundFactory { - public TCompound Square { get; } + internal ICompoundFactory Square { get; } } -public interface IHighDimFactory : IFactory - where TPower : IDimension +public interface ICubicFactory : IHighDimFactory, TLinear> + where TPower : ICubic + where TLinear : IDimension, ILinear +{ + internal ICompoundFactory Cubic { get; } +} + +public interface IHighDimFactory : IFactory + where TPower : TDim + where TDim : IDimension where TLinear : IDimension, ILinear { public TQuantity Metric() where TUnit : IMetricUnit, TPower, IInjectUnit; diff --git a/quantities/factories/SquareCreate.cs b/quantities/factories/SquareCreate.cs index fdd96492..b1ebb955 100644 --- a/quantities/factories/SquareCreate.cs +++ b/quantities/factories/SquareCreate.cs @@ -1,8 +1,9 @@ +using Quantities.Dimensions; using Quantities.Measures; namespace Quantities.Factories; -public readonly struct SquareTo : ICreate, IInjectCreate +public readonly struct SquareTo : ICreate, IInjectCreate, ISquare { private readonly Quant value; internal SquareTo(in Quant value) => this.value = value; @@ -10,7 +11,7 @@ namespace Quantities.Factories; Quant IInjectCreate.Create() => this.value.As(); } -public readonly struct SquareCreate : ICreate, IInjectCreate +public readonly struct SquareCreate : ICreate, IInjectCreate, ISquare { private readonly Double value; internal SquareCreate(in Double value) => this.value = value; diff --git a/quantities/factories/SquareFactory.cs b/quantities/factories/SquareFactory.cs index fd3f066e..3afef4d4 100644 --- a/quantities/factories/SquareFactory.cs +++ b/quantities/factories/SquareFactory.cs @@ -8,14 +8,15 @@ namespace Quantities.Factories; -public readonly struct SquareFactory : ISquareFactory +public readonly struct SquareFactory : ISquareFactory where TLinear : Dimensions.IDimension, ILinear - where TSquare : Dimensions.IDimension + where TSquare : ISquare where TCompound : ICompoundFactory, IInjectCreate where TQuantity : IFactory { private readonly TCompound squareFactory; public TCompound Square => this.squareFactory; + ICompoundFactory ISquareFactory.Square => this.squareFactory; internal SquareFactory(in TCompound compound) => this.squareFactory = compound; public TQuantity Metric() where TUnit : IMetricUnit, TSquare, IInjectUnit { diff --git a/quantities/quantities/Area.cs b/quantities/quantities/Area.cs index f5f39de9..de8f8c31 100644 --- a/quantities/quantities/Area.cs +++ b/quantities/quantities/Area.cs @@ -8,7 +8,7 @@ namespace Quantities.Quantities; public readonly struct Area : IQuantity, IArea , IFactory - , IFactory, IArea, ILength>, SquareFactory, IArea, ILength>> + , IFactory, ILength>, SquareFactory, IArea, ILength>, SquareFactory, IArea, ILength>> , IMultiplyOperators , IDivisionOperators { diff --git a/quantities/quantities/ElectricCurrent.cs b/quantities/quantities/ElectricCurrent.cs index c7a84b97..2ac36c80 100644 --- a/quantities/quantities/ElectricCurrent.cs +++ b/quantities/quantities/ElectricCurrent.cs @@ -1,5 +1,6 @@ using System.Numerics; using Quantities.Dimensions; +using Quantities.Factories; using Quantities.Measures; using Quantities.Prefixes; using Quantities.Quantities.Roots; @@ -8,36 +9,18 @@ namespace Quantities.Quantities; public readonly struct ElectricCurrent : IQuantity, IElectricCurrent - , ISi + , IFactory + , IFactory, SiTo, SiCreate> , IMultiplyOperators , IMultiplyOperators { private static readonly IRoot root = new UnitRoot(); private readonly Quant quant; internal Quant Quant => this.quant; + public SiTo To => new(in this.quant); private ElectricCurrent(in Quant quant) => this.quant = quant; - public ElectricCurrent To() - where TUnit : ISiUnit, IElectricCurrent - { - return new(this.quant.As>()); - } - public ElectricCurrent To() - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, IElectricCurrent - { - return new(this.quant.As>()); - } - public static ElectricCurrent Si(in Double value) - where TUnit : ISiUnit, IElectricCurrent - { - return new(value.As>()); - } - public static ElectricCurrent Si(in Double value) - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, IElectricCurrent - { - return new(value.As>()); - } + public static SiCreate Of(in Double value) => new(in value); + static ElectricCurrent IFactory.Create(in Quant quant) => new(in quant); public Boolean Equals(ElectricCurrent other) => this.quant.Equals(other.quant); public String ToString(String? format, IFormatProvider? provider) => this.quant.ToString(format, provider); diff --git a/quantities/quantities/ElectricPotential.cs b/quantities/quantities/ElectricPotential.cs index 44be672e..e74b125d 100644 --- a/quantities/quantities/ElectricPotential.cs +++ b/quantities/quantities/ElectricPotential.cs @@ -36,7 +36,7 @@ internal static ElectricPotential From(in ElectricCurrent current, in Electrical internal static ElectricPotential From(in Power power, in ElectricCurrent current) { Double siPower = power.To(); - Double siCurrent = current.To(); + Double siCurrent = current.To.Si(); return new(MetricPrefix.ScaleThree(siPower / siCurrent, root)); } diff --git a/quantities/quantities/ElectricalResistance.cs b/quantities/quantities/ElectricalResistance.cs index e1e41254..d3148135 100644 --- a/quantities/quantities/ElectricalResistance.cs +++ b/quantities/quantities/ElectricalResistance.cs @@ -1,49 +1,32 @@ using System.Numerics; using Quantities.Dimensions; +using Quantities.Factories; using Quantities.Measures; using Quantities.Prefixes; using Quantities.Quantities.Roots; -using Quantities.Units.Si; using Quantities.Units.Si.Derived; namespace Quantities.Quantities; public readonly struct ElectricalResistance : IQuantity, IElectricalResistance - , ISi + , IFactory + , IFactory, SiTo, SiCreate> , IMultiplyOperators { private static readonly IRoot root = new UnitRoot(); private readonly Quant quant; internal Quant Quant => this.quant; + public SiTo To => new(in this.quant); private ElectricalResistance(in Quant quant) => this.quant = quant; - public ElectricalResistance To() - where TUnit : ISiUnit, IElectricalResistance - { - return new(this.quant.As>()); - } - public ElectricalResistance To() - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, IElectricalResistance - { - return new(this.quant.As>()); - } - public static ElectricalResistance Si(in Double value) - where TUnit : ISiUnit, IElectricalResistance - { - return new(value.As>()); - } - public static ElectricalResistance Si(in Double value) - where TPrefix : IMetricPrefix - where TUnit : ISiUnit, IElectricalResistance - { - return new(value.As>()); - } + public static SiCreate Of(in Double value) => new(in value); + static ElectricalResistance IFactory.Create(in Quant quant) => new(in quant); public Boolean Equals(ElectricalResistance other) => this.quant.Equals(other.quant); public override Boolean Equals(Object? obj) => obj is ElectricalResistance resistance && Equals(resistance); public override Int32 GetHashCode() => this.quant.GetHashCode(); public override String ToString() => this.quant.ToString(); public String ToString(String? format, IFormatProvider? provider) => this.quant.ToString(format, provider); + internal static ElectricalResistance From(in ElectricPotential potential, in ElectricCurrent current) { return new(MetricPrefix.ScaleThree(potential.Quant.SiDivide(current.Quant), root)); diff --git a/quantities/quantities/Time.cs b/quantities/quantities/Time.cs index f8a0ceae..5022f89f 100644 --- a/quantities/quantities/Time.cs +++ b/quantities/quantities/Time.cs @@ -1,5 +1,6 @@ using System.Numerics; using Quantities.Dimensions; +using Quantities.Factories; using Quantities.Measures; using Quantities.Prefixes; using Quantities.Quantities.Roots; @@ -8,6 +9,8 @@ namespace Quantities.Quantities; public readonly struct Time : IQuantity