Boost logo

Boost :

From: Matthias Schabel (boost_at_[hidden])
Date: 2007-02-19 12:53:51


> Thus my desire for the xxx * unit that would convert k from the
> units it
> is written in to the unit system being used. There are times when you
> won't want to do this if precision is an issue but in the main, if
> there's a conversion somewhere to get into the units used by this
> EQ and
> out, you're loosing precision anyway.

Right now you can do this via explicit constructor: consider this:

static const quantity<SI::area> k(1.5*square_meters);

quantity<CGS::length> f(const quantity<CGS::length>& l)
{
        return quantity<CGS::area>(k)/l;
}

The main limitation at the moment, which I believe I have figured out
how to eliminate, is that all terms in a unit must belong to the same
unit system. It may take a while to get heterogeneous units and
conversions
working correctly, but I now see how it is possible to do that without
negatively impacting the ability to require function arguments that
belong to a homogeneous system. That is, I think it should be possible
to have both of these behaviors:

template<class System>
void f(const quantity< unit<System,dimension_type> >& q)

void f(const quantity< SI::dimension >& q)

function as expected, where the former takes any quantity of the
specified
dimension_type and the latter only takes homogeneous quantities of the
specified dimension type in the SI system. System in this context can be
homogeneous, so you could pass something like this to the first form:

f(1.5*feet*cm)

and have areas specified in ft cm units with no conversions... Then, you
could do this to convert :

quantity<SI::area> qq(1.5*feet*cm);

to get the equivalent in square meters.

> I wonder, have you read "Object-oriented units of measurement" by
> Allen
> et al?

I have briefly looked at it - they have more tolerance for runtime
overhead
than I do, which significantly simplifies the implementation issues.

> IE, gallons for volume. There are different definitions of gallon,
> some
> relate to L^3, some do not. There are other units in some
> dimensions
> that are not derived from any component dimension's units.

I think that the best I am going to be able to do is to have each
variant live
in its own "system" - if you don't like that nomenclature, you can
just consider
the system to be a tag that allows you to differentiate between
differing units
with the same dimensional signatures:

struct inch_system : public ordinal<1> { };
struct foot_system : public ordinal<2> { };
struct yard_system : public ordinal<3> { };

... conversions between the various lengths ...

Ultimately, my opinions on this problem domain are

1) The vast majority of users of this library will just convert from
other units into
SI units for internal computations; this is most easily accomplished
by simply
defining constants for the irregular units in terms of SI units.

2) There are various compromises to be made in choosing how to implement
variant unit systems, and there is no one-size-fits-all solution, so
the library
needs to be as flexible as possible in allowing knowledgeable
developers to
implement something that meets their needs.

3) There are many ways to skin this cat, each with advantages and
disadvantages.
I don't think the library is going to be able to provide an out-of-
the-box solution for
every reasonable use case. Therefore, I want to provide a functional
solution for
the most common case of (internationally standardized) SI units.
Conversion factors
for various commonly used non-SI units could be included as constants
in SI units.

Matthias


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