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); } } }