affine

An affine unit – the most common case being a unit that is related to other units representing the same physical quantity not by a scale factor, but by a shift in the zero point.

This is not a fundamentally new concept, adding a constant offset could just be implemented in a custom conversion function as well (see the UnitImpl documentation). However, Quantity is specialized on affine units such as to only provide operations which make sense for them:

Informally speaking, an affine space is a vector space which »forgot« its origin, its elements are points, not vectors. Thus, a quantity of an affine unit cannot be added to another (as it makes no sense to add two points), but like vectors can be added to points to yield a new point, a quantity of the underlying base unit can be. Also, two affine quantities can be substracted to yield a quantity of the base unit (just as two points can be substracted to get a vector pointing from one to another).

The most common example for this are units of temperature like degrees Celsius or Fahrenheit, as demonstrated below.

Examples

1 enum celsius = affine!(273.15, "degrees Celsius", "°C")(kelvin);
2 auto t = 3.0 * celsius;
3 t += 1.0 * kelvin; // adding Kelvin is okay
4 assert(!__traits(compiles, t += 2.0 * celsius)); // adding Celsius is not
5 writeln(t - 0.0 * celsius); // 4 Kelvin, not degrees Celsius

Meta