I want to write a library for working with units (lengths,
weights, ...). It should allow maths and converting with/between
different units (cm to mm, angstrom to meter, ...).
The SI Sytem consists of the base units for length (meter), mass
(kg), time (second) ,... and the prefixes like yotta (10²⁴) to
femto (10⁻¹⁵).
enum for the prefixes
enum prefix {
...
c = -2, /// for centi
m = -3, /// for mili
...
}
enum for different units
enum unit { length, weight, ... }
I take a struct to define the units
struct units (T) {
T _value; /// the value (eg 10)
prefix _pre; /// the SI-prefix (eg. c for cm)
unit _unit; /// the unit like length or weight to keep them
apart
};
to keep it simple maybe functions could help (also with ifti)
auto cm (T) (T value) { return units!T(value, prefix.c,
unit.length); }
conversion within a unit is simple comparing the prefixes:
real conv (prefix lhs, prefix rhs) {
import std.math:pow;
int c = rhs - lhs;
return pow(10.0,c);
}
math could be done with opBinary overloading in the struct
auto opBinary(string op)(length rhs)
{
return mixin("units(_value "~op~"
rhs._value*conv(pre,rhs.pre),_pre, _unit)");
}
auto opBinary(string op)(T rhs) if (isNumeric!T)
{
return mixin("units(_value "~op~" rhs,_pre,_unit)");
}
What do you think about the layout so far?
Is there a better way?
How to implement non-SI-units?