From: Geoff Leyland (geoff.leyland_at_[hidden])
Date: 2002-10-25 07:47:18
I've been unconnected for about a week, and I came back and saw the
physical units stuff that was written about a week ago. Since then it's
gone quiet. I think it would be very good if boost had a units
conversion and dimensionality checking library, and would be willing to
help out. I'm afraid I've probably missed some of what's been written
on the list - it's a lot of volume, so please excuse me if I'm out of
date or talking about things that have already been solved.
I wrote such a library some years ago, and though I imagine now that
some of its implementation is hopelessly out of date, some of the ideas
may be useful (or you may have thought of them already). It had two
parts - a "run-time" units and dimension library, and a compile-time
part. This was before MPL, and even decent compiler template support,
so some of it was probably a bit hairy.
The run time part consisted of a unit-string parser (written in antlr -
can we use spirit now?) and a unit definition file parser. The units
definition file was quite simple so that an end user could define new
units if they wanted to. It distinguished between fundamental
dimensions, and unit types:
// The cross unit is used to distinguish between angles and percents
// and between torques and work
m = length;
cm = 0.01 * m;
mm = 0.1 * cm;
km = 1000 * m;
in = 2.54 * cm;
ft = 12 * in;
yd = 3 * ft;
mile = 1760 * yd;
nm = 6076 * ft; // Fundamentals
This meant that a program could read in values with units from a file,
without even knowing too much about how the units were defined. Once
read, the value was stored as the value in the "fundamental unit" plus
something describing the dimensions. This was either a vector, or a
bitfield set of a long int or a long long int (meaning a limited number
of dimensions and a limited range of powers).
The compile-time units were defined with templates, so the "work code"
could be written using these, with (obviously) no-overhead dimension
checking, and operator overloading for dimension types (which is cool
for setting fluid properties, which can be set using one of a number of
pairs of physical properties).
Converting between run-time units and compile time units was just a
matter of checking that dimensions matched, and throwing if they
didn't. It required that the two were based on the same fundamental
dimensions, though I did have a vision of some way of re-defining the
fundamental dimensions of the run-time system (which could be changed by
editing the units definition file) to match the compiled in system.
There was facilities for output, with properties you could set on the
stream to choose what kind of units you wanted your output it.
Anyway, I'd be happy to tidy the code up if anyone's interested (I was
thinking of this, and I might even get a project soon that might need
something like this anyway), or just contribute to what's being done.
-- "Life is what happens to you while you're busy making other plans." - John Lennon Geoff Leyland, Village Idiot Laboratoire d'energetique industrielle LENI-DGM-EPFL, CH-1015, Lausanne, Switzerland Phone: +41 (21) 693 3505, Fax: +41 (21) 693 35 02
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk