Skip to content

Commit

Permalink
#515 - Area Units
Browse files Browse the repository at this point in the history
  • Loading branch information
sys27 committed Mar 27, 2022
1 parent a6f8b4a commit 289ae36
Show file tree
Hide file tree
Showing 23 changed files with 942 additions and 1 deletion.
4 changes: 4 additions & 0 deletions xFunc.Maths/Analyzers/Analyzer{TResult,TContext}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ public virtual TResult Analyze(Number exp, TContext context)
public virtual TResult Analyze(Angle exp, TContext context)
=> Analyze(exp as IExpression, context);

/// <inheritdoc />
public virtual TResult Analyze(Area exp, TContext context)
=> Analyze(exp as IExpression, context);

/// <inheritdoc />
public virtual TResult Analyze(Power exp, TContext context)
=> Analyze(exp as IExpression, context);
Expand Down
4 changes: 4 additions & 0 deletions xFunc.Maths/Analyzers/Analyzer{TResult}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ public virtual TResult Analyze(Number exp)
public virtual TResult Analyze(Angle exp)
=> Analyze(exp as IExpression);

/// <inheritdoc />
public virtual TResult Analyze(Area exp)
=> Analyze(exp as IExpression);

/// <inheritdoc />
public virtual TResult Analyze(Power exp)
=> Analyze(exp as IExpression);
Expand Down
8 changes: 8 additions & 0 deletions xFunc.Maths/Analyzers/Differentiator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,14 @@ public override IExpression Analyze(Angle exp, DifferentiatorContext context)
return Number.Zero;
}

/// <inheritdoc />
public override IExpression Analyze(Area exp, DifferentiatorContext context)
{
ValidateArguments(exp, context);

return Number.Zero;
}

/// <inheritdoc />
public override IExpression Analyze(Power exp, DifferentiatorContext context)
{
Expand Down
4 changes: 4 additions & 0 deletions xFunc.Maths/Analyzers/Formatters/CommonFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ public virtual string Analyze(Number exp)
public virtual string Analyze(Angle exp)
=> exp.Value.ToString();

/// <inheritdoc />
public virtual string Analyze(Area exp)
=> exp.Value.ToString();

/// <inheritdoc />
public virtual string Analyze(Power exp)
=> exp.Value.ToString();
Expand Down
8 changes: 8 additions & 0 deletions xFunc.Maths/Analyzers/IAnalyzer{TResult,TContext}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,14 @@ public interface IAnalyzer<out TResult, in TContext>
/// <returns>The result of analysis.</returns>
TResult Analyze(Angle exp, TContext context);

/// <summary>
/// Analyzes the specified expression.
/// </summary>
/// <param name="exp">The expression.</param>
/// <param name="context">The context.</param>
/// <returns>The result of analysis.</returns>
TResult Analyze(Area exp, TContext context);

/// <summary>
/// Analyzes the specified expression.
/// </summary>
Expand Down
7 changes: 7 additions & 0 deletions xFunc.Maths/Analyzers/IAnalyzer{TResult}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ public interface IAnalyzer<out TResult>
/// <returns>The result of analysis.</returns>
TResult Analyze(Angle exp);

/// <summary>
/// Analyzes the specified expression.
/// </summary>
/// <param name="exp">The expression.</param>
/// <returns>The result of analysis.</returns>
TResult Analyze(Area exp);

/// <summary>
/// Analyzes the specified expression.
/// </summary>
Expand Down
7 changes: 6 additions & 1 deletion xFunc.Maths/Analyzers/TypeAnalyzers/ResultTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ public enum ResultTypes
/// </summary>
TimeNumber = 1 << 13,

/// <summary>
/// The expression returns a area number.
/// </summary>
AreaNumber = 1 << 14,

/// <summary>
/// The expression returns a number or a complex number.
/// </summary>
Expand All @@ -109,7 +114,7 @@ public enum ResultTypes
/// <summary>
/// The expression returns any type of number.
/// </summary>
Numbers = Number | AngleNumber | PowerNumber | TemperatureNumber | MassNumber | LengthNumber | TimeNumber,
Numbers = Number | AngleNumber | PowerNumber | TemperatureNumber | MassNumber | LengthNumber | TimeNumber | AreaNumber,

/// <summary>
/// The expression returns a number or a angle number or a complex number or a vector.
Expand Down
4 changes: 4 additions & 0 deletions xFunc.Maths/Analyzers/TypeAnalyzers/TypeAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,10 @@ public virtual ResultTypes Analyze(Number exp)
public virtual ResultTypes Analyze(Angle exp)
=> CheckArgument(exp, ResultTypes.AngleNumber);

/// <inheritdoc />
public virtual ResultTypes Analyze(Area exp)
=> CheckArgument(exp, ResultTypes.AreaNumber);

/// <inheritdoc />
public virtual ResultTypes Analyze(Power exp)
=> CheckArgument(exp, ResultTypes.PowerNumber);
Expand Down
29 changes: 29 additions & 0 deletions xFunc.Maths/Expressions/Units/AreaUnits/Area.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) Dmytro Kyshchenko. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace xFunc.Maths.Expressions.Units.AreaUnits;

/// <summary>
/// Represents a length number.
/// </summary>
public class Area : Unit<AreaValue>
{
/// <summary>
/// Initializes a new instance of the <see cref="Area"/> class.
/// </summary>
/// <param name="value">A length value.</param>
public Area(AreaValue value)
: base(value)
{
}

/// <inheritdoc />
protected override TResult AnalyzeInternal<TResult>(IAnalyzer<TResult> analyzer)
=> analyzer.Analyze(this);

/// <inheritdoc />
protected override TResult AnalyzeInternal<TResult, TContext>(
IAnalyzer<TResult, TContext> analyzer,
TContext context)
=> analyzer.Analyze(this, context);
}
157 changes: 157 additions & 0 deletions xFunc.Maths/Expressions/Units/AreaUnits/AreaUnit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// Copyright (c) Dmytro Kyshchenko. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Diagnostics.CodeAnalysis;

