Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 16 additions & 31 deletions CodeGen/Generators/UnitsNetGen/QuantityGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ namespace UnitsNet
/// </remarks>");

Writer.WLIfText(1, GetObsoleteAttributeOrNull(_quantity));
Writer.WL(@$"
Writer.W(@$"
[DataContract]
[DebuggerTypeProxy(typeof(QuantityDisplay))]
public readonly partial struct {_quantity.Name} :");
public readonly partial struct {_quantity.Name}");
GenerateInterfaceExtensions();

Writer.WL($@"
Expand Down Expand Up @@ -103,62 +103,47 @@ namespace UnitsNet

private void GenerateInterfaceExtensions()
{
// generate the base interface (either IVectorQuantity, IAffineQuantity or ILogarithmicQuantity)
Writer.W($" : IQuantity<{_quantity.Name}, {_unitEnumName}>, ");

// generate ILogarithmicQuantity, IAffineQuantity or ILinearQuantity
if (_quantity.Logarithmic)
{
Writer.WL(@$"
ILogarithmicQuantity<{_quantity.Name}, {_unitEnumName}>,");
Writer.WL($"ILogarithmicQuantity<{_quantity.Name}>");
}
else if (!string.IsNullOrEmpty(_quantity.AffineOffsetType))
{
Writer.WL(@$"
IAffineQuantity<{_quantity.Name}, {_unitEnumName}, {_quantity.AffineOffsetType}>,");
Writer.WL($"IAffineQuantity<{_quantity.Name}, {_quantity.AffineOffsetType}>");
}
else // the default quantity type implements the IVectorQuantity interface
else // the default quantity type implements the ILinearQuantity interface
{
Writer.WL(@$"
IArithmeticQuantity<{_quantity.Name}, {_unitEnumName}>,");
}

Writer.WL(@"
#if NET7_0_OR_GREATER");
if (!_quantity.IsAffine)
{
Writer.WL($@"
IDivisionOperators<{_quantity.Name}, {_quantity.Name}, double>,");
Writer.WL($"ILinearQuantity<{_quantity.Name}>");
}

if (_quantity.Relations.Any(r => r.Operator is "*" or "/"))
{
Writer.WL(@"
#if NET7_0_OR_GREATER");
foreach (QuantityRelation relation in _quantity.Relations)
{
if (relation.LeftQuantity != _quantity) continue;
switch (relation.Operator)
{
case "*":
Writer.W(@"
IMultiplyOperators");
, IMultiplyOperators");
break;
case "/":
Writer.W(@"
IDivisionOperators");
, IDivisionOperators");
break;
default:
continue;
}

Writer.WL($"<{relation.LeftQuantity.Name}, {relation.RightQuantity.Name}, {relation.ResultQuantity.Name}>,");
Writer.WL($"<{relation.LeftQuantity.Name}, {relation.RightQuantity.Name}, {relation.ResultQuantity.Name}>");
}
Writer.WL(@$"
#endif");
}

Writer.WL(@$"
IComparisonOperators<{_quantity.Name}, {_quantity.Name}, bool>,
IParsable<{_quantity.Name}>,
#endif
IComparable,
IComparable<{_quantity.Name}>,
IEquatable<{_quantity.Name}>,
IFormattable");
}

private void GenerateQuantityInfo()
Expand Down
113 changes: 113 additions & 0 deletions UnitsNet.Tests/CustomQuantities/HowMuch.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
using UnitsNet.Units;

namespace UnitsNet.Tests.CustomQuantities
Expand Down Expand Up @@ -100,6 +101,118 @@ QuantityInfo IQuantity.QuantityInfo

Enum IQuantity.Unit => Unit;
#endif

#endregion


#region Equality / IComparable

/// <summary>Returns true if less or equal to.</summary>
public static bool operator <=(HowMuch left, HowMuch right)
{
return left.Value <= right.ToUnit(left.Unit).Value;
}

/// <summary>Returns true if greater than or equal to.</summary>
public static bool operator >=(HowMuch left, HowMuch right)
{
return left.Value >= right.ToUnit(left.Unit).Value;
}

/// <summary>Returns true if less than.</summary>
public static bool operator <(HowMuch left, HowMuch right)
{
return left.Value < right.ToUnit(left.Unit).Value;
}

/// <summary>Returns true if greater than.</summary>
public static bool operator >(HowMuch left, HowMuch right)
{
return left.Value > right.ToUnit(left.Unit).Value;
}

// We use obsolete attribute to communicate the preferred equality members to use.
// CS0809: Obsolete member 'memberA' overrides non-obsolete member 'memberB'.
#pragma warning disable CS0809

/// <summary>Indicates strict equality of two <see cref="HowMuch"/> quantities, where both <see cref="Value" /> and <see cref="Unit" /> are exactly equal.</summary>
[Obsolete(
"For null checks, use `x is null` syntax to not invoke overloads. For equality checks, use Equals(HowMuch other, HowMuch tolerance) instead, to check equality across units and to specify the max tolerance for rounding errors due to floating-point arithmetic when converting between units.")]
public static bool operator ==(HowMuch left, HowMuch right)
{
return left.Equals(right);
}

/// <summary>Indicates strict inequality of two <see cref="HowMuch"/> quantities, where both <see cref="Value" /> and <see cref="Unit" /> are exactly equal.</summary>
[Obsolete(
"For null checks, use `x is null` syntax to not invoke overloads. For equality checks, use Equals(HowMuch other, HowMuch tolerance) instead, to check equality across units and to specify the max tolerance for rounding errors due to floating-point arithmetic when converting between units.")]
public static bool operator !=(HowMuch left, HowMuch right)
{
return !(left == right);
}

/// <inheritdoc />
/// <summary>Indicates strict equality of two <see cref="HowMuch"/> quantities, where both <see cref="Value" /> and <see cref="Unit" /> are exactly equal.</summary>
[Obsolete(
"Use Equals(HowMuch other, HowMuch tolerance) instead, to check equality across units and to specify the max tolerance for rounding errors due to floating-point arithmetic when converting between units.")]
public override bool Equals(object? obj)
{
if (obj is null || !(obj is HowMuch otherQuantity))
return false;

return Equals(otherQuantity);
}

/// <inheritdoc />
/// <summary>Indicates strict equality of two <see cref="HowMuch"/> quantities, where both <see cref="Value" /> and <see cref="Unit" /> are exactly equal.</summary>
[Obsolete(
"Use Equals(HowMuch other, HowMuch tolerance) instead, to check equality across units and to specify the max tolerance for rounding errors due to floating-point arithmetic when converting between units.")]
public bool Equals(HowMuch other)
{
return new { Value, Unit }.Equals(new { other.Value, other.Unit });
}

#pragma warning restore CS0809

public override int GetHashCode()
{
return Comparison.GetHashCode(Unit, Value);
}

public int CompareTo(object? obj)
{
if (obj is null) throw new ArgumentNullException(nameof(obj));
if (!(obj is HowMuch otherQuantity)) throw new ArgumentException("Expected type HowMuch.", nameof(obj));

return CompareTo(otherQuantity);
}

public int CompareTo(HowMuch other)
{
return Value.CompareTo(other.ToUnit(Unit).Value);
}

#endregion

#region IParsable

public static HowMuch Parse(string str, IFormatProvider? provider)
{
return UnitsNetSetup.Default.QuantityParser.Parse<HowMuch, HowMuchUnit>(
str,
provider,
From);
}

public static bool TryParse([NotNullWhen(true)] string? str, IFormatProvider? provider, out HowMuch result)
{
return UnitsNetSetup.Default.QuantityParser.TryParse<HowMuch, HowMuchUnit>(
str,
provider,
From,
out result);
}

#endregion
}
}
12 changes: 6 additions & 6 deletions UnitsNet/Extensions/LogarithmicQuantityExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public static TQuantity Sum<TSource, TQuantity>(this IEnumerable<TSource> source
/// logarithmic space.
/// </remarks>
public static TQuantity Sum<TQuantity, TUnit>(this IEnumerable<TQuantity> quantities, TUnit targetUnit)
where TQuantity : ILogarithmicQuantity<TQuantity, TUnit>
where TQuantity : ILogarithmicQuantity<TQuantity>, IQuantity<TQuantity, TUnit>
where TUnit : struct, Enum
{
if (quantities is null)
Expand Down Expand Up @@ -224,7 +224,7 @@ public static TQuantity Sum<TQuantity, TUnit>(this IEnumerable<TQuantity> quanti
/// logarithmic space.
/// </remarks>
public static TQuantity Sum<TSource, TQuantity, TUnit>(this IEnumerable<TSource> source, Func<TSource, TQuantity> selector, TUnit targetUnit)
where TQuantity : ILogarithmicQuantity<TQuantity, TUnit>
where TQuantity : ILogarithmicQuantity<TQuantity>, IQuantity<TQuantity, TUnit>
where TUnit : struct, Enum
{
return source.Select(selector).Sum(targetUnit);
Expand Down Expand Up @@ -312,7 +312,7 @@ public static TQuantity ArithmeticMean<TSource, TQuantity>(this IEnumerable<TSou
/// averaged, and then the result is converted back to logarithmic space using the same unit.
/// </remarks>
public static TQuantity ArithmeticMean<TQuantity, TUnit>(this IEnumerable<TQuantity> quantities, TUnit unit)
where TQuantity : ILogarithmicQuantity<TQuantity, TUnit>
where TQuantity : ILogarithmicQuantity<TQuantity>, IQuantity<TQuantity, TUnit>
where TUnit : struct, Enum
{
if (quantities is null)
Expand Down Expand Up @@ -363,7 +363,7 @@ public static TQuantity ArithmeticMean<TQuantity, TUnit>(this IEnumerable<TQuant
/// averaged, and then the result is converted back to logarithmic space using the same unit.
/// </remarks>
public static TQuantity ArithmeticMean<TSource, TQuantity, TUnit>(this IEnumerable<TSource> source, Func<TSource, TQuantity> selector, TUnit targetUnit)
where TQuantity : ILogarithmicQuantity<TQuantity, TUnit>
where TQuantity : ILogarithmicQuantity<TQuantity>, IQuantity<TQuantity, TUnit>
where TUnit : struct, Enum
{
return ArithmeticMean(source.Select(selector), targetUnit);
Expand Down Expand Up @@ -448,7 +448,7 @@ public static TQuantity GeometricMean<TSource, TQuantity>(this IEnumerable<TSour
/// logarithmic quantities is equal to the sum the values, converted in unit of the first element.
/// </remarks>
public static TQuantity GeometricMean<TQuantity, TUnit>(this IEnumerable<TQuantity> quantities, TUnit targetUnit)
where TQuantity : ILogarithmicQuantity<TQuantity, TUnit>
where TQuantity : ILogarithmicQuantity<TQuantity>, IQuantity<TQuantity, TUnit>
where TUnit : struct, Enum
{
if (quantities is null)
Expand Down Expand Up @@ -494,7 +494,7 @@ public static TQuantity GeometricMean<TQuantity, TUnit>(this IEnumerable<TQuanti
/// logarithmic quantities is equal to the sum the values, converted in unit of the first element.
/// </remarks>
public static TQuantity GeometricMean<TSource, TQuantity, TUnit>(this IEnumerable<TSource> source, Func<TSource, TQuantity> selector, TUnit targetUnit)
where TQuantity : ILogarithmicQuantity<TQuantity, TUnit>
where TQuantity : ILogarithmicQuantity<TQuantity>, IQuantity<TQuantity, TUnit>
where TUnit : struct, Enum
{
return source.Select(selector).GeometricMean(targetUnit);
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 6 additions & 14 deletions UnitsNet/GeneratedCode/Quantities/Acceleration.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 7 additions & 15 deletions UnitsNet/GeneratedCode/Quantities/AmountOfSubstance.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 1 addition & 11 deletions UnitsNet/GeneratedCode/Quantities/AmplitudeRatio.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 4 additions & 12 deletions UnitsNet/GeneratedCode/Quantities/Angle.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading