Boost logo

Boost :

From: Thomas Matelich (sosedada_at_[hidden])
Date: 2001-04-12 14:52:30


Dejan Jelovic wrote:

> On September 23, 1999, NASA lost the Mars Climate Orbiter just as it was
> starting to circle the planet. The cause was a failure to convert
> navigational data from the English units used by one group of technicians to
> the metric units used by another.
>
> In order to avoid problems like this in my programs, I've developed a
> template class called arithmetic_type_wrapper. It provides a thin wrapper
> around primitive types like int and double but lets you define different
> types to represent different things.
>
> For example, say you have to do some calculation in meters and feet and want
> to represent different units with different types. The code for something
> like that would be:
>
> class meters_tag;
> typedef arithmetic_type_wrapper<double, meters_tag> meters;
>
> class feet_tag;
> typedef arithmetic_type_wrapper<double, feet_tag> feet;

Interesting. I was going to post something shortly about dealing with SI units
but with a different tack. I've been working on some classes regarding the
ability to store the unit with the value of a measurement and do implicit
conversions if people want to see a different type. I work in
"almost-shrinkwrapped" software and of course some people like english and some
people like metric, not to mention preferences on which dimension to use (milli
or centi or deka). We previously (C code) stored everything English and
converted for display.

So I developed my Measurement class. Currently my interface looks something
like this:

template <typename MeasurementClass> //the different types of Measurements
(speed, time, etc)
class Measurement //derive from appropriate operators.hpp stuff
{
public:
    typedef MeasurementClass::UnitType UnitType; //the different types of units
(feet, inches, meters)
   Measurement(double val, UnitType t);
   explicit Measurement(double val = 0.0); //uses the "system type"

    double getVal() const { return MeasurementClass::convert(val, type); }
//converts to system type
    //insert math stuff
private:
    double val;
    UnitType type;
};

//a MeasurementClass
class Length
{
public:
    enum UnitType { FEET, INCHES };
    static double convert(double val, UnitType src, UnitType dest);
    static double convert(double val, UnitType src); //convenience func using
system_type as dest

    //get and set system type funcs

private:
    static UnitType system_type;
};

I was especially please too come up with MeasurementDivider which uses a
std::pair as it's UnitType and allowed me to create Velocity and Acceleration
out of Length and Time.

I plan on developing something better than the static system type and adding
the metric dimension stuff and a way to generate a string describing the type.

Would there be any boost interest in this sort of thing? Or has anyone already
done something similar/better? I'd really appreciate some advanced template
guys nudging me in the right direction.

--
Thomas O Matelich
Senior Software Designer
Zetec, Inc.
sosedada_at_[hidden]
tmatelich_at_[hidden]

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