Boost logo

Boost :

From: Andy Little (andy_at_[hidden])
Date: 2004-06-17 18:54:39


> > "Andy Little" <andy_at_[hidden]> wrote
> >
> "Eric Ford" <un5o6n902_at_[hidden]> wrote in message
news:10855-92248_at_sneakemail.com...
> > The next version of my physical quantities library pqs-1-01-04 is
> > available on my site at:
> >
> > http://www.servocomm.freeserve.co.uk/Cpp/pqs-1-01-04/download.html
> > ...
>
> Andy,
> Thank you for your work on this very important area of development.

Thanks!

>
> From just quickly looking at the examples, it appears that you choose
> to use different types for quantities that have the same dimensions but
> different units. I don't think that is a good idea. You can search the
> archives for the discussions several of us had about similar issues,
> mostly a few years ago. If you still disagree, I'd like to hear why.

Firstly, the units are part of the Type of a concrete quantity. If you cant
declare the whole type at compile time you cant use in templates or
whatever.

Secondly the value is internally at the scale of the unit, because,you will
always be working at some particular scale and will get the best resolution
and range for that unit, which is surely where you want to be. The unit
prefix is embedded in the template parameter representing the exponent to
base10 of the unit, ie mm --> -3 ,km --> 3 etc.( km or um is just as valid
as m for represnting length in SI) multiplication and division resolves to
adding and subtracting exponents (at compile-time). At run-time only the
values themselves need to be mux/divided. In case of addition/subtraction of
differing units run-time conversion to one or other will occur, however
usually addition and subtraction is only between dimensionaly exuivalent
quantities at similar scale. In multiplication and division OTOH, a
different quantity will often result, which might be at a much different
scale, but due to the compile time tracking of exponents no resolution is
lost...only the internal values are muxed/divided. In fact it works much
like manual calculation, cancelling powers and so on.

Finally (for example) energy and torque are dimensionally-equivalent, but
not the same quantity, so they must have different units.

>
> Perhaps, you could summarize the main similarities and difference
> between your library and other similar libraries.

As for similarities, yes I have drawn a lot from all those libraries. I
originally came on boost because I had heard that there were some physical
quantities libraries there. I have looked at most (all )of them including
yours, however as is my usual practise I couldnt avoid starting to reinvent
the wheel. Most of those libraries were built before the latest generation
of compilers and I freely admit that things get much easier once (1) you
have the tools. (Thanks to All those compiler vendors who only ever sem to
get complaints from us coders) and (2) someone has done it before you. One
other important fact is documentation. I dont say mine is good (yet), but
however good the library is, if its not documented, its going nowhere.
(Personal note: Get on with the documentation! )

In many of the libraries on the boost file section the units are applied at
initialisation, but initialisation happens at run-time, not compile-time.
Therefore you cant throw around types representing concrete-quantities at
compile time.

In the current version of the library I have some examples that use the
ct-quantity (compile-time quantity... units fixed at compile-time ) as a
building block for other things. One is the rt-quantity (run-time
modifiable units ). Another derived from rt-quantity is the
mapped-rt-quantity which has units which can be set via strings. At this
point the combination is pretty versatile and you can start to use it right
from the application user level ie drop-down lists etc to something at a
lower level which has a good run-time speed performance.All unit conversions
are checked at compile time, because all these types are
ultimately based on the compile time type. For example the strings represent
ing units input by the user, are compared against a map generated from the
stream output of the ct-quantity units. Units are added in the mapped
quantity like so:

mapped_length length;

length.add_unit<q_length::m>();
length.add_unit<q_length::mi>();
etc.

User can set units and/or value etc like so:

if( length.set_quantity(100, "m") ){...}

The run-time quantities are entirely compatible with the ct-quantity and so
you can cast betwen them

> For example, there's
> Walter Brown's SIUnits, as well as a couple of drafts that have been
> uploaded to the boost vault. I know I posted ebf_units a while back to
> give people something to work from. And I believe there were one or two
> others there as well.

SIUnits is a ground-breaker, but all the innovation happens underneath the
surface. Many libraries are based on its user interface, but I dont think
that is so good. In my library I have tried to look more closely at the user
interface, to give the types an instinctive 'look and feel' etc, for simple
coding. It aims to be useful rather than to have an arguably pretty syntax.

regards
Andy Little


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk