Constructs a derived unit, consisting of a number of base units and associated exponents.

Usually, constructing unit types using the operators defined on the unit instances is preferred over using this template directly.

Internally, derived units are represented as DUnit instances, but never try to use it directly – the DerivedUnit template performs canonicalization to ensure that semantically equivalent units share the same underlying types. Also, the result will not actually be a DUnit in some cases, but rather Dimensionless or a single base unit without exponent.

  1. template DerivedUnit(T...)
    template DerivedUnit (
    ) if (
    allSatisfy!(isBaseUnitExp, T)
    ) {}
  2. struct DUnit(T...)


1 alias Coulomb = DerivedUnit!(
2    BaseUnitExp!(Ampere, Rational!1),
3    BaseUnitExp!(Second, Rational!1));
4 enum coulomb = Coulomb.init;
6 // In most cases, you would want to just use the operators
7 // on the unit instances instead:
8 enum coulomb = ampere * second;
1 alias A = DerivedUnit!(BaseUnitExp!(Foo, Rational!(-2)));
2 static assert(is(A.BaseUnitExps == AliasSeq!(BaseUnitExp!(Foo,
3     Rational!(-2)))), "Basic compound unit construction does not work.");
5 static assert(is(DerivedUnit!(BaseUnitExp!(Foo, Rational!2),
6     BaseUnitExp!(Bar, Rational!1), BaseUnitExp!(Baz, Rational!3)) == DerivedUnit!(
7     BaseUnitExp!(Bar, Rational!1), BaseUnitExp!(Baz, Rational!3),
8     BaseUnitExp!(Foo, Rational!2))), "Base unit sorting does not work.");
10 // FIXME: Another problem probably related to signed/unsigned integer
11 // literals, uncomment BarBU-related arguments below to see the assert fail.
12 static assert(is(DerivedUnit!(BaseUnitExp!(Foo, Rational!2),
13     BaseUnitExp!(Foo, Rational!1) /+,
14         BaseUnitExp!(Bar, Rational!(-3)), BaseUnitExp!(Bar, Rational!2)+/
15 ) == DerivedUnit!(BaseUnitExp!(Foo, Rational!3), /+BaseUnitExp!(Bar, Rational!(-1)+/
16     )), "Base unit joining does not work.");
18 static assert(is(DerivedUnit!(BaseUnitExp!(Foo, Rational!2),
19     BaseUnitExp!(Foo, Rational!(-2))) == Dimensionless),
20     "Zero exponent base unit pruning does not work.");
22 static assert(is(DerivedUnit!(BaseUnitExp!(Dimensionless, Rational!1),
23     BaseUnitExp!(Foo, Rational!1)) == Foo),
24     "Removing Dimensionless during zero exponent pruning does not work.");
26 static assert(is(DerivedUnit!(BaseUnitExp!(Foo, Rational!1)) == Foo),
27     "Demotion of trivial compound units to base units does not work.");