Unit Conversion and Dimensional Analysis Library 3.6.1
A compile-time, header-only C++23 dimensional-analysis library
Loading...
Searching...
No Matches
units Namespace Reference

Unit Conversion Library namespace. More...

Namespaces

namespace  acceleration
 namespace for unit types and containers representing acceleration values
namespace  angle
 namespace for unit types and containers representing angle values
namespace  angular_velocity
 namespace for unit types and containers representing angular velocity values
namespace  area
 namespace for unit types and containers representing area values
namespace  capacitance
 namespace for unit types and containers representing capacitance values
namespace  charge
 namespace for unit types and containers representing charge values
namespace  concentration
 namespace for unit types and containers representing concentration values
namespace  conductance
 namespace for unit types and containers representing conductance values
namespace  constants
 namespace for physical constants like PI and Avogadro's Number.
namespace  current
 namespace for unit types and containers representing current values
namespace  data
 namespace for unit types and containers representing data values
namespace  data_transfer_rate
 namespace for unit types and containers representing data values
namespace  density
 namespace for unit types and containers representing density values
namespace  dimension
 namespace representing the implemented base and derived unit types.
namespace  dynamic_viscosity
 namespace for unit types and containers representing dynamic (absolute) viscosity values
namespace  energy
 namespace for unit types and containers representing energy values
namespace  energy_density
 namespace for unit types and containers representing energy_density values
namespace  force
 namespace for unit types and containers representing force values
namespace  frequency
 namespace for unit types and containers representing frequency values
namespace  illuminance
 namespace for unit types and containers representing illuminance values
namespace  impedance
 namespace for unit types and containers representing impedance values
namespace  inductance
 namespace for unit types and containers representing inductance values
namespace  irradiance
 namespace for unit types and containers representing irradiance values
namespace  jerk
 namespace for unit types and containers representing jerk values
namespace  kinematic_viscosity
 namespace for unit types and containers representing kinematic viscosity values
namespace  length
 namespace for unit types and containers representing length values
namespace  literals
 namespace for unit literal definitions of all categories.
namespace  luminance
 namespace for unit types and containers representing luminance values
namespace  luminous_flux
 namespace for unit types and containers representing luminous_flux values
namespace  luminous_intensity
 namespace for unit types and containers representing luminous_intensity values
namespace  magnetic_field_strength
 namespace for unit types and containers representing magnetic_field_strength values
namespace  magnetic_flux
 namespace for unit types and containers representing magnetic_flux values
namespace  mass
 namespace for unit types and containers representing mass values
namespace  power
 namespace for unit types and containers representing power values
namespace  pressure
 namespace for unit types and containers representing pressure values
namespace  radiance
 namespace for unit types and containers representing radiance values
namespace  radiant_intensity
 namespace for unit types and containers representing radiant intensity values
namespace  radiation
 namespace for unit types and containers representing radiation values
namespace  solid_angle
 namespace for unit types and containers representing solid_angle values
namespace  spectral_flux
 namespace for unit types and containers representing spectral_flux values
namespace  spectral_intensity
 namespace for unit types and containers representing spectral_intensity values
namespace  spectral_irradiance
 namespace for unit types and containers representing spectral irradiance values
namespace  spectral_radiance
 namespace for unit types and containers representing spectral_radiance values
namespace  substance
 namespace for unit types and containers representing substance values
namespace  substance_concentration
 namespace for unit types and containers representing substance concentration values
namespace  substance_mass
 namespace for unit types and containers representing substance_mass values
namespace  temperature
 namespace for unit types and containers representing temperature values
namespace  time
 namespace for unit types and containers representing time values
namespace  torque
 namespace for unit types and containers representing torque values
namespace  traits
 namespace representing type traits which can access the properties of types provided by the units library.
namespace  velocity
 namespace for unit types and containers representing velocity values
namespace  voltage
 namespace for unit types and containers representing voltage values
namespace  volume
 namespace for unit types and containers representing volume values
namespace  volume_flow_rate
 namespace for unit types and containers representing volumetric-flow-rate values

Classes

class  absolute
 A point on a (possibly affine) scale — carries the unit's datum. More...
