using System;
using Chernobyl.Measures.Length;
using Chernobyl.Measures.Time;
namespace Chernobyl.Measures.Speed
{
///
/// A measurement for speed defined as metres per
/// where is the type of time being used.
///
/// The type to use for measuring time.
public struct Metres
: IMeasurement, IEquatable>, IComparable>
where TTime : ITime
{
///
/// Initializes a new instance of the struct.
///
/// The distance that was traveled in the specified
/// amount of .
/// The amount of time it took to travel the distance
/// specified by .
public Metres(Metres length, TTime time)
: this(length / time.Value)
{}
///
/// Initializes a new instance of the struct.
///
/// The raw value as metres per second in the form
/// of a .
public Metres(double value) : this()
{
Value = value;
}
///
/// Performs an explicit conversion from to
/// .
///
/// The raw value as metres per second in the form
/// of a .
/// The result of the conversion.
public static explicit operator Metres(double value)
{
return new Metres(value);
}
///
/// Performs an implicit conversion from to
/// .
///
/// The value as metres per
/// in the form of a
/// .
/// The result of the conversion.
public static implicit operator double(Metres value)
{
return value.Value;
}
///
/// Adds two .
///
/// The left side of the operation.
/// The right side of the operation.
/// The result of the operation.
public static Metres operator +(Metres left, Metres right)
{
return new Metres(left.Value + right.Value);
}
///
/// Subtracts two .
///
/// The left side of the operation.
/// The right side of the operation.
/// The result of the operation.
public static Metres operator -(Metres left, Metres right)
{
return new Metres(left.Value - right.Value);
}
///
/// Multiplies two .
///
/// The left side of the operation.
/// The right side of the operation.
/// The result of the operation.
public static Metres operator *(Metres left, Metres right)
{
return new Metres(left.Value * right.Value);
}
///
/// Divides two .
///
/// The left side of the operation.
/// The right side of the operation.
/// The result of the operation.
public static Metres operator /(Metres left, Metres right)
{
return new Metres(left.Value / right.Value);
}
///
/// Negates a .
///
/// The item to negate.
/// The result of the operation.
public static Metres operator -(Metres item)
{
return new Metres(-item.Value);
}
///
/// Pluses a .
///
/// The item to plus.
/// The result of the operation.
public static Metres operator +(Metres item)
{
return new Metres(+item.Value);
}
///
/// Checks if two are equal to each other.
///
/// The left side of the operation.
/// The right side of the operation.
/// True if the two are equal, false if otherwise.
public static bool operator ==(Metres left, Metres right)
{
return left.Equals(right);
}
///
/// Checks if two are equal to each other.
///
/// The left side of the operation.
/// The right side of the operation.
/// True if the two are different, false if otherwise.
public static bool operator !=(Metres left, Metres right)
{
return !(left == right);
}
///
/// Checks if one is less than another.
///
/// The left side of the operation.
/// The right side of the operation.
/// True if the first operand is less than the second, false if
/// otherwise.
public static bool operator <(Metres left, Metres right)
{
return left.Value < right.Value;
}
///
/// Checks if one is more than another.
///
/// The left side of the operation.
/// The right side of the operation.
/// True if the first operand is more than the second, false if
/// otherwise.
public static bool operator >(Metres left, Metres right)
{
return left.Value > right.Value;
}
///
/// Checks if one is less than or equal to
/// another.
///
/// The left side of the operation.
/// The right side of the operation.
/// True if the first operand is less than or equal to the
/// second, false if otherwise.
public static bool operator <=(Metres left, Metres right)
{
return left.Value <= right.Value;
}
///
/// Checks if one is more than or equal to
/// another.
///
/// The left side of the operation.
/// The right side of the operation.
/// True if the first operand is more than or equal to the
/// second, false if otherwise.
public static bool operator >=(Metres left, Metres right)
{
return left.Value >= right.Value;
}
///
/// Gets the hash code of the .
///
/// The hash code of the number.
public override int GetHashCode()
{
return Value.GetHashCode();
}
///
/// Indicates whether the current object is equal to another object of
/// the same type.
///
/// An object to compare with this object.
/// True if the current object is equal to the
/// parameter; otherwise, false.
public bool Equals(Metres other)
{
return Value == other.Value;
}
///
/// Checks this for equality with object passed in.
///
/// The object to compare to.
/// True if the object is equal to this ,
/// false if otherwise.
public override bool Equals(object obj)
{
return (obj is Metres && Equals((Metres)obj));
}
///
/// Compares the current object with another object of the same type.
///
/// An object to compare with this object.
/// A 32-bit signed integer that indicates the relative order
/// of the objects being compared. The return value has the following
/// meanings: if the value is less than zero then this object is less
/// than the parameter. If it is zero then
/// this object is equal to . If it is greater
/// than zero then this object is greater than .
///
public int CompareTo(Metres other)
{
return Value.CompareTo(other.Value);
}
///
/// Returns a that represents this instance. For
/// example, 32.0 metres per second will be returned as "32.0 m/s".
///
/// A that represents this instance.
public override string ToString()
{
return Value + " m/s";
}
///
/// The raw value as metres per second in the form of a
/// .
///
public double Value { get; private set; }
}
///
/// A class that holds conversion methods for the
/// type.
///
public static class Conversions
{
///
/// Converts meters per second to metres per milliseconds.
///
/// The speed in metres per second.
/// The speed in the form of metres per millisecond.
public static Metres ToMetersPerMillisecond(this Metres speed)
{
return new Metres((Metres)1, (Seconds)speed.Value);
}
}
}