text: ﻿//------------------------------------------------------------------------------
  // <auto-generated>
  //     This code was generated by \generate-code.bat.
  //
  //     Changes to this file will be lost when the code is regenerated.
  //     The build server regenerates the code before each build and a pre-build
  //     step will regenerate the code on each local build.
  //
  //     See https://github.com/angularsen/UnitsNet/wiki/Adding-a-New-Unit for how to add or edit units.
  //
  //     Add CustomCode\Quantities\MyQuantity.extra.cs files to add code to generated quantities.
  //     Add UnitDefinitions\MyQuantity.json and run generate-code.bat to generate new units or quantities.
  //
  // </auto-generated>
  //------------------------------------------------------------------------------
  
  // Licensed under MIT No Attribution, see LICENSE file at the root.
  // Copyright 2013 Andreas Gullberg Larsen (andreas.larsen84@gmail.com). Maintained at https://github.com/angularsen/UnitsNet.
  
  using System;
  using System.Globalization;
  using System.Linq;
  using JetBrains.Annotations;
  using UnitsNet.InternalHelpers;
  using UnitsNet.Units;
  
  #nullable enable
  
  // ReSharper disable once CheckNamespace
  
  namespace UnitsNet
  {
      /// <inheritdoc />
      /// <summary>
      ///     In everyday use and in kinematics, the speed of an object is the magnitude of its velocity (the rate of change of its position); it is thus a scalar quantity.[1] The average speed of an object in an interval of time is the distance travelled by the object divided by the duration of the interval;[2] the instantaneous speed is the limit of the average speed as the duration of the time interval approaches zero.
      /// </summary>
      public partial struct Speed : IQuantity<SpeedUnit>, IEquatable<Speed>, IComparable, IComparable<Speed>, IConvertible, IFormattable
      {
          /// <summary>
          ///     The numeric value this quantity was constructed with.
          /// </summary>
          private readonly double _value;
  
          /// <summary>
          ///     The unit this quantity was constructed with.
          /// </summary>
          private readonly SpeedUnit? _unit;
  
          static Speed()
          {
              BaseDimensions = new BaseDimensions(1, 0, -1, 0, 0, 0, 0);
  
              Info = new QuantityInfo<SpeedUnit>(QuantityType.Speed,
                  new UnitInfo<SpeedUnit>[] {
                      new UnitInfo<SpeedUnit>(SpeedUnit.CentimeterPerHour, BaseUnits.Undefined),
                      new UnitInfo<SpeedUnit>(SpeedUnit.CentimeterPerMinute, BaseUnits.Undefined),
                      new UnitInfo<SpeedUnit>(SpeedUnit.CentimeterPerSecond, BaseUnits.Undefined),
                      new UnitInfo<SpeedUnit>(SpeedUnit.DecimeterPerMinute, BaseUnits.Undefined),
                      new UnitInfo<SpeedUnit>(SpeedUnit.DecimeterPerSecond, BaseUnits.Undefined),
                      new UnitInfo<SpeedUnit>(SpeedUnit.FootPerHour, new BaseUnits(length: LengthUnit.Foot, time: DurationUnit.Hour)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.FootPerMinute, new BaseUnits(length: LengthUnit.Foot, time: DurationUnit.Minute)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.FootPerSecond, new BaseUnits(length: LengthUnit.Foot, time: DurationUnit.Second)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.InchPerHour, new BaseUnits(length: LengthUnit.Inch, time: DurationUnit.Hour)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.InchPerMinute, new BaseUnits(length: LengthUnit.Inch, time: DurationUnit.Minute)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.InchPerSecond, new BaseUnits(length: LengthUnit.Inch, time: DurationUnit.Second)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.KilometerPerHour, BaseUnits.Undefined),
                      new UnitInfo<SpeedUnit>(SpeedUnit.KilometerPerMinute, BaseUnits.Undefined),
                      new UnitInfo<SpeedUnit>(SpeedUnit.KilometerPerSecond, BaseUnits.Undefined),
                      new UnitInfo<SpeedUnit>(SpeedUnit.Knot, new BaseUnits(length: LengthUnit.NauticalMile, time: DurationUnit.Hour)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.MeterPerHour, new BaseUnits(length: LengthUnit.Meter, time: DurationUnit.Hour)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.MeterPerMinute, new BaseUnits(length: LengthUnit.Meter, time: DurationUnit.Minute)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.MeterPerSecond, new BaseUnits(length: LengthUnit.Meter, time: DurationUnit.Second)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.MicrometerPerMinute, BaseUnits.Undefined),
                      new UnitInfo<SpeedUnit>(SpeedUnit.MicrometerPerSecond, BaseUnits.Undefined),
                      new UnitInfo<SpeedUnit>(SpeedUnit.MilePerHour, new BaseUnits(length: LengthUnit.Mile, time: DurationUnit.Hour)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.MillimeterPerHour, BaseUnits.Undefined),
                      new UnitInfo<SpeedUnit>(SpeedUnit.MillimeterPerMinute, BaseUnits.Undefined),
                      new UnitInfo<SpeedUnit>(SpeedUnit.MillimeterPerSecond, BaseUnits.Undefined),
                      new UnitInfo<SpeedUnit>(SpeedUnit.NanometerPerMinute, BaseUnits.Undefined),
                      new UnitInfo<SpeedUnit>(SpeedUnit.NanometerPerSecond, BaseUnits.Undefined),
                      new UnitInfo<SpeedUnit>(SpeedUnit.UsSurveyFootPerHour, new BaseUnits(length: LengthUnit.UsSurveyFoot, time: DurationUnit.Hour)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.UsSurveyFootPerMinute, new BaseUnits(length: LengthUnit.UsSurveyFoot, time: DurationUnit.Minute)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.UsSurveyFootPerSecond, new BaseUnits(length: LengthUnit.UsSurveyFoot, time: DurationUnit.Second)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.YardPerHour, new BaseUnits(length: LengthUnit.Yard, time: DurationUnit.Hour)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.YardPerMinute, new BaseUnits(length: LengthUnit.Yard, time: DurationUnit.Minute)),
                      new UnitInfo<SpeedUnit>(SpeedUnit.YardPerSecond, new BaseUnits(length: LengthUnit.Yard, time: DurationUnit.Second)),
                  },
                  BaseUnit, Zero, BaseDimensions);
          }
  
          /// <summary>
          ///     Creates the quantity with the given numeric value and unit.
          /// </summary>
          /// <param name="value">The numeric value to construct this quantity with.</param>
          /// <param name="unit">The unit representation to construct this quantity with.</param>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public Speed(double value, SpeedUnit unit)
          {
              if(unit == SpeedUnit.Undefined)
                throw new ArgumentException("The quantity can not be created with an undefined unit.", nameof(unit));
  
              _value = Guard.EnsureValidNumber(value, nameof(value));
              _unit = unit;
          }
  
          /// <summary>
          /// Creates an instance of the quantity with the given numeric value in units compatible with the given <see cref="UnitSystem"/>.
          /// If multiple compatible units were found, the first match is used.
          /// </summary>
          /// <param name="value">The numeric value to construct this quantity with.</param>
          /// <param name="unitSystem">The unit system to create the quantity with.</param>
          /// <exception cref="ArgumentNullException">The given <see cref="UnitSystem"/> is null.</exception>
          /// <exception cref="ArgumentException">No unit was found for the given <see cref="UnitSystem"/>.</exception>
          public Speed(double value, UnitSystem unitSystem)
          {
              if(unitSystem is null) throw new ArgumentNullException(nameof(unitSystem));
  
              var unitInfos = Info.GetUnitInfosFor(unitSystem.BaseUnits);
              var firstUnitInfo = unitInfos.FirstOrDefault();
  
              _value = Guard.EnsureValidNumber(value, nameof(value));
              _unit = firstUnitInfo?.Value ?? throw new ArgumentException("No units were found for the given UnitSystem.", nameof(unitSystem));
          }
  
          #region Static Properties
  
          /// <inheritdoc cref="IQuantity.QuantityInfo"/>
          public static QuantityInfo<SpeedUnit> Info { get; }
  
          /// <summary>
          ///     The <see cref="BaseDimensions" /> of this quantity.
          /// </summary>
          public static BaseDimensions BaseDimensions { get; }
  
          /// <summary>
          ///     The base unit of Speed, which is MeterPerSecond. All conversions go via this value.
          /// </summary>
          public static SpeedUnit BaseUnit { get; } = SpeedUnit.MeterPerSecond;
  
          /// <summary>
          /// Represents the largest possible value of Speed
          /// </summary>
          public static Speed MaxValue { get; } = new Speed(double.MaxValue, BaseUnit);
  
          /// <summary>
          /// Represents the smallest possible value of Speed
          /// </summary>
          public static Speed MinValue { get; } = new Speed(double.MinValue, BaseUnit);
  
          /// <summary>
          ///     The <see cref="QuantityType" /> of this quantity.
          /// </summary>
          public static QuantityType QuantityType { get; } = QuantityType.Speed;
  
          /// <summary>
          ///     All units of measurement for the Speed quantity.
          /// </summary>
          public static SpeedUnit[] Units { get; } = Enum.GetValues(typeof(SpeedUnit)).Cast<SpeedUnit>().Except(new SpeedUnit[]{ SpeedUnit.Undefined }).ToArray();
  
          /// <summary>
          ///     Gets an instance of this quantity with a value of 0 in the base unit MeterPerSecond.
          /// </summary>
          public static Speed Zero { get; } = new Speed(0, BaseUnit);
  
          #endregion
  
          #region Properties
  
          /// <summary>
          ///     The numeric value this quantity was constructed with.
          /// </summary>
          public double Value => _value;
  
          Enum IQuantity.Unit => Unit;
  
          /// <inheritdoc />
          public SpeedUnit Unit => _unit.GetValueOrDefault(BaseUnit);
  
          /// <inheritdoc />
          public QuantityInfo<SpeedUnit> QuantityInfo => Info;
  
          /// <inheritdoc cref="IQuantity.QuantityInfo"/>
          QuantityInfo IQuantity.QuantityInfo => Info;
  
          /// <summary>
          ///     The <see cref="QuantityType" /> of this quantity.
          /// </summary>
          public QuantityType Type => Speed.QuantityType;
  
          /// <summary>
          ///     The <see cref="BaseDimensions" /> of this quantity.
          /// </summary>
          public BaseDimensions Dimensions => Speed.BaseDimensions;
  
          #endregion
  
          #region Conversion Properties
  
          /// <summary>
          ///     Get Speed in CentimetersPerHour.
          /// </summary>
          public double CentimetersPerHour => As(SpeedUnit.CentimeterPerHour);
  
          /// <summary>
          ///     Get Speed in CentimetersPerMinutes.
          /// </summary>
          public double CentimetersPerMinutes => As(SpeedUnit.CentimeterPerMinute);
  
          /// <summary>
          ///     Get Speed in CentimetersPerSecond.
          /// </summary>
          public double CentimetersPerSecond => As(SpeedUnit.CentimeterPerSecond);
  
          /// <summary>
          ///     Get Speed in DecimetersPerMinutes.
          /// </summary>
          public double DecimetersPerMinutes => As(SpeedUnit.DecimeterPerMinute);
  
          /// <summary>
          ///     Get Speed in DecimetersPerSecond.
          /// </summary>
          public double DecimetersPerSecond => As(SpeedUnit.DecimeterPerSecond);
  
          /// <summary>
          ///     Get Speed in FeetPerHour.
          /// </summary>
          public double FeetPerHour => As(SpeedUnit.FootPerHour);
  
          /// <summary>
          ///     Get Speed in FeetPerMinute.
          /// </summary>
          public double FeetPerMinute => As(SpeedUnit.FootPerMinute);
  
          /// <summary>
          ///     Get Speed in FeetPerSecond.
          /// </summary>
          public double FeetPerSecond => As(SpeedUnit.FootPerSecond);
  
          /// <summary>
          ///     Get Speed in InchesPerHour.
          /// </summary>
          public double InchesPerHour => As(SpeedUnit.InchPerHour);
  
          /// <summary>
          ///     Get Speed in InchesPerMinute.
          /// </summary>
          public double InchesPerMinute => As(SpeedUnit.InchPerMinute);
  
          /// <summary>
          ///     Get Speed in InchesPerSecond.
          /// </summary>
          public double InchesPerSecond => As(SpeedUnit.InchPerSecond);
  
          /// <summary>
          ///     Get Speed in KilometersPerHour.
          /// </summary>
          public double KilometersPerHour => As(SpeedUnit.KilometerPerHour);
  
          /// <summary>
          ///     Get Speed in KilometersPerMinutes.
          /// </summary>
          public double KilometersPerMinutes => As(SpeedUnit.KilometerPerMinute);
  
          /// <summary>
          ///     Get Speed in KilometersPerSecond.
          /// </summary>
          public double KilometersPerSecond => As(SpeedUnit.KilometerPerSecond);
  
          /// <summary>
          ///     Get Speed in Knots.
          /// </summary>
          public double Knots => As(SpeedUnit.Knot);
  
          /// <summary>
          ///     Get Speed in MetersPerHour.
          /// </summary>
          public double MetersPerHour => As(SpeedUnit.MeterPerHour);
  
          /// <summary>
          ///     Get Speed in MetersPerMinutes.
          /// </summary>
          public double MetersPerMinutes => As(SpeedUnit.MeterPerMinute);
  
          /// <summary>
          ///     Get Speed in MetersPerSecond.
          /// </summary>
          public double MetersPerSecond => As(SpeedUnit.MeterPerSecond);
  
          /// <summary>
          ///     Get Speed in MicrometersPerMinutes.
          /// </summary>
          public double MicrometersPerMinutes => As(SpeedUnit.MicrometerPerMinute);
  
          /// <summary>
          ///     Get Speed in MicrometersPerSecond.
          /// </summary>
          public double MicrometersPerSecond => As(SpeedUnit.MicrometerPerSecond);
  
          /// <summary>
          ///     Get Speed in MilesPerHour.
          /// </summary>
          public double MilesPerHour => As(SpeedUnit.MilePerHour);
  
          /// <summary>
          ///     Get Speed in MillimetersPerHour.
          /// </summary>
          public double MillimetersPerHour => As(SpeedUnit.MillimeterPerHour);
  
          /// <summary>
          ///     Get Speed in MillimetersPerMinutes.
          /// </summary>
          public double MillimetersPerMinutes => As(SpeedUnit.MillimeterPerMinute);
  
          /// <summary>
          ///     Get Speed in MillimetersPerSecond.
          /// </summary>
          public double MillimetersPerSecond => As(SpeedUnit.MillimeterPerSecond);
  
          /// <summary>
          ///     Get Speed in NanometersPerMinutes.
          /// </summary>
          public double NanometersPerMinutes => As(SpeedUnit.NanometerPerMinute);
  
          /// <summary>
          ///     Get Speed in NanometersPerSecond.
          /// </summary>
          public double NanometersPerSecond => As(SpeedUnit.NanometerPerSecond);
  
          /// <summary>
          ///     Get Speed in UsSurveyFeetPerHour.
          /// </summary>
          public double UsSurveyFeetPerHour => As(SpeedUnit.UsSurveyFootPerHour);
  
          /// <summary>
          ///     Get Speed in UsSurveyFeetPerMinute.
          /// </summary>
          public double UsSurveyFeetPerMinute => As(SpeedUnit.UsSurveyFootPerMinute);
  
          /// <summary>
          ///     Get Speed in UsSurveyFeetPerSecond.
          /// </summary>
          public double UsSurveyFeetPerSecond => As(SpeedUnit.UsSurveyFootPerSecond);
  
          /// <summary>
          ///     Get Speed in YardsPerHour.
          /// </summary>
          public double YardsPerHour => As(SpeedUnit.YardPerHour);
  
          /// <summary>
          ///     Get Speed in YardsPerMinute.
          /// </summary>
          public double YardsPerMinute => As(SpeedUnit.YardPerMinute);
  
          /// <summary>
          ///     Get Speed in YardsPerSecond.
          /// </summary>
          public double YardsPerSecond => As(SpeedUnit.YardPerSecond);
  
          #endregion
  
          #region Static Methods
  
          /// <summary>
          ///     Get unit abbreviation string.
          /// </summary>
          /// <param name="unit">Unit to get abbreviation for.</param>
          /// <returns>Unit abbreviation string.</returns>
          public static string GetAbbreviation(SpeedUnit unit)
          {
              return GetAbbreviation(unit, null);
          }
  
          /// <summary>
          ///     Get unit abbreviation string.
          /// </summary>
          /// <param name="unit">Unit to get abbreviation for.</param>
          /// <returns>Unit abbreviation string.</returns>
          /// <param name="provider">Format to use for localization. Defaults to <see cref="CultureInfo.CurrentUICulture" /> if null.</param>
          public static string GetAbbreviation(SpeedUnit unit, IFormatProvider? provider)
          {
              return UnitAbbreviationsCache.Default.GetDefaultAbbreviation(unit, provider);
          }
  
          #endregion
  
          #region Static Factory Methods
  
          /// <summary>
          ///     Get Speed from CentimetersPerHour.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromCentimetersPerHour(QuantityValue centimetersperhour)
          {
              double value = (double) centimetersperhour;
              return new Speed(value, SpeedUnit.CentimeterPerHour);
          }
          /// <summary>
          ///     Get Speed from CentimetersPerMinutes.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromCentimetersPerMinutes(QuantityValue centimetersperminutes)
          {
              double value = (double) centimetersperminutes;
              return new Speed(value, SpeedUnit.CentimeterPerMinute);
          }
          /// <summary>
          ///     Get Speed from CentimetersPerSecond.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromCentimetersPerSecond(QuantityValue centimeterspersecond)
          {
              double value = (double) centimeterspersecond;
              return new Speed(value, SpeedUnit.CentimeterPerSecond);
          }
          /// <summary>
          ///     Get Speed from DecimetersPerMinutes.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromDecimetersPerMinutes(QuantityValue decimetersperminutes)
          {
              double value = (double) decimetersperminutes;
              return new Speed(value, SpeedUnit.DecimeterPerMinute);
          }
          /// <summary>
          ///     Get Speed from DecimetersPerSecond.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromDecimetersPerSecond(QuantityValue decimeterspersecond)
          {
              double value = (double) decimeterspersecond;
              return new Speed(value, SpeedUnit.DecimeterPerSecond);
          }
          /// <summary>
          ///     Get Speed from FeetPerHour.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromFeetPerHour(QuantityValue feetperhour)
          {
              double value = (double) feetperhour;
              return new Speed(value, SpeedUnit.FootPerHour);
          }
          /// <summary>
          ///     Get Speed from FeetPerMinute.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromFeetPerMinute(QuantityValue feetperminute)
          {
              double value = (double) feetperminute;
              return new Speed(value, SpeedUnit.FootPerMinute);
          }
          /// <summary>
          ///     Get Speed from FeetPerSecond.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromFeetPerSecond(QuantityValue feetpersecond)
          {
              double value = (double) feetpersecond;
              return new Speed(value, SpeedUnit.FootPerSecond);
          }
          /// <summary>
          ///     Get Speed from InchesPerHour.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromInchesPerHour(QuantityValue inchesperhour)
          {
              double value = (double) inchesperhour;
              return new Speed(value, SpeedUnit.InchPerHour);
          }
          /// <summary>
          ///     Get Speed from InchesPerMinute.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromInchesPerMinute(QuantityValue inchesperminute)
          {
              double value = (double) inchesperminute;
              return new Speed(value, SpeedUnit.InchPerMinute);
          }
          /// <summary>
          ///     Get Speed from InchesPerSecond.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromInchesPerSecond(QuantityValue inchespersecond)
          {
              double value = (double) inchespersecond;
              return new Speed(value, SpeedUnit.InchPerSecond);
          }
          /// <summary>
          ///     Get Speed from KilometersPerHour.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromKilometersPerHour(QuantityValue kilometersperhour)
          {
              double value = (double) kilometersperhour;
              return new Speed(value, SpeedUnit.KilometerPerHour);
          }
          /// <summary>
          ///     Get Speed from KilometersPerMinutes.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromKilometersPerMinutes(QuantityValue kilometersperminutes)
          {
              double value = (double) kilometersperminutes;
              return new Speed(value, SpeedUnit.KilometerPerMinute);
          }
          /// <summary>
          ///     Get Speed from KilometersPerSecond.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromKilometersPerSecond(QuantityValue kilometerspersecond)
          {
              double value = (double) kilometerspersecond;
              return new Speed(value, SpeedUnit.KilometerPerSecond);
          }
          /// <summary>
          ///     Get Speed from Knots.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromKnots(QuantityValue knots)
          {
              double value = (double) knots;
              return new Speed(value, SpeedUnit.Knot);
          }
          /// <summary>
          ///     Get Speed from MetersPerHour.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromMetersPerHour(QuantityValue metersperhour)
          {
              double value = (double) metersperhour;
              return new Speed(value, SpeedUnit.MeterPerHour);
          }
          /// <summary>
          ///     Get Speed from MetersPerMinutes.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromMetersPerMinutes(QuantityValue metersperminutes)
          {
              double value = (double) metersperminutes;
              return new Speed(value, SpeedUnit.MeterPerMinute);
          }
          /// <summary>
          ///     Get Speed from MetersPerSecond.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromMetersPerSecond(QuantityValue meterspersecond)
          {
              double value = (double) meterspersecond;
              return new Speed(value, SpeedUnit.MeterPerSecond);
          }
          /// <summary>
          ///     Get Speed from MicrometersPerMinutes.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromMicrometersPerMinutes(QuantityValue micrometersperminutes)
          {
              double value = (double) micrometersperminutes;
              return new Speed(value, SpeedUnit.MicrometerPerMinute);
          }
          /// <summary>
          ///     Get Speed from MicrometersPerSecond.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromMicrometersPerSecond(QuantityValue micrometerspersecond)
          {
              double value = (double) micrometerspersecond;
              return new Speed(value, SpeedUnit.MicrometerPerSecond);
          }
          /// <summary>
          ///     Get Speed from MilesPerHour.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromMilesPerHour(QuantityValue milesperhour)
          {
              double value = (double) milesperhour;
              return new Speed(value, SpeedUnit.MilePerHour);
          }
          /// <summary>
          ///     Get Speed from MillimetersPerHour.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromMillimetersPerHour(QuantityValue millimetersperhour)
          {
              double value = (double) millimetersperhour;
              return new Speed(value, SpeedUnit.MillimeterPerHour);
          }
          /// <summary>
          ///     Get Speed from MillimetersPerMinutes.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromMillimetersPerMinutes(QuantityValue millimetersperminutes)
          {
              double value = (double) millimetersperminutes;
              return new Speed(value, SpeedUnit.MillimeterPerMinute);
          }
          /// <summary>
          ///     Get Speed from MillimetersPerSecond.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromMillimetersPerSecond(QuantityValue millimeterspersecond)
          {
              double value = (double) millimeterspersecond;
              return new Speed(value, SpeedUnit.MillimeterPerSecond);
          }
          /// <summary>
          ///     Get Speed from NanometersPerMinutes.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromNanometersPerMinutes(QuantityValue nanometersperminutes)
          {
              double value = (double) nanometersperminutes;
              return new Speed(value, SpeedUnit.NanometerPerMinute);
          }
          /// <summary>
          ///     Get Speed from NanometersPerSecond.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromNanometersPerSecond(QuantityValue nanometerspersecond)
          {
              double value = (double) nanometerspersecond;
              return new Speed(value, SpeedUnit.NanometerPerSecond);
          }
          /// <summary>
          ///     Get Speed from UsSurveyFeetPerHour.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromUsSurveyFeetPerHour(QuantityValue ussurveyfeetperhour)
          {
              double value = (double) ussurveyfeetperhour;
              return new Speed(value, SpeedUnit.UsSurveyFootPerHour);
          }
          /// <summary>
          ///     Get Speed from UsSurveyFeetPerMinute.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromUsSurveyFeetPerMinute(QuantityValue ussurveyfeetperminute)
          {
              double value = (double) ussurveyfeetperminute;
              return new Speed(value, SpeedUnit.UsSurveyFootPerMinute);
          }
          /// <summary>
          ///     Get Speed from UsSurveyFeetPerSecond.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromUsSurveyFeetPerSecond(QuantityValue ussurveyfeetpersecond)
          {
              double value = (double) ussurveyfeetpersecond;
              return new Speed(value, SpeedUnit.UsSurveyFootPerSecond);
          }
          /// <summary>
          ///     Get Speed from YardsPerHour.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromYardsPerHour(QuantityValue yardsperhour)
          {
              double value = (double) yardsperhour;
              return new Speed(value, SpeedUnit.YardPerHour);
          }
          /// <summary>
          ///     Get Speed from YardsPerMinute.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromYardsPerMinute(QuantityValue yardsperminute)
          {
              double value = (double) yardsperminute;
              return new Speed(value, SpeedUnit.YardPerMinute);
          }
          /// <summary>
          ///     Get Speed from YardsPerSecond.
          /// </summary>
          /// <exception cref="ArgumentException">If value is NaN or Infinity.</exception>
          public static Speed FromYardsPerSecond(QuantityValue yardspersecond)
          {
              double value = (double) yardspersecond;
              return new Speed(value, SpeedUnit.YardPerSecond);
          }
  
          /// <summary>
          ///     Dynamically convert from value and unit enum <see cref="SpeedUnit" /> to <see cref="Speed" />.
          /// </summary>
          /// <param name="value">Value to convert from.</param>
          /// <param name="fromUnit">Unit to convert from.</param>
          /// <returns>Speed unit value.</returns>
          public static Speed From(QuantityValue value, SpeedUnit fromUnit)
          {
              return new Speed((double)value, fromUnit);
          }
  
          #endregion
  
          #region Static Parse Methods
  
          /// <summary>
          ///     Parse a string with one or two quantities of the format "&lt;quantity&gt; &lt;unit&gt;".
          /// </summary>
          /// <param name="str">String to parse. Typically in the form: {number} {unit}</param>
          /// <example>
          ///     Length.Parse("5.5 m", new CultureInfo("en-US"));
          /// </example>
          /// <exception cref="ArgumentNullException">The value of 'str' cannot be null. </exception>
          /// <exception cref="ArgumentException">
          ///     Expected string to have one or two pairs of quantity and unit in the format
          ///     "&lt;quantity&gt; &lt;unit&gt;". Eg. "5.5 m" or "1ft 2in"
          /// </exception>
          /// <exception cref="AmbiguousUnitParseException">
          ///     More than one unit is represented by the specified unit abbreviation.
          ///     Example: Volume.Parse("1 cup") will throw, because it can refer to any of
          ///     <see cref="VolumeUnit.MetricCup" />, <see cref="VolumeUnit.UsLegalCup" /> and <see cref="VolumeUnit.UsCustomaryCup" />.
          /// </exception>
          /// <exception cref="UnitsNetException">
          ///     If anything else goes wrong, typically due to a bug or unhandled case.
          ///     We wrap exceptions in <see cref="UnitsNetException" /> to allow you to distinguish
          ///     Units.NET exceptions from other exceptions.
          /// </exception>
          public static Speed Parse(string str)
          {
              return Parse(str, null);
          }
  
          /// <summary>
          ///     Parse a string with one or two quantities of the format "&lt;quantity&gt; &lt;unit&gt;".
          /// </summary>
          /// <param name="str">String to parse. Typically in the form: {number} {unit}</param>
          /// <example>
          ///     Length.Parse("5.5 m", new CultureInfo("en-US"));
          /// </example>
          /// <exception cref="ArgumentNullException">The value of 'str' cannot be null. </exception>
          /// <exception cref="ArgumentException">
          ///     Expected string to have one or two pairs of quantity and unit in the format
          ///     "&lt;quantity&gt; &lt;unit&gt;". Eg. "5.5 m" or "1ft 2in"
          /// </exception>
          /// <exception cref="AmbiguousUnitParseException">
          ///     More than one unit is represented by the specified unit abbreviation.
          ///     Example: Volume.Parse("1 cup") will throw, because it can refer to any of
          ///     <see cref="VolumeUnit.MetricCup" />, <see cref="VolumeUnit.UsLegalCup" /> and <see cref="VolumeUnit.UsCustomaryCup" />.
          /// </exception>
          /// <exception cref="UnitsNetException">
          ///     If anything else goes wrong, typically due to a bug or unhandled case.
          ///     We wrap exceptions in <see cref="UnitsNetException" /> to allow you to distinguish
          ///     Units.NET exceptions from other exceptions.
          /// </exception>
          /// <param name="provider">Format to use when parsing number and unit. Defaults to <see cref="CultureInfo.CurrentUICulture" /> if null.</param>
          public static Speed Parse(string str, IFormatProvider? provider)
          {
              return QuantityParser.Default.Parse<Speed, SpeedUnit>(
                  str,
                  provider,
                  From);
          }
  
          /// <summary>
          ///     Try to parse a string with one or two quantities of the format "&lt;quantity&gt; &lt;unit&gt;".
          /// </summary>
          /// <param name="str">String to parse. Typically in the form: {number} {unit}</param>
          /// <param name="result">Resulting unit quantity if successful.</param>
          /// <example>
          ///     Length.Parse("5.5 m", new CultureInfo("en-US"));
          /// </example>
          public static bool TryParse(string? str, out Speed result)
          {
              return TryParse(str, null, out result);
          }
  
          /// <summary>
          ///     Try to parse a string with one or two quantities of the format "&lt;quantity&gt; &lt;unit&gt;".
          /// </summary>
          /// <param name="str">String to parse. Typically in the form: {number} {unit}</param>
          /// <param name="result">Resulting unit quantity if successful.</param>
          /// <returns>True if successful, otherwise false.</returns>
          /// <example>
          ///     Length.Parse("5.5 m", new CultureInfo("en-US"));
          /// </example>
          /// <param name="provider">Format to use when parsing number and unit. Defaults to <see cref="CultureInfo.CurrentUICulture" /> if null.</param>
          public static bool TryParse(string? str, IFormatProvider? provider, out Speed result)
          {
              return QuantityParser.Default.TryParse<Speed, SpeedUnit>(
                  str,
                  provider,
                  From,
                  out result);
          }
  
          /// <summary>
          ///     Parse a unit string.
          /// </summary>
          /// <param name="str">String to parse. Typically in the form: {number} {unit}</param>
          /// <example>
          ///     Length.ParseUnit("m", new CultureInfo("en-US"));
          /// </example>
          /// <exception cref="ArgumentNullException">The value of 'str' cannot be null. </exception>
          /// <exception cref="UnitsNetException">Error parsing string.</exception>
          public static SpeedUnit ParseUnit(string str)
          {
              return ParseUnit(str, null);
          }
  
          /// <summary>
          ///     Parse a unit string.
          /// </summary>
          /// <param name="str">String to parse. Typically in the form: {number} {unit}</param>
          /// <param name="provider">Format to use when parsing number and unit. Defaults to <see cref="CultureInfo.CurrentUICulture" /> if null.</param>
          /// <example>
          ///     Length.ParseUnit("m", new CultureInfo("en-US"));
          /// </example>
          /// <exception cref="ArgumentNullException">The value of 'str' cannot be null. </exception>
          /// <exception cref="UnitsNetException">Error parsing string.</exception>
          public static SpeedUnit ParseUnit(string str, IFormatProvider? provider)
          {
              return UnitParser.Default.Parse<SpeedUnit>(str, provider);
          }
  
          /// <inheritdoc cref="TryParseUnit(string,IFormatProvider,out UnitsNet.Units.SpeedUnit)"/>
          public static bool TryParseUnit(string str, out SpeedUnit unit)
          {
              return TryParseUnit(str, null, out unit);
          }
  
          /// <summary>
          ///     Parse a unit string.
          /// </summary>
          /// <param name="str">String to parse. Typically in the form: {number} {unit}</param>
          /// <param name="unit">The parsed unit if successful.</param>
          /// <returns>True if successful, otherwise false.</returns>
          /// <example>
          ///     Length.TryParseUnit("m", new CultureInfo("en-US"));
          /// </example>
          /// <param name="provider">Format to use when parsing number and unit. Defaults to <see cref="CultureInfo.CurrentUICulture" /> if null.</param>
          public static bool TryParseUnit(string str, IFormatProvider? provider, out SpeedUnit unit)
          {
              return UnitParser.Default.TryParse<SpeedUnit>(str, provider, out unit);
          }
  
          #endregion
  
          #region Arithmetic Operators
  
          /// <summary>Negate the value.</summary>
          public static Speed operator -(Speed right)
          {
              return new Speed(-right.Value, right.Unit);
          }
  
          /// <summary>Get <see cref="Speed"/> from adding two <see cref="Speed"/>.</summary>
          public static Speed operator +(Speed left, Speed right)
          {
              return new Speed(left.Value + right.GetValueAs(left.Unit), left.Unit);
          }
  
          /// <summary>Get <see cref="Speed"/> from subtracting two <see cref="Speed"/>.</summary>
          public static Speed operator -(Speed left, Speed right)
          {
              return new Speed(left.Value - right.GetValueAs(left.Unit), left.Unit);
          }
  
          /// <summary>Get <see cref="Speed"/> from multiplying value and <see cref="Speed"/>.</summary>
          public static Speed operator *(double left, Speed right)
          {
              return new Speed(left * right.Value, right.Unit);
          }
  
          /// <summary>Get <see cref="Speed"/> from multiplying value and <see cref="Speed"/>.</summary>
          public static Speed operator *(Speed left, double right)
          {
              return new Speed(left.Value * right, left.Unit);
          }
  
          /// <summary>Get <see cref="Speed"/> from dividing <see cref="Speed"/> by value.</summary>
          public static Speed operator /(Speed left, double right)
          {
              return new Speed(left.Value / right, left.Unit);
          }
  
          /// <summary>Get ratio value from dividing <see cref="Speed"/> by <see cref="Speed"/>.</summary>
          public static double operator /(Speed left, Speed right)
          {
              return left.MetersPerSecond / right.MetersPerSecond;
          }
  
          #endregion
  
          #region Equality / IComparable
  
          /// <summary>Returns true if less or equal to.</summary>
          public static bool operator <=(Speed left, Speed right)
          {
              return left.Value <= right.GetValueAs(left.Unit);
          }
  
          /// <summary>Returns true if greater than or equal to.</summary>
          public static bool operator >=(Speed left, Speed right)
          {
              return left.Value >= right.GetValueAs(left.Unit);
          }
  
          /// <summary>Returns true if less than.</summary>
          public static bool operator <(Speed left, Speed right)
          {
              return left.Value < right.GetValueAs(left.Unit);
          }
  
          /// <summary>Returns true if greater than.</summary>
          public static bool operator >(Speed left, Speed right)
          {
              return left.Value > right.GetValueAs(left.Unit);
          }
  
          /// <summary>Returns true if exactly equal.</summary>
          /// <remarks>Consider using <see cref="Equals(Speed, double, ComparisonType)"/> for safely comparing floating point values.</remarks>
          public static bool operator ==(Speed left, Speed right)
          {
              return left.Equals(right);
          }
  
          /// <summary>Returns true if not exactly equal.</summary>
          /// <remarks>Consider using <see cref="Equals(Speed, double, ComparisonType)"/> for safely comparing floating point values.</remarks>
          public static bool operator !=(Speed left, Speed right)
          {
              return !(left == right);
          }
  
          /// <inheritdoc />
          public int CompareTo(object obj)
          {
              if(obj is null) throw new ArgumentNullException(nameof(obj));
              if(!(obj is Speed objSpeed)) throw new ArgumentException("Expected type Speed.", nameof(obj));
  
              return CompareTo(objSpeed);
          }
  
          /// <inheritdoc />
          public int CompareTo(Speed other)
          {
              return _value.CompareTo(other.GetValueAs(this.Unit));
          }
  
          /// <inheritdoc />
          /// <remarks>Consider using <see cref="Equals(Speed, double, ComparisonType)"/> for safely comparing floating point values.</remarks>
          public override bool Equals(object obj)
          {
              if(obj is null || !(obj is Speed objSpeed))
                  return false;
  
              return Equals(objSpeed);
          }
  
          /// <inheritdoc />
          /// <remarks>Consider using <see cref="Equals(Speed, double, ComparisonType)"/> for safely comparing floating point values.</remarks>
          public bool Equals(Speed other)
          {
              return _value.Equals(other.GetValueAs(this.Unit));
          }
  
          /// <summary>
          ///     <para>
          ///     Compare equality to another Speed within the given absolute or relative tolerance.
          ///     </para>
          ///     <para>
          ///     Relative tolerance is defined as the maximum allowable absolute difference between this quantity's value and
          ///     <paramref name="other"/> as a percentage of this quantity's value. <paramref name="other"/> will be converted into
          ///     this quantity's unit for comparison. A relative tolerance of 0.01 means the absolute difference must be within +/- 1% of
          ///     this quantity's value to be considered equal.
          ///     <example>
          ///     In this example, the two quantities will be equal if the value of b is within +/- 1% of a (0.02m or 2cm).
          ///     <code>
          ///     var a = Length.FromMeters(2.0);
          ///     var b = Length.FromInches(50.0);
          ///     a.Equals(b, 0.01, ComparisonType.Relative);
          ///     </code>
          ///     </example>
          ///     </para>
          ///     <para>
          ///     Absolute tolerance is defined as the maximum allowable absolute difference between this quantity's value and
          ///     <paramref name="other"/> as a fixed number in this quantity's unit. <paramref name="other"/> will be converted into
          ///     this quantity's unit for comparison.
          ///     <example>
          ///     In this example, the two quantities will be equal if the value of b is within 0.01 of a (0.01m or 1cm).
          ///     <code>
          ///     var a = Length.FromMeters(2.0);
          ///     var b = Length.FromInches(50.0);
          ///     a.Equals(b, 0.01, ComparisonType.Absolute);
          ///     </code>
          ///     </example>
          ///     </para>
          ///     <para>
          ///     Note that it is advised against specifying zero difference, due to the nature
          ///     of floating point operations and using System.Double internally.
          ///     </para>
          /// </summary>
          /// <param name="other">The other quantity to compare to.</param>
          /// <param name="tolerance">The absolute or relative tolerance value. Must be greater than or equal to 0.</param>
          /// <param name="comparisonType">The comparison type: either relative or absolute.</param>
          /// <returns>True if the absolute difference between the two values is not greater than the specified relative or absolute tolerance.</returns>
          public bool Equals(Speed other, double tolerance, ComparisonType comparisonType)
          {
              if(tolerance < 0)
                  throw new ArgumentOutOfRangeException("tolerance", "Tolerance must be greater than or equal to 0.");
  
              double thisValue = (double)this.Value;
              double otherValueInThisUnits = other.As(this.Unit);
  
              return UnitsNet.Comparison.Equals(thisValue, otherValueInThisUnits, tolerance, comparisonType);
          }
  
          /// <summary>
          ///     Returns the hash code for this instance.
          /// </summary>
          /// <returns>A hash code for the current Speed.</returns>
          public override int GetHashCode()
          {
              return new { QuantityType, Value, Unit }.GetHashCode();
          }
  
          #endregion
  
          #region Conversion Methods
  
          /// <summary>
          ///     Convert to the unit representation <paramref name="unit" />.
          /// </summary>
          /// <returns>Value converted to the specified unit.</returns>
          public double As(SpeedUnit unit)
          {
              if(Unit == unit)
                  return Convert.ToDouble(Value);
  
              var converted = GetValueAs(unit);
              return Convert.ToDouble(converted);
          }
  
          /// <inheritdoc cref="IQuantity.As(UnitSystem)"/>
          public double As(UnitSystem unitSystem)
          {
              if(unitSystem is null)
                  throw new ArgumentNullException(nameof(unitSystem));
  
              var unitInfos = Info.GetUnitInfosFor(unitSystem.BaseUnits);
  
              var firstUnitInfo = unitInfos.FirstOrDefault();
              if(firstUnitInfo == null)
                  throw new ArgumentException("No units were found for the given UnitSystem.", nameof(unitSystem));
  
              return As(firstUnitInfo.Value);
          }
  
          /// <inheritdoc />
          double IQuantity.As(Enum unit)
          {
              if(!(unit is SpeedUnit unitAsSpeedUnit))
                  throw new ArgumentException($"The given unit is of type {unit.GetType()}. Only {typeof(SpeedUnit)} is supported.", nameof(unit));
  
              return As(unitAsSpeedUnit);
          }
  
          /// <summary>
          ///     Converts this Speed to another Speed with the unit representation <paramref name="unit" />.
          /// </summary>
          /// <returns>A Speed with the specified unit.</returns>
          public Speed ToUnit(SpeedUnit unit)
          {
              var convertedValue = GetValueAs(unit);
              return new Speed(convertedValue, unit);
          }
  
          /// <inheritdoc />
          IQuantity IQuantity.ToUnit(Enum unit)
          {
              if(!(unit is SpeedUnit unitAsSpeedUnit))
                  throw new ArgumentException($"The given unit is of type {unit.GetType()}. Only {typeof(SpeedUnit)} is supported.", nameof(unit));
  
              return ToUnit(unitAsSpeedUnit);
          }
  
          /// <inheritdoc cref="IQuantity.ToUnit(UnitSystem)"/>
          public Speed ToUnit(UnitSystem unitSystem)
          {
              if(unitSystem is null)
                  throw new ArgumentNullException(nameof(unitSystem));
  
              var unitInfos = Info.GetUnitInfosFor(unitSystem.BaseUnits);
  
              var firstUnitInfo = unitInfos.FirstOrDefault();
              if(firstUnitInfo == null)
                  throw new ArgumentException("No units were found for the given UnitSystem.", nameof(unitSystem));
  
              return ToUnit(firstUnitInfo.Value);
          }
  
          /// <inheritdoc />
          IQuantity IQuantity.ToUnit(UnitSystem unitSystem) => ToUnit(unitSystem);
  
          /// <inheritdoc />
          IQuantity<SpeedUnit> IQuantity<SpeedUnit>.ToUnit(SpeedUnit unit) => ToUnit(unit);
  
          /// <inheritdoc />
          IQuantity<SpeedUnit> IQuantity<SpeedUnit>.ToUnit(UnitSystem unitSystem) => ToUnit(unitSystem);
  
          /// <summary>
          ///     Converts the current value + unit to the base unit.
          ///     This is typically the first step in converting from one unit to another.
          /// </summary>
          /// <returns>The value in the base unit representation.</returns>
          private double GetValueInBaseUnit()
          {
              switch(Unit)
              {
                  case SpeedUnit.CentimeterPerHour: return (_value/3600) * 1e-2d;
                  case SpeedUnit.CentimeterPerMinute: return (_value/60) * 1e-2d;
                  case SpeedUnit.CentimeterPerSecond: return (_value) * 1e-2d;
                  case SpeedUnit.DecimeterPerMinute: return (_value/60) * 1e-1d;
                  case SpeedUnit.DecimeterPerSecond: return (_value) * 1e-1d;
                  case SpeedUnit.FootPerHour: return _value*0.3048/3600;
                  case SpeedUnit.FootPerMinute: return _value*0.3048/60;
                  case SpeedUnit.FootPerSecond: return _value*0.3048;
                  case SpeedUnit.InchPerHour: return (_value/3600)*2.54e-2;
                  case SpeedUnit.InchPerMinute: return (_value/60)*2.54e-2;
                  case SpeedUnit.InchPerSecond: return _value*2.54e-2;
                  case SpeedUnit.KilometerPerHour: return (_value/3600) * 1e3d;
                  case SpeedUnit.KilometerPerMinute: return (_value/60) * 1e3d;
                  case SpeedUnit.KilometerPerSecond: return (_value) * 1e3d;
                  case SpeedUnit.Knot: return _value*0.514444;
                  case SpeedUnit.MeterPerHour: return _value/3600;
                  case SpeedUnit.MeterPerMinute: return _value/60;
                  case SpeedUnit.MeterPerSecond: return _value;
                  case SpeedUnit.MicrometerPerMinute: return (_value/60) * 1e-6d;
                  case SpeedUnit.MicrometerPerSecond: return (_value) * 1e-6d;
                  case SpeedUnit.MilePerHour: return _value*0.44704;
                  case SpeedUnit.MillimeterPerHour: return (_value/3600) * 1e-3d;
                  case SpeedUnit.MillimeterPerMinute: return (_value/60) * 1e-3d;
                  case SpeedUnit.MillimeterPerSecond: return (_value) * 1e-3d;
                  case SpeedUnit.NanometerPerMinute: return (_value/60) * 1e-9d;
                  case SpeedUnit.NanometerPerSecond: return (_value) * 1e-9d;
                  case SpeedUnit.UsSurveyFootPerHour: return (_value*1200/3937)/3600;
                  case SpeedUnit.UsSurveyFootPerMinute: return (_value*1200/3937)/60;
                  case SpeedUnit.UsSurveyFootPerSecond: return _value*1200/3937;
                  case SpeedUnit.YardPerHour: return _value*0.9144/3600;
                  case SpeedUnit.YardPerMinute: return _value*0.9144/60;
                  case SpeedUnit.YardPerSecond: return _value*0.9144;
                  default:
                      throw new NotImplementedException($"Can not convert {Unit} to base units.");
              }
          }
  
          /// <summary>
          ///     Converts the current value + unit to the base unit.
          ///     This is typically the first step in converting from one unit to another.
          /// </summary>
          /// <returns>The value in the base unit representation.</returns>
          internal Speed ToBaseUnit()
          {
              var baseUnitValue = GetValueInBaseUnit();
              return new Speed(baseUnitValue, BaseUnit);
          }
  
          private double GetValueAs(SpeedUnit unit)
          {
              if(Unit == unit)
                  return _value;
  
              var baseUnitValue = GetValueInBaseUnit();
  
              switch(unit)
              {
                  case SpeedUnit.CentimeterPerHour: return (baseUnitValue*3600) / 1e-2d;
                  case SpeedUnit.CentimeterPerMinute: return (baseUnitValue*60) / 1e-2d;
                  case SpeedUnit.CentimeterPerSecond: return (baseUnitValue) / 1e-2d;
                  case SpeedUnit.DecimeterPerMinute: return (baseUnitValue*60) / 1e-1d;
                  case SpeedUnit.DecimeterPerSecond: return (baseUnitValue) / 1e-1d;
                  case SpeedUnit.FootPerHour: return baseUnitValue/0.3048*3600;
                  case SpeedUnit.FootPerMinute: return baseUnitValue/0.3048*60;
                  case SpeedUnit.FootPerSecond: return baseUnitValue/0.3048;
                  case SpeedUnit.InchPerHour: return (baseUnitValue/2.54e-2)*3600;
                  case SpeedUnit.InchPerMinute: return (baseUnitValue/2.54e-2)*60;
                  case SpeedUnit.InchPerSecond: return baseUnitValue/2.54e-2;
                  case SpeedUnit.KilometerPerHour: return (baseUnitValue*3600) / 1e3d;
                  case SpeedUnit.KilometerPerMinute: return (baseUnitValue*60) / 1e3d;
                  case SpeedUnit.KilometerPerSecond: return (baseUnitValue) / 1e3d;
                  case SpeedUnit.Knot: return baseUnitValue/0.514444;
                  case SpeedUnit.MeterPerHour: return baseUnitValue*3600;
                  case SpeedUnit.MeterPerMinute: return baseUnitValue*60;
                  case SpeedUnit.MeterPerSecond: return baseUnitValue;
                  case SpeedUnit.MicrometerPerMinute: return (baseUnitValue*60) / 1e-6d;
                  case SpeedUnit.MicrometerPerSecond: return (baseUnitValue) / 1e-6d;
                  case SpeedUnit.MilePerHour: return baseUnitValue/0.44704;
                  case SpeedUnit.MillimeterPerHour: return (baseUnitValue*3600) / 1e-3d;
                  case SpeedUnit.MillimeterPerMinute: return (baseUnitValue*60) / 1e-3d;
                  case SpeedUnit.MillimeterPerSecond: return (baseUnitValue) / 1e-3d;
                  case SpeedUnit.NanometerPerMinute: return (baseUnitValue*60) / 1e-9d;
                  case SpeedUnit.NanometerPerSecond: return (baseUnitValue) / 1e-9d;
                  case SpeedUnit.UsSurveyFootPerHour: return (baseUnitValue*3937/1200)*3600;
                  case SpeedUnit.UsSurveyFootPerMinute: return (baseUnitValue*3937/1200)*60;
                  case SpeedUnit.UsSurveyFootPerSecond: return baseUnitValue*3937/1200;
                  case SpeedUnit.YardPerHour: return baseUnitValue/0.9144*3600;
                  case SpeedUnit.YardPerMinute: return baseUnitValue/0.9144*60;
                  case SpeedUnit.YardPerSecond: return baseUnitValue/0.9144;
                  default:
                      throw new NotImplementedException($"Can not convert {Unit} to {unit}.");
              }
          }
  
          #endregion
  
          #region ToString Methods
  
          /// <summary>
          ///     Gets the default string representation of value and unit.
          /// </summary>
          /// <returns>String representation.</returns>
          public override string ToString()
          {
              return ToString("g");
          }
  
          /// <summary>
          ///     Gets the default string representation of value and unit using the given format provider.
          /// </summary>
          /// <returns>String representation.</returns>
          /// <param name="provider">Format to use for localization and number formatting. Defaults to <see cref="CultureInfo.CurrentUICulture" /> if null.</param>
          public string ToString(IFormatProvider? provider)
          {
              return ToString("g", provider);
          }
  
          /// <summary>
          ///     Get string representation of value and unit.
          /// </summary>
          /// <param name="significantDigitsAfterRadix">The number of significant digits after the radix point.</param>
          /// <returns>String representation.</returns>
          /// <param name="provider">Format to use for localization and number formatting. Defaults to <see cref="CultureInfo.CurrentUICulture" /> if null.</param>
          [Obsolete(@"This method is deprecated and will be removed at a future release. Please use ToString(""s2"") or ToString(""s2"", provider) where 2 is an example of the number passed to significantDigitsAfterRadix.")]
          public string ToString(IFormatProvider? provider, int significantDigitsAfterRadix)
          {
              var value = Convert.ToDouble(Value);
              var format = UnitFormatter.GetFormat(value, significantDigitsAfterRadix);
              return ToString(provider, format);
          }
  
          /// <summary>
          ///     Get string representation of value and unit.
          /// </summary>
          /// <param name="format">String format to use. Default:  "{0:0.##} {1} for value and unit abbreviation respectively."</param>
          /// <param name="args">Arguments for string format. Value and unit are implicitly included as arguments 0 and 1.</param>
          /// <returns>String representation.</returns>
          /// <param name="provider">Format to use for localization and number formatting. Defaults to <see cref="CultureInfo.CurrentUICulture" /> if null.</param>
          [Obsolete("This method is deprecated and will be removed at a future release. Please use string.Format().")]
          public string ToString(IFormatProvider? provider, [NotNull] string format, [NotNull] params object[] args)
          {
              if (format == null) throw new ArgumentNullException(nameof(format));
              if (args == null) throw new ArgumentNullException(nameof(args));
  
              provider = provider ?? CultureInfo.CurrentUICulture;
  
              var value = Convert.ToDouble(Value);
              var formatArgs = UnitFormatter.GetFormatArgs(Unit, value, provider, args);
              return string.Format(provider, format, formatArgs);
          }
  
          /// <inheritdoc cref="QuantityFormatter.Format{TUnitType}(IQuantity{TUnitType}, string, IFormatProvider)"/>
          /// <summary>
          /// Gets the string representation of this instance in the specified format string using <see cref="CultureInfo.CurrentUICulture" />.
          /// </summary>
          /// <param name="format">The format string.</param>
          /// <returns>The string representation.</returns>
          public string ToString(string format)
          {
              return ToString(format, CultureInfo.CurrentUICulture);
          }
  
          /// <inheritdoc cref="QuantityFormatter.Format{TUnitType}(IQuantity{TUnitType}, string, IFormatProvider)"/>
          /// <summary>
          /// Gets the string representation of this instance in the specified format string using the specified format provider, or <see cref="CultureInfo.CurrentUICulture" /> if null.
          /// </summary>
          /// <param name="format">The format string.</param>
          /// <param name="provider">Format to use for localization and number formatting. Defaults to <see cref="CultureInfo.CurrentUICulture" /> if null.</param>
          /// <returns>The string representation.</returns>
          public string ToString(string format, IFormatProvider? provider)
          {
              return QuantityFormatter.Format<SpeedUnit>(this, format, provider);
          }
  
          #endregion
  
          #region IConvertible Methods
  
          TypeCode IConvertible.GetTypeCode()
          {
              return TypeCode.Object;
          }
  
          bool IConvertible.ToBoolean(IFormatProvider provider)
          {
              throw new InvalidCastException($"Converting {typeof(Speed)} to bool is not supported.");
          }
  
          byte IConvertible.ToByte(IFormatProvider provider)
          {
              return Convert.ToByte(_value);
          }
  
          char IConvertible.ToChar(IFormatProvider provider)
          {
              throw new InvalidCastException($"Converting {typeof(Speed)} to char is not supported.");
          }
  
          DateTime IConvertible.ToDateTime(IFormatProvider provider)
          {
              throw new InvalidCastException($"Converting {typeof(Speed)} to DateTime is not supported.");
          }
  
          decimal IConvertible.ToDecimal(IFormatProvider provider)
          {
              return Convert.ToDecimal(_value);
          }
  
          double IConvertible.ToDouble(IFormatProvider provider)
          {
              return Convert.ToDouble(_value);
          }
  
          short IConvertible.ToInt16(IFormatProvider provider)
          {
              return Convert.ToInt16(_value);
          }
  
          int IConvertible.ToInt32(IFormatProvider provider)
          {
              return Convert.ToInt32(_value);
          }
  
          long IConvertible.ToInt64(IFormatProvider provider)
          {
              return Convert.ToInt64(_value);
          }
  
          sbyte IConvertible.ToSByte(IFormatProvider provider)
          {
              return Convert.ToSByte(_value);
          }
  
          float IConvertible.ToSingle(IFormatProvider provider)
          {
              return Convert.ToSingle(_value);
          }
  
          string IConvertible.ToString(IFormatProvider provider)
          {
              return ToString("g", provider);
          }
  
          object IConvertible.ToType(Type conversionType, IFormatProvider provider)
          {
              if(conversionType == typeof(Speed))
                  return this;
              else if(conversionType == typeof(SpeedUnit))
                  return Unit;
              else if(conversionType == typeof(QuantityType))
                  return Speed.QuantityType;
              else if(conversionType == typeof(BaseDimensions))
                  return Speed.BaseDimensions;
              else
                  throw new InvalidCastException($"Converting {typeof(Speed)} to {conversionType} is not supported.");
          }
  
          ushort IConvertible.ToUInt16(IFormatProvider provider)
          {
              return Convert.ToUInt16(_value);
          }
  
          uint IConvertible.ToUInt32(IFormatProvider provider)
          {
              return Convert.ToUInt32(_value);
          }
  
          ulong IConvertible.ToUInt64(IFormatProvider provider)
          {
              return Convert.ToUInt64(_value);
          }
  
          #endregion
      }
  }
  