class  any_unit
struct  append
struct  append< dimension_t< T... >, dimension_t< U... > >
class  basic_kind
 A quantity distinguished by a string TAG — a "kind of quantity" that shares a unit and a dimension with others but is semantically distinct (radial vs. More...
struct  conversion_factor
 Type representing an arbitrary conversion factor between units. More...
struct  decibel_scale
 numerical scale which is decibel More...
struct  decibels
 dimensionless unit with decibel scale More...
class  delta
 An amount of a quantity — offset-free (no datum). More...
struct  dim
struct  dimension_pow_impl
struct  dimension_pow_impl< dimension_t< dim< T, E >... >, R >
struct  dimension_t
struct  dimension_t< D0, D... >
struct  dimension_t<>
struct  dimension_term
 one base-dimension term of a signature: which base dimension (by name-hash), and its rational exponent More...
struct  fixed_string
 A compile-time string usable as a non-type template parameter (the tag of a kind/of). More...
struct  linear_scale
 numerical scale which is linear More...
struct  linearized_value_t
 Tag for unit constructors. More...
struct  make_dimension_list
struct  make_dimension_list< dimension_t< T... >, N0, Rest... >
struct  make_dimension_list<>
struct  merge_dimensions_combine_impl
struct  merge_dimensions_combine_impl< false >
struct  merge_dimensions_combine_impl< true >
struct  merge_dimensions_impl
struct  merge_dimensions_impl< 0 >
struct  merge_dimensions_impl< 1 >
struct  merge_dimensions_impl<-1 >
struct  merge_dimensions_recurse_impl
struct  merge_dimensions_recurse_impl< false, false >
struct  merge_dimensions_recurse_impl< false, true >
struct  merge_dimensions_recurse_impl< true, false >
struct  merge_dimensions_recurse_impl< true, true >
class  unit
struct  unit_abbreviation
struct  unit_abbreviation< decibels< Underlying > >
struct  unit_identity
 the runtime identity of a quantity's dimension — the set of nonzero base-dimension terms More...
struct  unit_name
struct  unit_name< decibels< Underlying > >

Concepts

concept  AbsoluteType
 Concept satisfied by any absolute<U> point wrapper.
concept  ArithmeticType
 Concept for types which represent arithmetic types.
concept  ConversionFactorType
 Concept for types which represent conversion factors.
concept  DeltaType
 Concept satisfied by any delta<U> amount wrapper.
concept  DimensionedUnitType
 Concept for types which represent units with a dimension (i.e.
concept  Dimensionless
 Concept satisfied by any unit whose SI dimension is dimensionless; being dimension-keyed it.
concept  DimensionlessUnitType
 Concept for types which represent units without a dimension (dimensionless).
concept  KindType
 Concept satisfied by any string-tagged kind<Tag, U>.
concept  NonArithmeticType
 Concept for types which represent non-arithmetic types.
concept  NumericalScaleType
 Concept for types which represent numerical scales.
concept  OrdinaryDimensionlessUnitType
concept  PureDimensionlessCF
concept  RatioDimensionlessUnitType
concept  RatioType
 Concept for types which represent std::ratios.
concept  same_dimension
 Concept for types which represent units of the same dimensionality.
concept  UnitType
 Concept for types which represent units.

Typedefs

template<class T, class U>
using combine_dims = dim<typename T::dimension, std::ratio_add<typename T::exponent, typename U::exponent>>
template<class T, class U, class... R>
using merge_dimensions_recurse = typename merge_dimensions_recurse_impl<!T::empty, !U::empty>::template apply<T, U, R...>
template<class T, class U>
using merge_dimensions = merge_dimensions_recurse<T, U>
template<class T, class E>
using dimension_pow = typename dimension_pow_impl<T, E>::type
template<class T, class E>
using dimension_root = dimension_pow<T, std::ratio_divide<std::ratio<1>, E>>
template<class T, class U>
using dimension_multiply = merge_dimensions<T, U>
template<class T, class U>
using dimension_divide = merge_dimensions<T, dimension_pow<U, std::ratio<-1>>>
template<class... T>
using make_dimension = typename make_dimension_list<T...>::type
template<ConversionFactorType Cf>
using inverse = typename detail::inverse_impl<Cf>::type
 represents the inverse unit type of class U.
template<ConversionFactorType Cf>
using squared = typename detail::squared_impl<Cf>::type
 represents the unit type of class U squared
template<ConversionFactorType Cf>
using cubed = typename detail::cubed_impl<Cf>::type
 represents the type of class U cubed.
template<RatioType Ratio, std::intmax_t Eps = 10000000000>
using ratio_sqrt = typename units::detail::Sqrt<Ratio, std::ratio<1, Eps>>::type
 Calculate square root of a ratio at compile-time.
template<ConversionFactorType Cf, std::intmax_t Eps = 10000000000>
using square_root = typename detail::sqrt_impl<Cf, Eps>::type
 represents the square root of type class U.
template<ConversionFactorType Cf, ConversionFactorType... Cfs>
using compound_conversion_factor = typename detail::compound_impl<Cf, Cfs...>::type
 Represents a conversion factor made up from other conversion factors.
using dimensionless_ = conversion_factor<std::ratio<1>, dimension::dimensionless>
template<class Underlying = double>
using dimensionless = unit<traits::strong_t<conversion_factor<std::ratio<1>, dimension::dimensionless>>, Underlying, linear_scale>
template<class Underlying>
using dBi = decibels<Underlying>
template<affine::fixed_string Tag, UnitType U>
using kind = affine::basic_kind<Tag, U>
 The preferred user-facing spelling of a string-tagged quantity kind: units::kind<"radial", meters<double>>.
template<class Underlying>
using metres = meters<Underlying>
template<class T>
using nits = candelas_per_square_meter<T>
template<class T>
using blondels = apostilbs<T>
template<ConversionFactorType Cf>
using atto = typename detail::prefix<std::atto,Cf>::type
template<ConversionFactorType Cf>
using femto = typename detail::prefix<std::femto,Cf>::type
 < Represents the type of class Cf with the metric 'atto' prefix appended.
template<ConversionFactorType Cf>
using pico = typename detail::prefix<std::pico,Cf>::type
 < Represents the type of class Cf with the metric 'femto' prefix appended.
template<ConversionFactorType Cf>
using nano = typename detail::prefix<std::nano,Cf>::type
 < Represents the type of class Cf with the metric 'pico' prefix appended.
template<ConversionFactorType Cf>
using micro = typename detail::prefix<std::micro,Cf>::type
 < Represents the type of class Cf with the metric 'nano' prefix appended.
template<ConversionFactorType Cf>
using milli = typename detail::prefix<std::milli,Cf>::type
 < Represents the type of class Cf with the metric 'micro' prefix appended.
template<ConversionFactorType Cf>
using centi = typename detail::prefix<std::centi,Cf>::type
 < Represents the type of class Cf with the metric 'milli' prefix appended.
template<ConversionFactorType Cf>
using deci = typename detail::prefix<std::deci,Cf>::type
 < Represents the type of class Cf with the metric 'centi' prefix appended.
template<ConversionFactorType Cf>
using deca = typename detail::prefix<std::deca,Cf>::type
 < Represents the type of class Cf with the metric 'deci' prefix appended.
template<ConversionFactorType Cf>
using hecto = typename detail::prefix<std::hecto,Cf>::type
 < Represents the type of class Cf with the metric 'deca' prefix appended.
template<ConversionFactorType Cf>
using kilo = typename detail::prefix<std::kilo,Cf>::type
 < Represents the type of class Cf with the metric 'hecto' prefix appended.
template<ConversionFactorType Cf>
using mega = typename detail::prefix<std::mega,Cf>::type
 < Represents the type of class Cf with the metric 'kilo' prefix appended.
template<ConversionFactorType Cf>
using giga = typename detail::prefix<std::giga,Cf>::type
 < Represents the type of class Cf with the metric 'mega' prefix appended.
template<ConversionFactorType Cf>
using tera = typename detail::prefix<std::tera,Cf>::type
 < Represents the type of class Cf with the metric 'giga' prefix appended.
template<ConversionFactorType Cf>
using peta = typename detail::prefix<std::peta,Cf>::type
 < Represents the type of class Cf with the metric 'tera' prefix appended.
template<ConversionFactorType Cf>
using exa = typename detail::prefix<std::exa, Cf>::type
 < Represents the type of class Cf with the metric 'peta' prefix appended.
template<ConversionFactorType Cf>
using kibi = typename detail::prefix<std::ratio<1024>, Cf>::type
 < Represents the type of class Cf with the metric 'exa' prefix appended.
template<ConversionFactorType Cf>
using mebi = typename detail::prefix<std::ratio<1048576>, Cf>::type
 < Represents the type of class Cf with the binary 'kibi' prefix appended.
template<ConversionFactorType Cf>
using gibi = typename detail::prefix<std::ratio<1073741824>, Cf>::type
 < Represents the type of class Cf with the binary 'mibi' prefix appended.
template<ConversionFactorType Cf>
using tebi = typename detail::prefix<std::ratio<1099511627776>, Cf>::type
 < Represents the type of class Cf with the binary 'gibi' prefix appended.
template<ConversionFactorType Cf>
using pebi = typename detail::prefix<std::ratio<1125899906842624>, Cf>::type
 < Represents the type of class Cf with the binary 'tebi' prefix appended.
template<ConversionFactorType Cf>
using exbi = typename detail::prefix<std::ratio<1152921504606846976>, Cf>::type
 < Represents the type of class Cf with the binary 'pebi' prefix appended.

Enumerations

enum class  deserialize_error {
  truncated , bad_version , dimension_mismatch , unknown_base_dimension ,
  lossy_target
}
 the reasons a deserialize can fail More...

Functions

template<class AngleUnit, std::enable_if_t< traits::is_angle_unit_v< AngleUnit >, int > = 0>
dimensionless< detail::floating_point_promotion_t< typename AngleUnit::underlying_type > > cos (const AngleUnit angle) noexcept
 Compute cosine.
template<class AngleUnit, std::enable_if_t< traits::is_angle_unit_v< AngleUnit >, int > = 0>
dimensionless< detail::floating_point_promotion_t< typename AngleUnit::underlying_type > > sin (const AngleUnit angle) noexcept
 Compute sine.
template<class AngleUnit, std::enable_if_t< traits::is_angle_unit_v< AngleUnit >, int > = 0>
dimensionless< detail::floating_point_promotion_t< typename AngleUnit::underlying_type > > tan (const AngleUnit angle) noexcept
 Compute tangent.
template<class dimensionlessUnit, std::enable_if_t< traits::is_dimensionless_unit_v< dimensionlessUnit >, int > = 0>
radians< detail::floating_point_promotion_t< typename dimensionlessUnit::underlying_type > > acos (const dimensionlessUnit x) noexcept
 Compute arc cosine.
template<class dimensionlessUnit, std::enable_if_t< traits::is_dimensionless_unit_v< dimensionlessUnit >, int > = 0>
radians< detail::floating_point_promotion_t< typename dimensionlessUnit::underlying_type > > asin (const dimensionlessUnit x) noexcept
 Compute arc sine.
template<class dimensionlessUnit, std::enable_if_t< traits::is_dimensionless_unit_v< dimensionlessUnit >, int > = 0>
radians< detail::floating_point_promotion_t< typename dimensionlessUnit::underlying_type > > atan (const dimensionlessUnit x) noexcept
 Compute arc tangent.
template<class Y, class X, std::enable_if_t< traits::is_dimensionless_unit_v< decltype(std::declval< Y >()/std::declval< X >())>, int>
radians< detail::floating_point_promotion_t< std::common_type_t< typename X::underlying_type, typename Y::underlying_type > > > atan2 (const Y y, const X x) noexcept
 Compute arc tangent with two parameters.
template<class dimensionlessUnit, std::enable_if_t< traits::is_dimensionless_unit_v< dimensionlessUnit >, int > = 0>
dimensionless< detail::floating_point_promotion_t< typename dimensionlessUnit::underlying_type > > cosh (const dimensionlessUnit x) noexcept
 Compute hyperbolic cosine.
template<class dimensionlessUnit, std::enable_if_t< traits::is_dimensionless_unit_v< dimensionlessUnit >, int > = 0>
dimensionless< detail::floating_point_promotion_t< typename dimensionlessUnit::underlying_type > > sinh (const dimensionlessUnit x) noexcept
 Compute hyperbolic sine.
template<class dimensionlessUnit, std::enable_if_t< traits::is_dimensionless_unit_v< dimensionlessUnit >, int > = 0>
dimensionless< detail::floating_point_promotion_t< typename dimensionlessUnit::underlying_type > > tanh (const dimensionlessUnit x) noexcept
 Compute hyperbolic tangent.
template<class dimensionlessUnit, std::enable_if_t< traits::is_dimensionless_unit_v< dimensionlessUnit >, int > = 0>
dimensionless< detail::floating_point_promotion_t< typename dimensionlessUnit::underlying_type > > acosh (const dimensionlessUnit x) noexcept
 Compute arc hyperbolic cosine.
template<class dimensionlessUnit, std::enable_if_t< traits::is_dimensionless_unit_v< dimensionlessUnit >, int > = 0>
dimensionless< detail::floating_point_promotion_t< typename dimensionlessUnit::underlying_type > > asinh (const dimensionlessUnit x) noexcept
 Compute arc hyperbolic sine.
template<class dimensionlessUnit, std::enable_if_t< traits::is_dimensionless_unit_v< dimensionlessUnit >, int > = 0>
dimensionless< detail::floating_point_promotion_t< typename dimensionlessUnit::underlying_type > > atanh (const dimensionlessUnit x) noexcept
 Compute arc hyperbolic tangent.
constexpr int const_strcmp (const char *lhs, const char *rhs)
template<ArithmeticType T>
constexpr detail::floating_point_promotion_t< T > sqrt (T x_)
template<signed long long Exp, ArithmeticType B>
constexpr detail::floating_point_promotion_t< B > pow (B base) noexcept
template<ArithmeticType T1, ArithmeticType T2>
requires std::is_unsigned_v<T2>
constexpr detail::floating_point_promotion_t< T1 > pow (T1 x, T2 y) noexcept
template<ArithmeticType T1, ArithmeticType T2>
requires std::is_signed_v<T2>
constexpr detail::floating_point_promotion_t< T1 > pow (T1 x, T2 y) noexcept
template<ArithmeticType T>
constexpr T abs (T x)
template<ConversionFactorType ConversionFactorFrom, ConversionFactorType ConversionFactorTo, ArithmeticType To = double, ArithmeticType From>
requires (traits::is_same_dimension_conversion_factor_v<ConversionFactorFrom, ConversionFactorTo>)
constexpr To convert (const From &value) noexcept
 converts a value from an unit to another.
template<UnitType UnitTo, UnitType UnitFrom>
requires same_dimension<UnitFrom, UnitTo>
constexpr UnitTo convert (const UnitFrom &from) noexcept
 converts an unit to another unit.
template<UnitType UnitType, ArithmeticType T>
requires detail::is_losslessly_convertible<T, typename UnitType::underlying_type>
constexpr UnitType make_unit (const T value) noexcept
 Constructs a unit container from an arithmetic type.
template<class D, class E>
std::ostream & operator<< (std::ostream &os, const dim< D, E > &)
template<class... Dims>
std::ostream & operator<< (std::ostream &os, const dimension_t< Dims... > &)
template<ConversionFactorType ConversionFactor, ArithmeticType T, NumericalScaleType< T > NumericalScale>
std::ostream & operator<< (std::ostream &os, const unit< ConversionFactor, T, NumericalScale > &obj)
template<ConversionFactorType ConversionFactor, ArithmeticType T, NumericalScaleType< T > NumericalScale>
std::string to_string (const unit< ConversionFactor, T, NumericalScale > &obj)
template<ArithmeticType T, UnitType Unit>
constexpr T unit_cast (const Unit &value) noexcept
 Casts an unit to an arithmetic type.
template<UnitType UnitTypeLhs>
requires (!traits::is_affine_unit_v<UnitTypeLhs>)
constexpr UnitTypeLhs & operator+= (UnitTypeLhs &lhs, const detail::type_identity_t< UnitTypeLhs > &rhs) noexcept
template<UnitType UnitTypeLhs>
requires (traits::is_affine_unit_v<UnitTypeLhs>)
constexpr UnitTypeLhs & operator+= (UnitTypeLhs &lhs, const detail::type_identity_t< UnitTypeLhs > &rhs) noexcept
 Compound addition for AFFINE units (e.g.
template<UnitType UnitTypeLhs, ArithmeticType T>
requires (!RatioDimensionlessUnitType<UnitTypeLhs>)
constexpr UnitTypeLhs & operator+= (UnitTypeLhs &lhs, T rhs) noexcept
template<RatioDimensionlessUnitType U, ArithmeticType T>
requires (traits::has_linear_scale_v<U>)
constexpr U & operator+= (U &lhs, T rhs) noexcept
template<RatioDimensionlessUnitType U, DimensionlessUnitType D>
requires (traits::has_linear_scale_v<U, D> && !RatioDimensionlessUnitType<D>)
constexpr U & operator+= (U &lhs, const D &rhs) noexcept
template<RatioDimensionlessUnitType U, ArithmeticType T>
requires (traits::has_linear_scale_v<U>)
constexpr U & operator-= (U &lhs, T rhs) noexcept
template<UnitType UnitTypeLhs>
requires (!traits::is_affine_unit_v<UnitTypeLhs>)
constexpr UnitTypeLhs & operator-= (UnitTypeLhs &lhs, const detail::type_identity_t< UnitTypeLhs > &rhs) noexcept
template<UnitType UnitTypeLhs>
requires (traits::is_affine_unit_v<UnitTypeLhs>)
constexpr UnitTypeLhs & operator-= (UnitTypeLhs &lhs, const detail::type_identity_t< UnitTypeLhs > &rhs) noexcept
 Compound subtraction for AFFINE units (e.g.
template<UnitType UnitTypeLhs, ArithmeticType T>
requires (!RatioDimensionlessUnitType<UnitTypeLhs>)
constexpr UnitTypeLhs & operator-= (UnitTypeLhs &lhs, const T &rhs) noexcept
template<RatioDimensionlessUnitType U, DimensionlessUnitType D>
requires (traits::has_linear_scale_v<U, D> && !RatioDimensionlessUnitType<D>)
constexpr U & operator-= (U &lhs, const D &rhs) noexcept
template<UnitType UnitTypeLhs, ArithmeticType T>
requires (!RatioDimensionlessUnitType<UnitTypeLhs>)
constexpr UnitTypeLhs & operator*= (UnitTypeLhs &lhs, const T &rhs)
template<RatioDimensionlessUnitType U, RatioDimensionlessUnitType URhs>
requires (traits::has_linear_scale_v<U, URhs>)
constexpr U & operator*= (U &lhs, const URhs &rhs) noexcept
template<RatioDimensionlessUnitType U>
requires (units::traits::has_linear_scale_v<U>)
constexpr U & operator*= (U &lhs, const U &rhs) noexcept
template<RatioDimensionlessUnitType U, units::ArithmeticType T>
requires (units::traits::has_linear_scale_v<U>)
constexpr U & operator*= (U &lhs, T rhs) noexcept
template<RatioDimensionlessUnitType U, DimensionlessUnitType D>
requires (units::traits::has_linear_scale_v<U, D> && !RatioDimensionlessUnitType<D>)
constexpr U & operator*= (U &lhs, const D &rhs) noexcept
template<UnitType UnitTypeLhs, DimensionlessUnitType D>
requires (!RatioDimensionlessUnitType<UnitTypeLhs>)
constexpr UnitTypeLhs & operator*= (UnitTypeLhs &lhs, const D &rhs)
template<UnitType UnitTypeLhs, ArithmeticType T>
requires (!RatioDimensionlessUnitType<UnitTypeLhs>)
constexpr UnitTypeLhs & operator/= (UnitTypeLhs &lhs, const T &rhs)
template<UnitType UnitTypeLhs, DimensionlessUnitType D>
requires (!RatioDimensionlessUnitType<UnitTypeLhs>)
constexpr UnitTypeLhs & operator/= (UnitTypeLhs &lhs, const D &rhs)
template<RatioDimensionlessUnitType U, RatioDimensionlessUnitType URhs>
requires (traits::has_linear_scale_v<U, URhs>)
constexpr U & operator/= (U &lhs, const URhs &rhs) noexcept
template<RatioDimensionlessUnitType U>
requires (units::traits::has_linear_scale_v<U>)
constexpr U & operator/= (U &lhs, const U &rhs) noexcept
template<RatioDimensionlessUnitType U, units::ArithmeticType T>
requires (units::traits::has_linear_scale_v<U>)
constexpr U & operator/= (U &lhs, T rhs) noexcept
template<RatioDimensionlessUnitType U, DimensionlessUnitType D>
requires (units::traits::has_linear_scale_v<U, D> && !RatioDimensionlessUnitType<D>)
constexpr U & operator/= (U &lhs, const D &rhs) noexcept
template<DimensionedUnitType UnitTypeLhs>
requires (!RatioDimensionlessUnitType<UnitTypeLhs>)
constexpr UnitTypeLhs & operator%= (UnitTypeLhs &lhs, const detail::type_identity_t< UnitTypeLhs > &rhs) noexcept
template<DimensionlessUnitType UnitTypeLhs, DimensionlessUnitType UnitTypeRhs>
requires (!(RatioDimensionlessUnitType<UnitTypeLhs> || RatioDimensionlessUnitType<UnitTypeRhs>))
constexpr UnitTypeLhs & operator%= (UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
template<UnitType UnitTypeLhs>
requires (!RatioDimensionlessUnitType<UnitTypeLhs>)
constexpr UnitTypeLhs & operator%= (UnitTypeLhs &lhs, const typename UnitTypeLhs::underlying_type &rhs) noexcept
template<RatioDimensionlessUnitType U>
requires (traits::has_linear_scale_v<U>)
constexpr U & operator%= (U &lhs, const U &rhs) noexcept
template<RatioDimensionlessUnitType U>
requires (traits::has_linear_scale_v<U>)
constexpr U & operator%= (U &lhs, const typename U::underlying_type &rhs) noexcept
template<RatioDimensionlessUnitType U, DimensionlessUnitType D>
requires (traits::has_linear_scale_v<U, D> && !RatioDimensionlessUnitType<D>)
constexpr U & operator%= (U &lhs, const D &rhs) noexcept
template<UnitType UnitTypeLhs>
constexpr UnitTypeLhs operator+ (const UnitTypeLhs &u) noexcept
template<UnitType UnitTypeLhs>
constexpr UnitTypeLhs & operator++ (UnitTypeLhs &u) noexcept
template<UnitType UnitTypeLhs>
constexpr UnitTypeLhs operator++ (UnitTypeLhs &u, int) noexcept
template<UnitType UnitTypeLhs>
constexpr UnitTypeLhs operator- (const UnitTypeLhs &u) noexcept
template<UnitType UnitTypeLhs>
constexpr UnitTypeLhs & operator-- (UnitTypeLhs &u) noexcept
template<UnitType UnitTypeLhs>
constexpr UnitTypeLhs operator-- (UnitTypeLhs &u, int) noexcept
template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs> &&
!traits::is_affine_unit_v<UnitTypeLhs> && !traits::is_affine_unit_v<UnitTypeRhs>)
constexpr auto operator+ (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Addition operator for unit types with a linear_scale.
template<RatioDimensionlessUnitType U, ArithmeticType T>
requires (traits::has_linear_scale_v<U>)
constexpr auto operator+ (const U &lhs, T rhs) noexcept -> traits::replace_underlying_t< U, detail::floating_point_promotion_t< std::common_type_t< typename U::underlying_type, T > > >
 Addition template for ratio-like dimensionless units (concentrations, etc).
template<RatioDimensionlessUnitType U, ArithmeticType T>
requires (traits::has_linear_scale_v<U>)
constexpr auto operator+ (T lhs, const U &rhs) noexcept -> traits::replace_underlying_t< U, detail::floating_point_promotion_t< std::common_type_t< T, typename U::underlying_type > > >
template<DimensionlessUnitType UnitTypeLhs, ArithmeticType T>
requires (traits::has_linear_scale_v<UnitTypeLhs> && !RatioDimensionlessUnitType<UnitTypeLhs> && !RatioDimensionlessUnitType
<UnitTypeLhs>)
constexpr traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, T > > operator+ (const UnitTypeLhs &lhs, T rhs) noexcept
 Addition operator for dimensionless unit types with a linear_scale.
template<DimensionlessUnitType UnitTypeRhs, ArithmeticType T>
requires (traits::has_linear_scale_v<UnitTypeRhs> && !RatioDimensionlessUnitType<UnitTypeRhs>)
constexpr traits::replace_underlying_t< UnitTypeRhs, std::common_type_t< T, typename UnitTypeRhs::underlying_type > > operator+ (T lhs, const UnitTypeRhs &rhs) noexcept
 Addition operator for dimensionless unit types with a linear_scale.
template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs> &&
!traits::is_affine_unit_v<UnitTypeLhs> && !traits::is_affine_unit_v<UnitTypeRhs>)
constexpr auto operator- (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Subtraction operator for NON-AFFINE unit types with a linear_scale.
template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs> &&
(traits::is_affine_unit_v<UnitTypeLhs> || traits::is_affine_unit_v<UnitTypeRhs>))
constexpr auto operator- (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Subtraction operator for AFFINE unit types (e.g.
template<DimensionlessUnitType UnitTypeLhs, ArithmeticType T>
requires (traits::has_linear_scale_v<UnitTypeLhs> && !RatioDimensionlessUnitType<UnitTypeLhs>)
constexpr traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, T > > operator- (const UnitTypeLhs &lhs, T rhs) noexcept
 Subtraction operator for dimensionless unit types with a linear_scale.
template<RatioDimensionlessUnitType U, ArithmeticType T>
requires (traits::has_linear_scale_v<U>)
constexpr auto operator- (const U &lhs, T rhs) noexcept -> traits::replace_underlying_t< U, detail::floating_point_promotion_t< std::common_type_t< typename U::underlying_type, T > > >
 Subtraction for ratio-like dimensionless units.
template<RatioDimensionlessUnitType U, ArithmeticType T>
requires (traits::has_linear_scale_v<U>)
constexpr auto operator- (T lhs, const U &rhs) noexcept -> traits::replace_underlying_t< U, detail::floating_point_promotion_t< std::common_type_t< T, typename U::underlying_type > > >
template<DimensionlessUnitType UnitTypeRhs, ArithmeticType T>
requires (traits::has_linear_scale_v<UnitTypeRhs> && !RatioDimensionlessUnitType<UnitTypeRhs>)
constexpr traits::replace_underlying_t< UnitTypeRhs, std::common_type_t< T, typename UnitTypeRhs::underlying_type > > operator- (T lhs, const UnitTypeRhs &rhs) noexcept
 Subtraction operator for dimensionless unit types with a linear_scale.
template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr auto operator* (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept -> detail::rewrap_to_named_t< unit< traits::strong_t< squared< typename traits::unit_traits< std::common_type_t< UnitTypeLhs, UnitTypeRhs > >::conversion_factor > >, typename std::common_type_t< UnitTypeLhs, UnitTypeRhs >::underlying_type > >
 Multiplication type for convertible unit types with a linear scale.
template<DimensionedUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (!same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr auto operator* (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept -> detail::rewrap_to_named_t< unit< traits::strong_t< compound_conversion_factor< typename traits::unit_traits< UnitTypeLhs >::conversion_factor, typename traits::unit_traits< UnitTypeRhs >::conversion_factor > >, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > >
 Multiplication type for non-convertible unit types with a linear scale.
template<DimensionedUnitType UnitTypeLhs, OrdinaryDimensionlessUnitType UnitTypeRhs>
requires (traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > operator* (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Multiplication by an ordinary dimensionless unit for unit types with a linear scale.
template<DimensionedUnitType UnitTypeLhs, RatioDimensionlessUnitType UnitTypeRhs>
requires (traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > operator* (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Multiplication by a ratio-dimensionless unit for unit types with a linear scale.
template<OrdinaryDimensionlessUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr traits::replace_underlying_t< UnitTypeRhs, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > operator* (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Multiplication by an ordinary dimensionless unit for unit types with a linear scale.
template<RatioDimensionlessUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr traits::replace_underlying_t< UnitTypeRhs, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > operator* (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 ratio-dimensionless * dimensioned -> dimensioned (scalar multiply)
template<DimensionedUnitType UnitTypeLhs, ArithmeticType T>
requires (traits::has_linear_scale_v<UnitTypeLhs>)
constexpr traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, T > > operator* (const UnitTypeLhs &lhs, T rhs) noexcept
 Multiplication by an arithmetic type for dimensioned unit types with a linear scale.
template<DimensionedUnitType UnitTypeRhs, ArithmeticType T>
requires (traits::has_linear_scale_v<UnitTypeRhs>)
constexpr traits::replace_underlying_t< UnitTypeRhs, std::common_type_t< T, typename UnitTypeRhs::underlying_type > > operator* (T lhs, const UnitTypeRhs &rhs) noexcept
 Multiplication by an arithmetic type for dimensioned unit types with a linear scale.
template<RatioDimensionlessUnitType U, units::ArithmeticType T>
requires (units::traits::has_linear_scale_v<U>)
constexpr units::dimensionless< units::detail::floating_point_promotion_t< std::common_type_t< T, typename U::underlying_type > > > operator* (T lhs, const U &rhs) noexcept
 scalar * ratio-dimensionless -> base dimensionless (PROMOTED)
template<RatioDimensionlessUnitType U, units::ArithmeticType T>
requires (units::traits::has_linear_scale_v<U>)
constexpr units::dimensionless< units::detail::floating_point_promotion_t< std::common_type_t< typename U::underlying_type, T > > > operator* (const U &lhs, T rhs) noexcept
 ratio-dimensionless * scalar -> base dimensionless (PROMOTED)
template<DimensionlessUnitType UnitTypeLhs, ArithmeticType T>
requires (traits::has_linear_scale_v<UnitTypeLhs> && !RatioDimensionlessUnitType<UnitTypeLhs>)
constexpr traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, T > > operator* (const UnitTypeLhs &lhs, T rhs) noexcept
 Multiplication by an arithmetic type for dimensionless unit types with a linear scale.
template<DimensionlessUnitType UnitTypeRhs, ArithmeticType T>
requires (traits::has_linear_scale_v<UnitTypeRhs> && !RatioDimensionlessUnitType<UnitTypeRhs>)
constexpr traits::replace_underlying_t< UnitTypeRhs, std::common_type_t< T, typename UnitTypeRhs::underlying_type > > operator* (T lhs, const UnitTypeRhs &rhs) noexcept
 Multiplication by an arithmetic type for dimensionless unit types with a linear scale.
template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires ( same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs> &&
!RatioDimensionlessUnitType<UnitTypeLhs> && !RatioDimensionlessUnitType<UnitTypeRhs>)
constexpr dimensionless< std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > operator/ (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Division for convertible unit types with a linear scale.
template<DimensionedUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (!same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr auto operator/ (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept -> detail::rewrap_to_named_t< unit< traits::strong_t< compound_conversion_factor< typename traits::unit_traits< UnitTypeLhs >::conversion_factor, inverse< typename traits::unit_traits< UnitTypeRhs >::conversion_factor > > >, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > >
 Division for non-convertible unit types with a linear scale.
template<DimensionedUnitType UnitTypeLhs, OrdinaryDimensionlessUnitType UnitTypeRhs>
requires (traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > operator/ (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Division by an ordinary dimensionless unit for unit types with a linear scale.
template<DimensionedUnitType UnitTypeLhs, RatioDimensionlessUnitType UnitTypeRhs>
requires (traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > operator/ (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Division by a ratio-dimensionless unit for unit types with a linear scale.
template<OrdinaryDimensionlessUnitType UnitTypeLhs, RatioDimensionlessUnitType UnitTypeRhs>
requires (traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr auto operator/ (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept -> detail::rewrap_to_named_t< unit< traits::strong_t< inverse< typename traits::unit_traits< UnitTypeRhs >::conversion_factor > >, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > >
 Division of an ordinary dimensionless unit by a ratio-dimensionless unit.
template<OrdinaryDimensionlessUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs> && traits::is_dimensionless_unit_v<UnitTypeLhs>)
constexpr auto operator/ (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept -> detail::rewrap_to_named_t< unit< traits::strong_t< inverse< typename traits::unit_traits< UnitTypeRhs >::conversion_factor > >, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > >
 Division of a dimensionless unit by a unit type with a linear scale.
template<RatioDimensionlessUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr auto operator/ (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept -> unit< traits::strong_t< compound_conversion_factor< typename traits::unit_traits< UnitTypeLhs >::conversion_factor, inverse< typename traits::unit_traits< UnitTypeRhs >::conversion_factor > > >, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > >
 Division of a ratio-dimensionless unit (pct/ppm/ppb/...) by a dimensioned unit.
template<UnitType UnitTypeLhs, ArithmeticType T>
requires (traits::has_linear_scale_v<UnitTypeLhs> && !RatioDimensionlessUnitType<UnitTypeLhs>)
constexpr traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, T > > operator/ (const UnitTypeLhs &lhs, T rhs) noexcept
 Division by a dimensionless for unit types with a linear scale.
template<UnitType UnitTypeRhs, ArithmeticType T>
requires (traits::has_linear_scale_v<UnitTypeRhs> && !RatioDimensionlessUnitType<UnitTypeRhs>)
constexpr auto operator/ (T lhs, const UnitTypeRhs &rhs) noexcept -> detail::rewrap_to_named_t< unit< traits::strong_t< inverse< typename traits::unit_traits< UnitTypeRhs >::conversion_factor > >, std::common_type_t< T, typename UnitTypeRhs::underlying_type > > >
 Division of a dimensionless by a unit type with a linear scale.
template<RatioDimensionlessUnitType U, ArithmeticType T>
requires (traits::has_linear_scale_v<U>)
constexpr traits::replace_underlying_t< U, std::common_type_t< typename U::underlying_type, T > > operator/ (const U &lhs, T rhs) noexcept
 Division of ratio-like dimensionless units with arithmetic types.
template<RatioDimensionlessUnitType U, ArithmeticType T>
requires (traits::has_linear_scale_v<U>)
constexpr units::dimensionless< detail::floating_point_promotion_t< std::common_type_t< T, typename U::underlying_type > > > operator/ (T lhs, const U &rhs) noexcept
template<RatioDimensionlessUnitType U1, RatioDimensionlessUnitType U2>
requires (traits::has_linear_scale_v<U1, U2>)
constexpr dimensionless< detail::floating_point_promotion_t< std::common_type_t< typename U1::underlying_type, typename U2::underlying_type > > > operator/ (const U1 &lhs, const U2 &rhs) noexcept
template<DimensionedUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr std::common_type_t< UnitTypeLhs, UnitTypeRhs > operator% (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Modulo for convertible unit types with a linear scale.
template<DimensionedUnitType UnitTypeLhs, DimensionlessUnitType UnitTypeRhs>
requires (traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > operator% (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Modulo by a dimensionless for unit types with a linear scale.
template<DimensionlessUnitType UnitTypeLhs, DimensionlessUnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr traits::replace_underlying_t< UnitTypeLhs, typename std::common_type_t< UnitTypeLhs, UnitTypeRhs >::underlying_type > operator% (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Modulo for two dimensionless unit types with a linear scale.
template<UnitType UnitTypeLhs, ArithmeticType T>
requires (traits::has_linear_scale_v<UnitTypeLhs> && !RatioDimensionlessUnitType<UnitTypeLhs>)
constexpr traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, T > > operator% (const UnitTypeLhs &lhs, const T &rhs) noexcept
 Modulo by an arithmetic type for unit types with a linear scale.
template<RatioDimensionlessUnitType U>
requires (traits::has_linear_scale_v<U>)
constexpr U operator% (const U &lhs, const U &rhs) noexcept
template<RatioDimensionlessUnitType U, ArithmeticType T>
requires (traits::has_linear_scale_v<U>)
constexpr U operator% (const U &lhs, T rhs) noexcept
template<RatioDimensionlessUnitType U, ArithmeticType T>
requires (traits::has_linear_scale_v<U>)
constexpr U operator% (T lhs, const U &rhs) noexcept
template<DimensionlessUnitType UnitTypeRhs, ArithmeticType T>
constexpr bool operator== (const T &lhs, const UnitTypeRhs &rhs) noexcept
template<DimensionlessUnitType UnitTypeLhs, ArithmeticType T>
constexpr bool operator== (const UnitTypeLhs &lhs, const T &rhs) noexcept
template<DimensionlessUnitType UnitTypeRhs, ArithmeticType T>
requires (traits::is_dimensionless_unit_v<UnitTypeRhs> && std::is_arithmetic_v<T>)
constexpr bool operator!= (const T &lhs, const UnitTypeRhs &rhs) noexcept
template<DimensionlessUnitType UnitTypeLhs, ArithmeticType T>
constexpr bool operator!= (const UnitTypeLhs &lhs, const T &rhs) noexcept
template<DimensionlessUnitType UnitTypeRhs, ArithmeticType T>
requires (traits::is_dimensionless_unit_v<UnitTypeRhs> && std::is_arithmetic_v<T>)
constexpr bool operator>= (const T &lhs, const UnitTypeRhs &rhs) noexcept
template<DimensionlessUnitType UnitTypeLhs, ArithmeticType T>
constexpr bool operator>= (const UnitTypeLhs &lhs, const T &rhs) noexcept
template<DimensionlessUnitType UnitTypeRhs, ArithmeticType T>
constexpr bool operator> (const T &lhs, const UnitTypeRhs &rhs) noexcept
template<DimensionlessUnitType UnitTypeLhs, ArithmeticType T>
constexpr bool operator> (const UnitTypeLhs &lhs, const T &rhs) noexcept
template<DimensionlessUnitType UnitTypeRhs, ArithmeticType T>
constexpr bool operator<= (const T &lhs, const UnitTypeRhs &rhs) noexcept
template<DimensionlessUnitType UnitTypeLhs, ArithmeticType T>
constexpr bool operator<= (const UnitTypeLhs &lhs, const T &rhs) noexcept
template<DimensionlessUnitType UnitTypeRhs, ArithmeticType T>
constexpr bool operator< (const T &lhs, const UnitTypeRhs &rhs) noexcept
template<DimensionlessUnitType UnitTypeLhs, ArithmeticType T>
constexpr bool operator< (const UnitTypeLhs &lhs, const T &rhs) noexcept
template<int power, UnitType UnitType>
requires (traits::has_linear_scale_v<UnitType>)
constexpr auto pow (const UnitType &value) noexcept -> detail::rewrap_to_named_t< unit< traits::strong_t< typename units::detail::power_of_unit< power, typename units::traits::unit_traits< UnitType >::conversion_factor >::type >, detail::floating_point_promotion_t< typename units::traits::unit_traits< UnitType >::underlying_type >, linear_scale > >
 computes the value of value raised to the power
template<class Arg>
requires ::std::is_arithmetic_v< Arg > decibels (Arg) -> decibels< Arg >
 Deduction guide so the BARE name works (no <>): decibels x(5.0) / constexpr decibels c(3e8) deduces.
 decibels () -> decibels< double >
 Nullary guide so bare default-construction decibels{} / decibels() deduces decibels<default> — again a.
template<class OtherUnit>
requires (::units::traits::is_unit<OtherUnit>::value && ::units::traits::is_same_dimension_unit_v<OtherUnit, ::units::unit
<traits::strong_t<dimensionless_>, typename ::units::traits::unit_traits<OtherUnit>::underlying_type,
::units::decibel_scale>>)
 decibels (const OtherUnit &) -> decibels<::units::detail::deduced_named_underlying_t< OtherUnit, traits::strong_t< dimensionless_ >, ::units::decibel_scale > >
 And from another same-dimension UNIT (bare): decibels x(otherUnit) deduces the underlying the converting.
template<class Rep, class Period>
 decibels (const ::std::chrono::duration< Rep, Period > &) -> decibels< double >
 And from a std::chrono::duration (bare, for time units): nanoseconds n(chrono::nanoseconds(10)) deduces.
template<class Underlying>
std::ostream & operator<< (std::ostream &os, const decibels< Underlying > &obj)
template<DimensionedUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_decibel_scale_v<UnitTypeLhs, UnitTypeRhs>)
auto operator+ (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept=delete
 Addition of two absolute decibel LEVELS (both dimensioned, same dimension — e.g.
template<DimensionlessUnitType UnitTypeLhs, DimensionlessUnitType UnitTypeRhs>
requires (traits::has_decibel_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr std::common_type_t< UnitTypeLhs, UnitTypeRhs > operator+ (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Addition of two dimensionless decibel GAINS (dB + dB).
template<DimensionedUnitType UnitTypeLhs, DimensionlessUnitType UnitTypeRhs>
requires (traits::has_decibel_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > operator+ (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Addition between unit types with a decibel_scale and dimensionless dB units.
template<DimensionlessUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (traits::has_decibel_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr traits::replace_underlying_t< UnitTypeRhs, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > operator+ (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Addition between unit types with a decibel_scale and dimensionless dB units.
template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_decibel_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr auto operator- (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept -> decibels< typename std::common_type_t< UnitTypeLhs, UnitTypeRhs >::underlying_type >
 Subtraction for convertible unit types with a decibel_scale.
template<DimensionedUnitType UnitTypeLhs, DimensionlessUnitType UnitTypeRhs>
requires (traits::has_decibel_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > operator- (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
 Subtraction between unit types with a decibel_scale and dimensionless dB units.
template<DimensionlessUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (traits::has_decibel_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr auto operator- (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept -> detail::rewrap_to_named_t< unit< traits::strong_t< inverse< typename traits::unit_traits< UnitTypeRhs >::conversion_factor > >, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type >, decibel_scale > >
 Subtraction between unit types with a decibel_scale and dimensionless dB units.
template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs>)
constexpr std::common_type_t< UnitTypeLhs, UnitTypeRhs > min (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs)
template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs>)
constexpr std::common_type_t< UnitTypeLhs, UnitTypeRhs > max (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs)
template<DimensionlessUnitType UnitType>
constexpr dimensionless< detail::floating_point_promotion_t< typename UnitType::underlying_type > > exp (const UnitType x) noexcept
 Compute exponential function.
template<DimensionlessUnitType UnitType>
constexpr dimensionless< detail::floating_point_promotion_t< typename UnitType::underlying_type > > log (const UnitType x) noexcept
 Compute natural logarithm.
template<DimensionlessUnitType UnitType>
constexpr dimensionless< detail::floating_point_promotion_t< typename UnitType::underlying_type > > log10 (const UnitType x) noexcept
 Compute common logarithm.
template<DimensionlessUnitType UnitType>
constexpr dimensionless< detail::floating_point_promotion_t< typename UnitType::underlying_type > > modf (const UnitType x, UnitType *intpart) noexcept
 Break into fractional and integral parts.
template<DimensionlessUnitType UnitType>
constexpr dimensionless< detail::floating_point_promotion_t< typename UnitType::underlying_type > > exp2 (const UnitType x) noexcept
 Compute binary exponential function.
template<DimensionlessUnitType UnitType>
constexpr dimensionless< detail::floating_point_promotion_t< typename UnitType::underlying_type > > expm1 (const UnitType x) noexcept
 Compute exponential minus one.
template<DimensionlessUnitType UnitType>
constexpr dimensionless< detail::floating_point_promotion_t< typename UnitType::underlying_type > > log1p (const UnitType x) noexcept
 Compute logarithm plus one.
template<DimensionlessUnitType UnitType>
constexpr dimensionless< detail::floating_point_promotion_t< typename UnitType::underlying_type > > log2 (const UnitType x) noexcept
 Compute binary logarithm.
template<UnitType UnitType>
requires (traits::has_linear_scale_v<UnitType>)
constexpr auto sqrt (const UnitType &value) noexcept -> detail::rewrap_to_named_t< unit< traits::strong_t< square_root< typename traits::unit_traits< UnitType >::conversion_factor > >, detail::floating_point_promotion_t< typename traits::unit_traits< UnitType >::underlying_type > > >
 computes the square root of value
template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
constexpr detail::floating_point_promotion_t< std::common_type_t< UnitTypeLhs, UnitTypeRhs > > hypot (const UnitTypeLhs &x, const UnitTypeRhs &y)
 Computes the square root of the sum-of-squares of x and y.
template<UnitType Unit>
constexpr detail::floating_point_promotion_t< Unit > ceil (const Unit x) noexcept
 Round up value.
template<UnitType Unit>
constexpr detail::floating_point_promotion_t< Unit > floor (const Unit x) noexcept
 Round down value.
template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs>)
constexpr detail::floating_point_promotion_t< std::common_type_t< UnitTypeLhs, UnitTypeRhs > > fmod (const UnitTypeLhs numer, const UnitTypeRhs denom) noexcept
 Compute remainder of division.
template<UnitType UnitType>
constexpr detail::floating_point_promotion_t< UnitType > trunc (const UnitType x) noexcept
 Truncate value.
template<UnitType UnitType>
constexpr detail::floating_point_promotion_t< UnitType > round (const UnitType x) noexcept
 Round to nearest.
template<class To, UnitType From>
requires detail::is_roundable_unit_conversion<To, From>
constexpr To floor (const From &x) noexcept
 Convert to a coarser integral unit, rounding down (toward negative infinity).
template<class To, UnitType From>
requires detail::is_roundable_unit_conversion<To, From>
constexpr To ceil (const From &x) noexcept
 Convert to a coarser integral unit, rounding up (toward positive infinity).
template<class To, UnitType From>
requires detail::is_roundable_unit_conversion<To, From>
constexpr To round (const From &x) noexcept
 Convert to a coarser integral unit, rounding to nearest (halfway away from zero).
template<class To, UnitType From>
requires detail::is_roundable_unit_conversion<To, From>
constexpr To trunc (const From &x) noexcept
 Convert to a coarser integral unit, rounding toward zero.
template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
constexpr detail::floating_point_promotion_t< UnitTypeLhs > copysign (const UnitTypeLhs x, const UnitTypeRhs y) noexcept
 Copy sign.
template<UnitType UnitTypeLhs, ArithmeticType T>
constexpr detail::floating_point_promotion_t< UnitTypeLhs > copysign (const UnitTypeLhs x, const T &y) noexcept
 Overload to copy the sign from a raw double.
template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs>)
constexpr detail::floating_point_promotion_t< std::common_type_t< UnitTypeLhs, UnitTypeRhs > > fdim (const UnitTypeLhs x, const UnitTypeRhs y) noexcept
 Positive difference.
template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs>)
constexpr detail::floating_point_promotion_t< std::common_type_t< UnitTypeLhs, UnitTypeRhs > > fmax (const UnitTypeLhs x, const UnitTypeRhs y) noexcept
 Maximum value.
template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs>)
constexpr detail::floating_point_promotion_t< std::common_type_t< UnitTypeLhs, UnitTypeRhs > > fmin (const UnitTypeLhs x, const UnitTypeRhs y) noexcept
 Minimum value.
template<UnitType UnitType>
constexpr detail::floating_point_promotion_t< UnitType > fabs (const UnitType x) noexcept
 Compute absolute value.
template<UnitType UnitType>
constexpr UnitType abs (const UnitType x) noexcept
 Compute absolute value.
template<UnitType UnitTypeLhs, UnitType UnitMultiply, UnitType UnitAdd>
requires (traits::is_same_dimension_conversion_factor_v< compound_conversion_factor<typename traits::unit_traits<UnitTypeLhs>
::conversion_factor, typename traits::unit_traits<UnitMultiply>::conversion_factor>, typename traits::unit_traits
<UnitAdd>::conversion_factor>)
constexpr auto fma (const UnitTypeLhs x, const UnitMultiply y, const UnitAdd z) noexcept -> std::common_type_t< decltype(detail::floating_point_promotion_t< UnitTypeLhs >(x) *detail::floating_point_promotion_t< UnitMultiply >(y)), UnitAdd >
 Multiply-add.
template<UnitType UnitType>
constexpr bool isnan (const UnitType &x) noexcept
template<UnitType UnitType>
constexpr bool isinf (const UnitType &x) noexcept
template<UnitType UnitType>
constexpr bool isfinite (const UnitType &x) noexcept
template<UnitType UnitType>
constexpr bool isnormal (const UnitType &x) noexcept
template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs>)
constexpr bool isunordered (const UnitTypeLhs &lhs, const UnitTypeRhs &rhs) noexcept
template<ArithmeticType Rep, RatioType Period>
 unit (std::chrono::duration< Rep, Period >) -> unit< conversion_factor< Period, dimension::time >, Rep >
template<ArithmeticType SourceTy, ConversionFactorType SourceCf>
requires (traits::is_unit_v<unit<SourceCf, SourceTy>> && PureDimensionlessCF<SourceCf>)
 unit (const unit< SourceCf, SourceTy > &) -> unit< conversion_factor< std::ratio< 1 >, dimension::dimensionless >, SourceTy >
template<ArithmeticType SourceTy, ConversionFactorType SourceCf, ConversionFactorType TargetCf = SourceCf>
requires (traits::is_unit_v<unit<SourceCf, SourceTy>> && traits::is_conversion_factor_v<TargetCf> &&
traits::is_same_dimension_conversion_factor_v<SourceCf, TargetCf> && !std::is_same_v<SourceCf, TargetCf> &&
detail::is_losslessly_convertible_unit<unit<SourceCf, SourceTy>, unit<TargetCf, SourceTy>>)
 unit (const unit< SourceCf, SourceTy > &) -> unit< TargetCf, SourceTy >
template<ArithmeticType SourceTy, ConversionFactorType SourceCf, ConversionFactorType TargetCf = SourceCf>
requires (traits::is_unit_v<unit<SourceCf, SourceTy>> && traits::is_conversion_factor_v<TargetCf> &&
traits::is_same_dimension_conversion_factor_v<SourceCf, TargetCf> && !std::is_same_v<SourceCf, TargetCf> &&
!detail::is_losslessly_convertible_unit<unit<SourceCf, SourceTy>, unit<TargetCf, SourceTy>>)
 unit (const unit< SourceCf, SourceTy > &) -> unit< TargetCf, detail::floating_point_promotion_t< SourceTy > >
template<ConversionFactorType TargetCf, ArithmeticType SourceTy>
requires traits::is_unit_v<unit<TargetCf, SourceTy>>
 unit (const unit< TargetCf, SourceTy > &) -> unit< TargetCf, SourceTy >
template<typename T, typename Cf = dimension::dimensionless, typename = std::enable_if_t<std::is_arithmetic_v<T>>>
 unit (T) -> unit< Cf, T >
template<std::size_t N>
 fixed_string (const char(&)[N]) -> fixed_string< N >
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto operator- (const absolute< U > &lhs, const absolute< V > &rhs) noexcept
 point - point -> delta, kept in the LHS unit (the datum offsets cancel).
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto operator+ (const absolute< U > &lhs, const delta< V > &rhs) noexcept
 point + delta -> point (move the point up by a relative amount), kept in the LHS point's unit.
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<V, U>
constexpr auto operator+ (const delta< V > &lhs, const absolute< U > &rhs) noexcept
 delta + point -> point (commutative form).
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto operator- (const absolute< U > &lhs, const delta< V > &rhs) noexcept
 point - delta -> point (move the point down by a relative amount), kept in the LHS point's unit.
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto operator+ (const delta< U > &lhs, const delta< V > &rhs) noexcept
 delta + delta -> delta, kept in the LHS unit (underlying promoted only if the RHS would narrow it).
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto operator- (const delta< U > &lhs, const delta< V > &rhs) noexcept
 delta - delta -> delta, kept in the LHS unit (underlying promoted only if the RHS would narrow it).
template<UnitType U>
constexpr delta< U > operator- (const delta< U > &d) noexcept
 Unary negation of a delta (an amount can be negated; a point cannot).
template<UnitType U, ArithmeticType T>
constexpr auto operator* (const delta< U > &lhs, T rhs) noexcept
 delta scaled by a bare number -> delta.
template<UnitType U, ArithmeticType T>
constexpr auto operator* (T lhs, const delta< U > &rhs) noexcept
template<UnitType U, ArithmeticType T>
constexpr auto operator/ (const delta< U > &lhs, T rhs) noexcept
 delta divided by a bare number -> delta (promotes like the wrapped unit's own operator/).
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr absolute< U > & operator+= (absolute< U > &lhs, const delta< V > &rhs) noexcept
 Compound move of a point by a delta.
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr absolute< U > & operator-= (absolute< U > &lhs, const delta< V > &rhs) noexcept
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr delta< U > & operator+= (delta< U > &lhs, const delta< V > &rhs) noexcept
 Compound add of a delta into a delta, in place (the lhs keeps its unit; the rhs is scale-converted).
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr delta< U > & operator-= (delta< U > &lhs, const delta< V > &rhs) noexcept
template<UnitType U, ArithmeticType T>
constexpr delta< U > & operator*= (delta< U > &lhs, T rhs) noexcept
 Compound scale of a delta by a bare number, in place (the underlying stays the lhs type, so the scaled result is assigned back through the lhs unit — an integer delta scaled by an integer stays integer, matching the plain unit's own operator*=).
template<UnitType U, ArithmeticType T>
constexpr delta< U > & operator/= (delta< U > &lhs, T rhs) noexcept
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr bool operator== (const absolute< U > &lhs, const absolute< V > &rhs) noexcept
 Compare two points (the datum is applied on each side as it unwraps to the plain unit).
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr std::partial_ordering operator<=> (const absolute< U > &lhs, const absolute< V > &rhs) noexcept
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr bool operator== (const delta< U > &lhs, const delta< V > &rhs) noexcept
 Compare two deltas.
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr std::partial_ordering operator<=> (const delta< U > &lhs, const delta< V > &rhs) noexcept
template<UnitType U>
std::ostream & operator<< (std::ostream &os, const absolute< U > &obj)
 Stream a point: its wrapped quantity, unmarked.
template<UnitType U>
std::ostream & operator<< (std::ostream &os, const delta< U > &obj)
 Stream a delta: a leading delta marker, then its wrapped quantity.
template<UnitType U>
std::string to_string (const absolute< U > &obj)
 String form of a point: its wrapped quantity, unmarked.
template<UnitType U>
std::string to_string (const delta< U > &obj)
 String form of a delta: a leading delta marker, then its wrapped quantity.
template<UnitType U>
constexpr auto abs (const delta< U > &d) noexcept
 Absolute magnitude of a delta (|amount|), promoting like the wrapped unit's units::abs.
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto min (const delta< U > &lhs, const delta< V > &rhs) noexcept
 The smaller of two deltas, kept in the LHS unit (scale-only reconciliation of the rhs).
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto max (const delta< U > &lhs, const delta< V > &rhs) noexcept
 The larger of two deltas, kept in the LHS unit (scale-only reconciliation of the rhs).
template<UnitType U, UnitType V, UnitType W>
requires (traits::is_same_dimension_unit_v<U, V> && traits::is_same_dimension_unit_v<U, W>)
constexpr auto clamp (const delta< U > &value, const delta< V > &lo, const delta< W > &hi) noexcept
 Clamp a delta into [lo, hi], kept in the value's LHS unit.
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto min (const absolute< U > &lhs, const absolute< V > &rhs) noexcept
 The smaller of two points, kept in the LHS unit (affine reconciliation of the rhs).
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto max (const absolute< U > &lhs, const absolute< V > &rhs) noexcept
 The larger of two points, kept in the LHS unit (affine reconciliation of the rhs).
template<UnitType U, UnitType V, UnitType W>
requires (traits::is_same_dimension_unit_v<U, V> && traits::is_same_dimension_unit_v<U, W>)
constexpr auto clamp (const absolute< U > &value, const absolute< V > &lo, const absolute< W > &hi) noexcept
 Clamp a point into [lo, hi], kept in the value's LHS unit.
template<UnitType U, ArithmeticType T>
constexpr auto operator* (const absolute< U > &lhs, T) noexcept
 Scaling or dividing a POINT is meaningless — a point has no magnitude; only a delta (an amount) scales.
template<UnitType U, ArithmeticType T>
constexpr auto operator* (T, const absolute< U > &rhs) noexcept
template<UnitType U, ArithmeticType T>
constexpr auto operator/ (const absolute< U > &lhs, T) noexcept
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto operator/ (const absolute< U > &lhs, const absolute< V > &) noexcept
 Dividing a POINT by a POINT is meaningless — there is no ratio of two absolute positions.
template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto operator+ (const absolute< U > &lhs, const absolute< V > &) noexcept
 Summing two POINTS is meaningless (the sum of two positions has no meaning); subtract them for a delta, or add a delta to move a point.
template<UnitType U, ArithmeticType T>
constexpr auto operator+ (const delta< U > &lhs, T) noexcept
 A delta/absolute does not combine with a BARE NUMBER — an amount adds an amount, a point moves by an amount.
template<UnitType U, ArithmeticType T>
constexpr auto operator- (const delta< U > &lhs, T) noexcept
template<UnitType U, ArithmeticType T>
constexpr auto operator+ (const absolute< U > &lhs, T) noexcept
template<fixed_string Tag, UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto operator+ (const basic_kind< Tag, U > &lhs, const basic_kind< Tag, V > &rhs) noexcept
 kind + kind (same tag) -> kind, kept in the LHS unit.
template<fixed_string Tag, UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto operator- (const basic_kind< Tag, U > &lhs, const basic_kind< Tag, V > &rhs) noexcept
 kind - kind (same tag) -> kind, kept in the LHS unit.
template<fixed_string Tag, UnitType U>
constexpr basic_kind< Tag, U > operator- (const basic_kind< Tag, U > &k) noexcept
 Unary negation of a kind (keeps the tag).
template<fixed_string Tag, UnitType U, ArithmeticType T>
constexpr auto operator* (const basic_kind< Tag, U > &lhs, T rhs) noexcept
 kind scaled by a bare number -> kind (same tag), promoting like the wrapped unit's own operator*.
template<fixed_string Tag, UnitType U, ArithmeticType T>
constexpr auto operator* (T lhs, const basic_kind< Tag, U > &rhs) noexcept
template<fixed_string Tag, UnitType U, ArithmeticType T>
constexpr auto operator/ (const basic_kind< Tag, U > &lhs, T rhs) noexcept
 kind divided by a bare number -> kind (same tag).
template<fixed_string Tag, UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto operator/ (const basic_kind< Tag, U > &lhs, const basic_kind< Tag, V > &rhs) noexcept
 The ratio of two SAME-tag kinds is a plain dimensionless quantity — the tag cancels, exactly as the ratio of two lengths is a number.
template<fixed_string Tag, UnitType U, ArithmeticType T>
constexpr basic_kind< Tag, U > & operator*= (basic_kind< Tag, U > &lhs, T rhs) noexcept
 Compound scale of a same-tag kind by a bare number, in place (mirrors delta's *=//=).
template<fixed_string Tag, UnitType U, ArithmeticType T>
constexpr basic_kind< Tag, U > & operator/= (basic_kind< Tag, U > &lhs, T rhs) noexcept
template<fixed_string Tag, UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr basic_kind< Tag, U > & operator+= (basic_kind< Tag, U > &lhs, const basic_kind< Tag, V > &rhs) noexcept
 Compound add/subtract of a same-tag kind, in place (the rhs is converted to the lhs unit).
template<fixed_string Tag, UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr basic_kind< Tag, U > & operator-= (basic_kind< Tag, U > &lhs, const basic_kind< Tag, V > &rhs) noexcept
template<fixed_string Tag, UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr bool operator== (const basic_kind< Tag, U > &lhs, const basic_kind< Tag, V > &rhs) noexcept
 Compare two kinds of the SAME tag; the wrapped plain units compare (inheriting the core's value-based, signedness-safe integer comparison).
template<fixed_string Tag, UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr std::partial_ordering operator<=> (const basic_kind< Tag, U > &lhs, const basic_kind< Tag, V > &rhs) noexcept
template<fixed_string TagL, fixed_string TagR, UnitType U, UnitType V>
requires (!(TagL == TagR))
constexpr auto operator+ (const basic_kind< TagL, U > &, const basic_kind< TagR, V > &) noexcept
template<fixed_string TagL, fixed_string TagR, UnitType U, UnitType V>
requires (!(TagL == TagR))
constexpr auto operator- (const basic_kind< TagL, U > &, const basic_kind< TagR, V > &) noexcept
template<fixed_string TagL, fixed_string TagR, UnitType U, UnitType V>
requires (!(TagL == TagR))
constexpr bool operator== (const basic_kind< TagL, U > &, const basic_kind< TagR, V > &) noexcept
template<fixed_string Tag, UnitType U, UnitType Plain>
constexpr auto operator+ (const basic_kind< Tag, U > &lhs, const Plain &) noexcept
template<fixed_string Tag, UnitType U, UnitType Plain>
constexpr auto operator+ (const Plain &, const basic_kind< Tag, U > &rhs) noexcept
template<fixed_string Tag, UnitType U, UnitType Plain>
constexpr auto operator- (const basic_kind< Tag, U > &lhs, const Plain &) noexcept
template<fixed_string Tag, UnitType U, ArithmeticType T>
constexpr auto operator+ (const basic_kind< Tag, U > &lhs, T) noexcept
template<fixed_string Tag, UnitType U, ArithmeticType T>
constexpr auto operator+ (T, const basic_kind< Tag, U > &rhs) noexcept
template<fixed_string Tag, UnitType U, ArithmeticType T>
constexpr auto operator- (const basic_kind< Tag, U > &lhs, T) noexcept
template<fixed_string Tag, UnitType U>
std::ostream & operator<< (std::ostream &os, const basic_kind< Tag, U > &obj)
 Stream a kind: its tag in brackets, then its wrapped quantity (e.g. [radial] 5 m).
template<fixed_string Tag, UnitType U>
std::string to_string (const basic_kind< Tag, U > &obj)
 String form of a kind: its tag in brackets, then its wrapped value.
template<fixed_string Tag, UnitType U>
constexpr auto abs (const basic_kind< Tag, U > &k) noexcept
 Absolute magnitude of a kind (|value|), keeping the tag, promoting like the wrapped unit's units::abs.
template<fixed_string Tag, UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto min (const basic_kind< Tag, U > &lhs, const basic_kind< Tag, V > &rhs) noexcept
 The smaller of two same-tag kinds, kept in the LHS unit (the tag is preserved).
template<fixed_string Tag, UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
constexpr auto max (const basic_kind< Tag, U > &lhs, const basic_kind< Tag, V > &rhs) noexcept
 The larger of two same-tag kinds, kept in the LHS unit (the tag is preserved).
template<fixed_string Tag, UnitType U, UnitType V, UnitType W>
requires (traits::is_same_dimension_unit_v<U, V> && traits::is_same_dimension_unit_v<U, W>)
constexpr auto clamp (const basic_kind< Tag, U > &value, const basic_kind< Tag, V > &lo, const basic_kind< Tag, W > &hi) noexcept
 Clamp a same-tag kind into [lo, hi], kept in the value's LHS unit.
std::ostream & operator<< (std::ostream &os, const any_unit &value)
 writes an erased quantity's self-describing BINARY bytes to a stream
template<class Target>
Target unit_cast (const any_unit &value)
 explicit cast from an erased any_unit to a concrete unit, throwing on a dimension mismatch
template<class Unit>
any_unit serialize (const Unit &quantity)
 serializes a quantity to a self-describing, erased any_unit
std::expected< any_unit, deserialize_errordeserialize (std::span< const std::byte > bytes)
 decodes a self-describing byte stream into an erased quantity
template<class Unit>
std::expected< Unit, deserialize_errordeserialize (std::span< const std::byte > bytes)
 decodes a self-describing byte stream directly into a known unit type (fully static)
std::expected< any_unit, deserialize_errordeserialize (std::istream &is)
 reads and decodes one self-describing erased quantity from a binary stream, in a single expression
std::istream & operator>> (std::istream &is, any_unit &value)
 reads one self-describing erased quantity from a binary stream (classic stream-extraction form)
template<class Unit>
std::expected< Unit, deserialize_errordeserialize (std::istream &is)
 reads and decodes one record from a binary stream directly into a known unit type
 UNIT_ADD_STRONG_CONVERSION_FACTOR (time, minutes, conversion_factor< std::ratio< 60 >, seconds_ >) UNIT_ADD_UNIT_DEFINITION(time
conversion_factor< std::ratio< 60 >, seconds_ > UNIT_ADD_NAME (time, minutes, min) UNIT_REGISTER_NAMED_CLASS(time

Variables

template<class Unit>
constexpr const char * unit_name_v = unit_name<Unit>::value
template<class Unit>
constexpr const char * unit_abbreviation_v = unit_abbreviation<Unit>::value
constexpr linearized_value_t linearized_value {}
 minutes

Detailed Description

Unit Conversion Library namespace.

Typedef Documentation

◆ kind

template<affine::fixed_string Tag, UnitType U>
using units::kind = affine::basic_kind<Tag, U>

The preferred user-facing spelling of a string-tagged quantity kind: units::kind<"radial", meters<double>>.

It resolves to the underlying basic_kind.

Enumeration Type Documentation

◆ deserialize_error

enum class units::deserialize_error
strong

the reasons a deserialize can fail

Enumerator
truncated 

the byte range ended before a complete quantity was read

bad_version 

the stream's format version is not understood

dimension_mismatch 

the stream's dimension does not match the requested target

unknown_base_dimension 

the stream names a base-dimension code this build does not know

lossy_target 

the value cannot be represented in the requested underlying type without loss

Function Documentation

◆ decibels() [1/4]

units::decibels ( ) -> decibels< double >

Nullary guide so bare default-construction decibels{} / decibels() deduces decibels<default> — again a.

CLASS template needs this where the old alias resolved via its default arg; GCC 13 requires it explicitly.

◆ decibels() [2/4]

template<class Arg>
requires ::std::is_arithmetic_v< Arg > units::decibels ( Arg ) -> decibels< Arg >

Deduction guide so the BARE name works (no <>): decibels x(5.0) / constexpr decibels c(3e8) deduces.

decibels<double>. As an ALIAS template (pre-refactor) a bare name resolved via the default arg; as a CLASS template CTAD is required, and some compilers (e.g. GCC 13) will not deduce it from an arithmetic argument without this guide. Constrained to arithmetic so it never competes with the base/converting constructors.

◆ decibels() [3/4]

template<class Rep, class Period>
units::decibels ( const ::std::chrono::duration< Rep, Period > & ) -> decibels< double >

And from a std::chrono::duration (bare, for time units): nanoseconds n(chrono::nanoseconds(10)) deduces.

the default underlying; the chrono converting constructor does the Rep/Period conversion. GCC 13 needs the explicit guide.

◆ decibels() [4/4]

template<class OtherUnit>
requires (::units::traits::is_unit<OtherUnit>::value && ::units::traits::is_same_dimension_unit_v<OtherUnit, ::units::unit
<traits::strong_t<dimensionless_>, typename ::units::traits::unit_traits<OtherUnit>::underlying_type,
::units::decibel_scale>>)
units::decibels ( const OtherUnit & ) -> decibels<::units::detail::deduced_named_underlying_t< OtherUnit, traits::strong_t< dimensionless_ >, ::units::decibel_scale > >

And from another same-dimension UNIT (bare): decibels x(otherUnit) deduces the underlying the converting.

constructor would produce — the SOURCE underlying when losslessly convertible to this named unit, else its floating-point promotion (so e.g. radians r(degrees{1}) deduces radians<double>, since degrees->radians is not integer-lossless). GCC 13 will not deduce this implicitly (GCC 15 will), so the guide is required; constrained to unit types so it never competes with the arithmetic/nullary guides.

◆ deserialize() [1/4]

template<class Unit>
std::expected< Unit, deserialize_error > units::deserialize ( std::istream & is)
nodiscard

reads and decodes one record from a binary stream directly into a known unit type

The single-check read: auto q = deserialize<meters<double>>(file); reads the next record and collapses it in one step, so one if (q) guards both the read and the dimension match (a mismatch or a malformed record is a deserialize_error). Same seekable-stream requirement as deserialize(std::istream&).

Template Parameters
Unitthe expected unit type
Parameters
[in]isthe input stream, positioned at the start of a record
Returns
the value as Unit on success, else a deserialize_error

◆ deserialize() [2/4]

std::expected< any_unit, deserialize_error > units::deserialize ( std::istream & is)
inlinenodiscard

reads and decodes one self-describing erased quantity from a binary stream, in a single expression

The stream counterpart to deserialize(span): auto q = deserialize(file); reads the next record written by stream << serialize(q) with no pre-declared value and no manual buffer. A record is self-delimiting, so this decodes exactly one and rewinds the stream to just past it (a subsequent read gets the following record); the stream must be seekable (a file or memory stream, opened in binary mode) and, for a non-seekable stream such as a live socket, frame the records yourself and call deserialize(span) on each frame.

Parameters
[in]isthe input stream, positioned at the start of a record
Returns
the decoded any_unit, or a deserialize_error

◆ deserialize() [3/4]

template<class Unit>
std::expected< Unit, deserialize_error > units::deserialize ( std::span< const std::byte > bytes)
nodiscard

decodes a self-describing byte stream directly into a known unit type (fully static)

Template Parameters
Unitthe expected unit type
Parameters
[in]bytesthe encoded stream
Returns
the value as Unit on success, else a deserialize_error

◆ deserialize() [4/4]

std::expected< any_unit, deserialize_error > units::deserialize ( std::span< const std::byte > bytes)
inlinenodiscard

decodes a self-describing byte stream into an erased quantity

Decodes exactly one record from the front of bytes; any trailing bytes (a following record) are ignored. The decoded record's byte length is result->size() — a reader consuming a sequence advances by that to reach the next record (this is how operator>> reads records back-to-back).

Parameters
[in]bytesthe encoded stream
Returns
an any_unit on success, else a deserialize_error

◆ operator%() [1/2]

template<DimensionlessUnitType UnitTypeLhs, DimensionlessUnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
traits::replace_underlying_t< UnitTypeLhs, typename std::common_type_t< UnitTypeLhs, UnitTypeRhs >::underlying_type > units::operator% ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs )
constexprnoexcept

Modulo for two dimensionless unit types with a linear scale.

Returns
the lhs value modulo the rhs value, whose type is their common type

◆ operator%() [2/2]

template<DimensionedUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
std::common_type_t< UnitTypeLhs, UnitTypeRhs > units::operator% ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs )
constexprnoexcept

Modulo for convertible unit types with a linear scale.

Returns
the lhs value modulo the rhs value, in their common (finer) unit.
Note
The result is the std::common_type of the operands — the finer of the two units — not the lhs unit. Returning the lhs unit made the operator order-dependent: meters % kilometers compiled (finer lhs) but kilometers % meters did not (converting the finer common result back to the coarser lhs is lossy for an integer underlying, disabling the constructor). The common-unit result mirrors fmod and removes the asymmetry.

◆ operator*() [1/4]

template<UnitType U, ArithmeticType T>
auto units::affine::operator* ( const delta< U > & lhs,
T rhs )
constexprnoexcept

delta scaled by a bare number -> delta.

The underlying type promotes exactly as the wrapped unit's own operator* does (scaling an integer delta by a floating factor yields a floating delta — the wrapper is never less precise than the unit it wraps).

◆ operator*() [2/4]

template<DimensionedUnitType UnitTypeLhs, RatioDimensionlessUnitType UnitTypeRhs>
requires (traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > units::operator* ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs )
constexprnoexcept

Multiplication by a ratio-dimensionless unit for unit types with a linear scale.

Treat ratio-dimensionless as a scalar (normalized fraction).

◆ operator*() [3/4]

template<DimensionedUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (!same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
auto units::operator* ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs ) -> detail::rewrap_to_named_t< unit< traits::strong_t< compound_conversion_factor< typename traits::unit_traits< UnitTypeLhs >::conversion_factor, typename traits::unit_traits< UnitTypeRhs >::conversion_factor > >, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > >
constexprnoexcept

Multiplication type for non-convertible unit types with a linear scale.

Returns
the multiplied value, whose type is a compound unit of the left and right hand side values.

◆ operator*() [4/4]

template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
auto units::operator* ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs ) -> detail::rewrap_to_named_t< unit< traits::strong_t< squared< typename traits::unit_traits< std::common_type_t< UnitTypeLhs, UnitTypeRhs > >::conversion_factor > >, typename std::common_type_t< UnitTypeLhs, UnitTypeRhs >::underlying_type > >
constexprnoexcept

Multiplication type for convertible unit types with a linear scale.

Returns
the multiplied value, with the same type as left-hand side unit.

◆ operator+() [1/10]

template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
auto units::affine::operator+ ( const absolute< U > & lhs,
const delta< V > & rhs )
constexprnoexcept

point + delta -> point (move the point up by a relative amount), kept in the LHS point's unit.

A point has a datum, and reconciling two affine frames to a common unit mangles the datum; only the delta (offset-free) is converted, scale-only, into the point's unit.

◆ operator+() [2/10]

template<UnitType U, ArithmeticType T>
auto units::affine::operator+ ( const delta< U > & lhs,
T  )
constexprnoexcept

A delta/absolute does not combine with a BARE NUMBER — an amount adds an amount, a point moves by an amount.

Wrap the number in a delta of the same unit.

◆ operator+() [3/10]

template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<V, U>
auto units::affine::operator+ ( const delta< V > & lhs,
const absolute< U > & rhs )
constexprnoexcept

delta + point -> point (commutative form).

The result keeps the POINT's unit (the point is the affine operand), matching point + delta.

◆ operator+() [4/10]

template<DimensionlessUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (traits::has_decibel_scale_v<UnitTypeLhs, UnitTypeRhs>)
traits::replace_underlying_t< UnitTypeRhs, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > units::operator+ ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs )
constexprdeletenoexcept

Addition between unit types with a decibel_scale and dimensionless dB units.

Addition of two absolute decibel LEVELS (both dimensioned, same dimension — e.g.

Addition operator for unit types with a linear_scale.

dBW + dBW) is ill-formed. A dimensioned decibel value is an absolute point on a logarithmic reference scale, exactly like an affine temperature: dBW + dBW is a point + point, which has no meaning (two 10 dBW sources are not a 20 dBW source). The defined operations are level + gain -> level (add a dimensionless dB gain), gain + gain -> gain, and level - level -> gain. To combine two independent power levels, add them in the linear domain (two equal powers sum to +3 dB), not by adding their dB numbers.

Addition of two absolute decibel LEVELS (both dimensioned, same dimension — e.g.

Note
Disabled when either operand is AFFINE (carries a datum offset, e.g. degrees Celsius): summing two offset quantities adds their datums, which is arithmetically corrupt (20 degC + 5 degC is not 25 degC in any absolute sense). Zero-offset scales of the same dimension (including kelvin and rankine) add normally — the sum is well-defined arithmetically even where it is rarely the physically intended operation.

The result is expressed in the LEFT operand's unit, so the caller controls the result unit by operand order (meters + feet is meters, feet + meters is feet) and the value reads in the unit they named. The underlying is widened only when the left operand's is integral and the right cannot convert into it without truncation, in which case the result reconciles to the common (finest, lossless) unit — the same exact behavior integer comparisons rely on.

◆ operator+() [5/10]

template<DimensionedUnitType UnitTypeLhs, DimensionlessUnitType UnitTypeRhs>
requires (traits::has_decibel_scale_v<UnitTypeLhs, UnitTypeRhs>)
traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > units::operator+ ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs )
constexprdeletenoexcept

Addition between unit types with a decibel_scale and dimensionless dB units.

Addition of two absolute decibel LEVELS (both dimensioned, same dimension — e.g.

Addition operator for unit types with a linear_scale.

dBW + dBW) is ill-formed. A dimensioned decibel value is an absolute point on a logarithmic reference scale, exactly like an affine temperature: dBW + dBW is a point + point, which has no meaning (two 10 dBW sources are not a 20 dBW source). The defined operations are level + gain -> level (add a dimensionless dB gain), gain + gain -> gain, and level - level -> gain. To combine two independent power levels, add them in the linear domain (two equal powers sum to +3 dB), not by adding their dB numbers.

Addition of two absolute decibel LEVELS (both dimensioned, same dimension — e.g.

Note
Disabled when either operand is AFFINE (carries a datum offset, e.g. degrees Celsius): summing two offset quantities adds their datums, which is arithmetically corrupt (20 degC + 5 degC is not 25 degC in any absolute sense). Zero-offset scales of the same dimension (including kelvin and rankine) add normally — the sum is well-defined arithmetically even where it is rarely the physically intended operation.

The result is expressed in the LEFT operand's unit, so the caller controls the result unit by operand order (meters + feet is meters, feet + meters is feet) and the value reads in the unit they named. The underlying is widened only when the left operand's is integral and the right cannot convert into it without truncation, in which case the result reconciles to the common (finest, lossless) unit — the same exact behavior integer comparisons rely on.

◆ operator+() [6/10]

template<DimensionlessUnitType UnitTypeLhs, DimensionlessUnitType UnitTypeRhs>
requires (traits::has_decibel_scale_v<UnitTypeLhs, UnitTypeRhs>)
std::common_type_t< UnitTypeLhs, UnitTypeRhs > units::operator+ ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs )
constexprdeletenoexcept

Addition of two dimensionless decibel GAINS (dB + dB).

Addition of two absolute decibel LEVELS (both dimensioned, same dimension — e.g.

Both are relative ratios, so their dB numbers add (a linear multiplication of the ratios): 3 dB + 3 dB is 6 dB. The result is a dimensionless dB gain.

Addition operator for unit types with a linear_scale.

dBW + dBW) is ill-formed. A dimensioned decibel value is an absolute point on a logarithmic reference scale, exactly like an affine temperature: dBW + dBW is a point + point, which has no meaning (two 10 dBW sources are not a 20 dBW source). The defined operations are level + gain -> level (add a dimensionless dB gain), gain + gain -> gain, and level - level -> gain. To combine two independent power levels, add them in the linear domain (two equal powers sum to +3 dB), not by adding their dB numbers.

Addition of two absolute decibel LEVELS (both dimensioned, same dimension — e.g.

Note
Disabled when either operand is AFFINE (carries a datum offset, e.g. degrees Celsius): summing two offset quantities adds their datums, which is arithmetically corrupt (20 degC + 5 degC is not 25 degC in any absolute sense). Zero-offset scales of the same dimension (including kelvin and rankine) add normally — the sum is well-defined arithmetically even where it is rarely the physically intended operation.

The result is expressed in the LEFT operand's unit, so the caller controls the result unit by operand order (meters + feet is meters, feet + meters is feet) and the value reads in the unit they named. The underlying is widened only when the left operand's is integral and the right cannot convert into it without truncation, in which case the result reconciles to the common (finest, lossless) unit — the same exact behavior integer comparisons rely on.

◆ operator+() [7/10]

template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs> &&
!traits::is_affine_unit_v<UnitTypeLhs> && !traits::is_affine_unit_v<UnitTypeRhs>)
auto units::operator+ ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs )
constexprdeletenoexcept

Addition operator for unit types with a linear_scale.

Addition of two absolute decibel LEVELS (both dimensioned, same dimension — e.g.

Note
Disabled when either operand is AFFINE (carries a datum offset, e.g. degrees Celsius): summing two offset quantities adds their datums, which is arithmetically corrupt (20 degC + 5 degC is not 25 degC in any absolute sense). Zero-offset scales of the same dimension (including kelvin and rankine) add normally — the sum is well-defined arithmetically even where it is rarely the physically intended operation.

The result is expressed in the LEFT operand's unit, so the caller controls the result unit by operand order (meters + feet is meters, feet + meters is feet) and the value reads in the unit they named. The underlying is widened only when the left operand's is integral and the right cannot convert into it without truncation, in which case the result reconciles to the common (finest, lossless) unit — the same exact behavior integer comparisons rely on.

Addition operator for unit types with a linear_scale.

dBW + dBW) is ill-formed. A dimensioned decibel value is an absolute point on a logarithmic reference scale, exactly like an affine temperature: dBW + dBW is a point + point, which has no meaning (two 10 dBW sources are not a 20 dBW source). The defined operations are level + gain -> level (add a dimensionless dB gain), gain + gain -> gain, and level - level -> gain. To combine two independent power levels, add them in the linear domain (two equal powers sum to +3 dB), not by adding their dB numbers.

◆ operator+() [8/10]

template<DimensionedUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_decibel_scale_v<UnitTypeLhs, UnitTypeRhs>)
auto units::operator+ ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs )
constexprdeletenoexcept

Addition of two absolute decibel LEVELS (both dimensioned, same dimension — e.g.

Addition operator for unit types with a linear_scale.

dBW + dBW) is ill-formed. A dimensioned decibel value is an absolute point on a logarithmic reference scale, exactly like an affine temperature: dBW + dBW is a point + point, which has no meaning (two 10 dBW sources are not a 20 dBW source). The defined operations are level + gain -> level (add a dimensionless dB gain), gain + gain -> gain, and level - level -> gain. To combine two independent power levels, add them in the linear domain (two equal powers sum to +3 dB), not by adding their dB numbers.

Addition of two absolute decibel LEVELS (both dimensioned, same dimension — e.g.

Note
Disabled when either operand is AFFINE (carries a datum offset, e.g. degrees Celsius): summing two offset quantities adds their datums, which is arithmetically corrupt (20 degC + 5 degC is not 25 degC in any absolute sense). Zero-offset scales of the same dimension (including kelvin and rankine) add normally — the sum is well-defined arithmetically even where it is rarely the physically intended operation.

The result is expressed in the LEFT operand's unit, so the caller controls the result unit by operand order (meters + feet is meters, feet + meters is feet) and the value reads in the unit they named. The underlying is widened only when the left operand's is integral and the right cannot convert into it without truncation, in which case the result reconciles to the common (finest, lossless) unit — the same exact behavior integer comparisons rely on.

◆ operator+() [9/10]

template<DimensionlessUnitType UnitTypeLhs, ArithmeticType T>
requires (traits::has_linear_scale_v<UnitTypeLhs> && !RatioDimensionlessUnitType<UnitTypeLhs> && !RatioDimensionlessUnitType
<UnitTypeLhs>)
traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, T > > units::operator+ ( const UnitTypeLhs & lhs,
T rhs )
constexprnoexcept

Addition operator for dimensionless unit types with a linear_scale.

dimensionless types can be implicitly converted to built-in types.

◆ operator+() [10/10]

template<DimensionlessUnitType UnitTypeRhs, ArithmeticType T>
requires (traits::has_linear_scale_v<UnitTypeRhs> && !RatioDimensionlessUnitType<UnitTypeRhs>)
traits::replace_underlying_t< UnitTypeRhs, std::common_type_t< T, typename UnitTypeRhs::underlying_type > > units::operator+ ( T lhs,
const UnitTypeRhs & rhs )
constexprnoexcept

Addition operator for dimensionless unit types with a linear_scale.

dimensionless types can be implicitly converted to built-in types.

◆ operator+=() [1/2]

template<UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
absolute< U > & units::affine::operator+= ( absolute< U > & lhs,
const delta< V > & rhs )
constexprnoexcept

Compound move of a point by a delta.

The point stays in its own unit (in-place semantics), so the rhs delta is converted to the lhs unit; this is well-formed whenever that conversion is (a lossy integer case is cleanly rejected by the delta conversion, as elsewhere in the library).

◆ operator+=() [2/2]

template<UnitType UnitTypeLhs>
requires (traits::is_affine_unit_v<UnitTypeLhs>)
UnitTypeLhs & units::operator+= ( UnitTypeLhs & lhs,
const detail::type_identity_t< UnitTypeLhs > & rhs )
constexprnoexcept

Compound addition for AFFINE units (e.g.

temperatures). The lhs is an absolute point; the rhs is interpreted as a RELATIVE delta and the point is moved in place by that magnitude, staying in the lhs unit (celsius(20) += celsius(5) -> celsius(25), i.e. "warm by 5 degrees"). The rhs's datum offset is intentionally not applied — only its magnitude in the lhs unit matters for a delta. (Binary a + b of two absolute affine points is disabled; use += to move a point by a relative amount.)

◆ operator-() [1/4]

template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs> &&
(traits::is_affine_unit_v<UnitTypeLhs> || traits::is_affine_unit_v<UnitTypeRhs>))
auto units::operator- ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs )
constexprnoexcept

Subtraction operator for AFFINE unit types (e.g.

temperatures with a datum offset).

The difference of two absolute affine quantities is a DELTA: the datum offsets cancel, so the result must be a pure (non-affine) quantity — otherwise storing it back into an affine unit would re-apply the offset (e.g. celsius(0) - kelvin(0) would read 546.30 K instead of the true 273.15 K delta). Both operands are reconciled to their common affine unit, their raw values subtracted (the offsets cancel exactly), and the result returned in the offset-stripped counterpart of that common unit so it never re-applies a datum.

◆ operator-() [2/4]

template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires (same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs> &&
!traits::is_affine_unit_v<UnitTypeLhs> && !traits::is_affine_unit_v<UnitTypeRhs>)
auto units::operator- ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs )
constexprnoexcept

Subtraction operator for NON-AFFINE unit types with a linear_scale.

Like operator+, the result is in the LEFT operand's unit (caller controls the result unit by operand order), widening to the common lossless unit only when the left operand is integral and cannot hold the right without truncation.

◆ operator-() [3/4]

template<DimensionlessUnitType UnitTypeLhs, ArithmeticType T>
requires (traits::has_linear_scale_v<UnitTypeLhs> && !RatioDimensionlessUnitType<UnitTypeLhs>)
traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, T > > units::operator- ( const UnitTypeLhs & lhs,
T rhs )
constexprnoexcept

Subtraction operator for dimensionless unit types with a linear_scale.

dimensionless types can be implicitly converted to built-in types.

◆ operator-() [4/4]

template<DimensionlessUnitType UnitTypeRhs, ArithmeticType T>
requires (traits::has_linear_scale_v<UnitTypeRhs> && !RatioDimensionlessUnitType<UnitTypeRhs>)
traits::replace_underlying_t< UnitTypeRhs, std::common_type_t< T, typename UnitTypeRhs::underlying_type > > units::operator- ( T lhs,
const UnitTypeRhs & rhs )
constexprnoexcept

Subtraction operator for dimensionless unit types with a linear_scale.

dimensionless types can be implicitly converted to built-in types.

◆ operator-=()

template<UnitType UnitTypeLhs>
requires (traits::is_affine_unit_v<UnitTypeLhs>)
UnitTypeLhs & units::operator-= ( UnitTypeLhs & lhs,
const detail::type_identity_t< UnitTypeLhs > & rhs )
constexprnoexcept

Compound subtraction for AFFINE units (e.g.

temperatures). The lhs is an absolute point; the rhs is interpreted as a RELATIVE delta and the point is moved down in place by that magnitude, staying in the lhs unit (celsius(20) -= celsius(5) -> celsius(15), i.e. "cool by 5 degrees"). The rhs's datum offset is intentionally not applied. (Binary a - b of two absolute affine points yields a non-affine delta; use -= to move a point down by a relative amount.)

◆ operator/() [1/6]

template<fixed_string Tag, UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
auto units::affine::operator/ ( const basic_kind< Tag, U > & lhs,
const basic_kind< Tag, V > & rhs )
constexprnoexcept

The ratio of two SAME-tag kinds is a plain dimensionless quantity — the tag cancels, exactly as the ratio of two lengths is a number.

(Different tags do not divide; that stays ill-formed.)

◆ operator/() [2/6]

template<DimensionedUnitType UnitTypeLhs, RatioDimensionlessUnitType UnitTypeRhs>
requires (traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
traits::replace_underlying_t< UnitTypeLhs, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > units::operator/ ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs )
constexprnoexcept

Division by a ratio-dimensionless unit for unit types with a linear scale.

Treat ratio-dimensionless as a scalar (normalized fraction).

◆ operator/() [3/6]

template<UnitType UnitTypeLhs, UnitType UnitTypeRhs>
requires ( same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs> &&
!RatioDimensionlessUnitType<UnitTypeLhs> && !RatioDimensionlessUnitType<UnitTypeRhs>)
dimensionless< std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > units::operator/ ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs )
constexprnoexcept

Division for convertible unit types with a linear scale.

Returns
the lhs divided by rhs value, whose type is a dimensionless

◆ operator/() [4/6]

template<DimensionedUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (!same_dimension<UnitTypeLhs, UnitTypeRhs> && traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
auto units::operator/ ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs ) -> detail::rewrap_to_named_t< unit< traits::strong_t< compound_conversion_factor< typename traits::unit_traits< UnitTypeLhs >::conversion_factor, inverse< typename traits::unit_traits< UnitTypeRhs >::conversion_factor > > >, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > >
constexprnoexcept

Division for non-convertible unit types with a linear scale.

Returns
the lhs divided by the rhs, with a compound unit type of lhs/rhs

◆ operator/() [5/6]

template<OrdinaryDimensionlessUnitType UnitTypeLhs, RatioDimensionlessUnitType UnitTypeRhs>
requires (traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
auto units::operator/ ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs ) -> detail::rewrap_to_named_t< unit< traits::strong_t< inverse< typename traits::unit_traits< UnitTypeRhs >::conversion_factor > >, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > > >
constexprnoexcept

Division of an ordinary dimensionless unit by a ratio-dimensionless unit.

Produces inverse<ratio-dimensionless> (compound) and uses raw() for rhs.

◆ operator/() [6/6]

template<RatioDimensionlessUnitType UnitTypeLhs, DimensionedUnitType UnitTypeRhs>
requires (traits::has_linear_scale_v<UnitTypeLhs, UnitTypeRhs>)
auto units::operator/ ( const UnitTypeLhs & lhs,
const UnitTypeRhs & rhs ) -> unit< traits::strong_t< compound_conversion_factor< typename traits::unit_traits< UnitTypeLhs >::conversion_factor, inverse< typename traits::unit_traits< UnitTypeRhs >::conversion_factor > > >, std::common_type_t< typename UnitTypeLhs::underlying_type, typename UnitTypeRhs::underlying_type > >
constexprnoexcept

Division of a ratio-dimensionless unit (pct/ppm/ppb/...) by a dimensioned unit.

This MUST preserve the numerator ratio semantics (do NOT collapse to 1/unit).

◆ operator<<()

std::ostream & units::operator<< ( std::ostream & os,
const any_unit & value )
inline

writes an erased quantity's self-describing BINARY bytes to a stream

Writes exactly bytes() — the serialized form — so stream << serialize(q) persists a quantity to a file/socket and a later stream >> value recovers it. Open the stream in binary mode. This moves the raw bytes, NOT text; for a human-readable rendering use to_string().

Parameters
[in]osthe output stream
[in]valuethe erased quantity
Returns
the stream

◆ operator==()

template<fixed_string Tag, UnitType U, UnitType V>
requires traits::is_same_dimension_unit_v<U, V>
bool units::affine::operator== ( const basic_kind< Tag, U > & lhs,
const basic_kind< Tag, V > & rhs )
constexprnoexcept

Compare two kinds of the SAME tag; the wrapped plain units compare (inheriting the core's value-based, signedness-safe integer comparison).

Different tags do not compare.

◆ operator>>()

std::istream & units::operator>> ( std::istream & is,
any_unit & value )
inline

reads one self-describing erased quantity from a binary stream (classic stream-extraction form)

The counterpart to operator<<: stream >> value decodes the next record written by stream << serialize(q), setting the stream's failbit (and leaving value unchanged) on a malformed or truncated record. Equivalent to deserialize(stream); use that overload when the richer deserialize_error is wanted. Same seekable-stream requirement.

Parameters
[in]isthe input stream
[out]valuereceives the decoded quantity on success
Returns
the stream

◆ pow()

template<int power, UnitType UnitType>
requires (traits::has_linear_scale_v<UnitType>)
auto units::pow ( const UnitType & value) -> detail::rewrap_to_named_t< unit< traits::strong_t< typename units::detail::power_of_unit< power, typename units::traits::unit_traits< UnitType >::conversion_factor >::type >, detail::floating_point_promotion_t< typename units::traits::unit_traits< UnitType >::underlying_type >, linear_scale > >
constexprnoexcept

computes the value of value raised to the power

Only implemented for linear_scale units. Power must be known at compile time, so the resulting unit type can be deduced.

Template Parameters
powerexponential power to raise value by.
Parameters
[in]valueunit derived type to raise to the given power
Returns
new unit, raised to the given exponent

◆ serialize()

template<class Unit>
any_unit units::serialize ( const Unit & quantity)
nodiscard

serializes a quantity to a self-describing, erased any_unit

The returned any_unit carries the dimension signature, the magnitude in SI canonical base, and the owned byte stream. A peer decodes it with deserialize without prior agreement on the type; the byte form is available through bytes() (type-safe span) and data()/size() (for ostream::write, fwrite, a socket send, and other byte-oriented interfaces, with no cast at the call site).

Template Parameters
Unita UnitType
Parameters
[in]quantitythe value to serialize
Returns
the erased quantity, owning its serialized bytes

◆ unit_cast()

template<class Target>
Target units::unit_cast ( const any_unit & value)
nodiscard

explicit cast from an erased any_unit to a concrete unit, throwing on a dimension mismatch

The free-function cast idiom for the same operation as any_unit::try_to<Unit>(). Mirrors std::any_cast. This is the purpose unit_cast was created for.

Template Parameters
Targetthe target unit type
Parameters
[in]valuethe erased quantity
Returns
the value as Target