namespace xFunc.Maths.Expressions.Units.AreaUnits;

/// <summary>
/// Represents a area unit.
/// </summary>
public class AreaUnit : IEquatable<AreaUnit>
{
/// <summary>
/// The meter (m²) unit.
/// </summary>
public static readonly AreaUnit Meter = new AreaUnit(1.0, "m^2");

/// <summary>
/// The millimeter (mm²) unit.
/// </summary>
public static readonly AreaUnit Millimeter = new AreaUnit(0.000001, "mm^2");

/// <summary>
/// The centimeter (cm²) unit.
/// </summary>
public static readonly AreaUnit Centimeter = new AreaUnit(0.0001, "cm^2");

/// <summary>
/// The kilometer (km²) unit.
/// </summary>
public static readonly AreaUnit Kilometer = new AreaUnit(1000000, "km^2");

/// <summary>
/// The inch (in²) unit.
/// </summary>
public static readonly AreaUnit Inch = new AreaUnit(0.00064516, "in^2");

/// <summary>
/// The foot (ft²) unit.
/// </summary>
public static readonly AreaUnit Foot = new AreaUnit(0.09290304, "ft^2");

/// <summary>
/// The yard (yd²) unit.
/// </summary>
public static readonly AreaUnit Yard = new AreaUnit(0.83612736, "yd^2");

/// <summary>
/// The mile (mi²) unit.
/// </summary>
public static readonly AreaUnit Mile = new AreaUnit(2589988.110336, "mi^2");

/// <summary>
/// The hectare (ha) unit.
/// </summary>
public static readonly AreaUnit Hectare = new AreaUnit(10000.0, "ha");

/// <summary>
/// The acre (ac) unit.
/// </summary>
public static readonly AreaUnit Acre = new AreaUnit(4046.8564224, "ac");

private AreaUnit(double factor, string unitName)
{
Factor = factor;
UnitName = unitName;
}

/// <summary>
/// Determines whether two specified instances of <see cref="AreaValue"/> are equal.
/// </summary>
/// <param name="left">The first object to compare.</param>
/// <param name="right">The second object to compare.</param>
/// <returns><c>true</c> if <paramref name="left"/> is equal to <paramref name="right"/>; otherwise, <c>false</c>.</returns>
public static bool operator ==(AreaUnit left, AreaUnit right)
=> left.Equals(right);

/// <summary>
/// Determines whether two specified instances of <see cref="AreaValue"/> are equal.
/// </summary>
/// <param name="left">The first object to compare.</param>
/// <param name="right">The second object to compare.</param>
/// <returns><c>true</c> if <paramref name="left"/> is equal to <paramref name="right"/>; otherwise, <c>false</c>.</returns>
public static bool operator !=(AreaUnit left, AreaUnit right)
=> !left.Equals(right);

/// <inheritdoc />
public bool Equals(AreaUnit other)
=> Factor.Equals(other.Factor) && UnitName == other.UnitName;

/// <inheritdoc />
public override bool Equals(object? obj)
=> obj is AreaUnit other && Equals(other);

/// <inheritdoc />
[ExcludeFromCodeCoverage]
public override int GetHashCode()
=> HashCode.Combine(Factor, UnitName);

/// <inheritdoc />
public override string ToString()
=> UnitName;

/// <summary>
/// Gets a factor of conversion from this unit to base unit.
/// </summary>
public double Factor { get; }

/// <summary>
/// Gets a short name of the unit.
/// </summary>
public string UnitName { get; }

private static readonly Lazy<IDictionary<string, AreaUnit>> AllUnits
= new Lazy<IDictionary<string, AreaUnit>>(GetUnits);

private static IDictionary<string, AreaUnit> GetUnits()
=> new Dictionary<string, AreaUnit>(StringComparer.InvariantCultureIgnoreCase)
{
{ Meter.UnitName, Meter },
{ Millimeter.UnitName, Millimeter },
{ Centimeter.UnitName, Centimeter },
{ Kilometer.UnitName, Kilometer },
{ Inch.UnitName, Inch },
{ Foot.UnitName, Foot },
{ Yard.UnitName, Yard },
{ Mile.UnitName, Mile },
{ Acre.UnitName, Acre },
{ Hectare.UnitName, Hectare },
};

/// <summary>
/// Gets all available unit names.
/// </summary>
public static IEnumerable<string> Names => AllUnits.Value.Keys;

/// <summary>
/// Gets all available units.
/// </summary>
[ExcludeFromCodeCoverage]
public static IEnumerable<AreaUnit> Units => AllUnits.Value.Values;

/// <summary>
/// Gets a unit by name.
/// </summary>
/// <param name="name">The name of unit.</param>
/// <param name="unit">When this method returns, the value associated with the specified name, if the unit is found; otherwise, the default value for the type of the value parameter. This parameter is passed uninitialized.</param>
/// <returns><c>true</c> if area units contain an unit with the specified <paramref name="name"/>; otherwise, <c>false</c>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="name"/> is <c>null</c>.</exception>
public static bool FromName(string name, out AreaUnit unit)
{
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentNullException(nameof(name));

return AllUnits.Value.TryGetValue(name, out unit);
}
}

0 comments on commit 289ae36

Please sign in to comment.