Boost logo

Boost :

From: Pavel Vozenilek (pavel_vozenilek_at_[hidden])
Date: 2003-04-12 16:26:46


I wrote Quantity library some time ago and wonder whether it may get added
into Conversion library. If anyone gets interested I will Boostify and
submit it.

Quantity library is used to get safe conversions between different physical
units (like between Celsius and Farhernheit degrees). Instead of bare number
you have specific type and conversion rules are applied automatically.

Example:

typedef struct { float value; } speed_km_per_hour_t;

typedef Quantity
<
    float, // numeric type to represent speed in meter/sec
    speed_km_per_hour // alternative representation
> speed_meters_per_sec_t;

// conversion rule: define them when it makes sense
void convert_quantity(const speed_meters_per_sec_t& from,
speed_km_per_hour_t& to)
{
    to.value = from.value * 3.6;
}

int main()
{
    speed_meters_per_sec_t m_p_s(10);
    speed_km_per_hour_t km_p_h;

    km_p_h = m_p_s; // OK
// m_p_s = km_p_h; ERROR - this conversion is not defined
    km_p_h = static_cast<speed_km_per_hour_t>(m_p_s); // OK
}

You can manipulate Quantity value like any other value (add, multiply,
compare), you may add e.g. 1 inch to value of 2.1 meters. This library
helps to avoid really hard to track down conversion errors.

Some conversions may not be needed: e.g. $1.5 money may be converted to
string "one dollar, fifty cents" but not vice versa. Unimplemented and used
conversions result in (relatively) readable linker error.

Ability e.g. to divide length quantity by time quantity and get speed
quantity may be added into the library.

The library is simple and uses Boost.Preprocessor to emulate variable number
of template parameters.

-------------
Shortened snippet of implementation:

template<typename MainType, typename OtherType1>
class Quantity
{
public:
    Quantity() {}
    Quantity(const Quantity& other) : value(other.value) {}
    Quantity(const MainType& val) : value(val) {}
    Quantity(const OtherType1& val) { convert_quantity(val, *this); }

    ~Quantity() {}

    Quantity& operator=(const Quantity& other) { value = other.value; return
*this; }
    Quantity& operator=(const MainType& other) { value = other; return
this*; }
    Quantity& operator=(const OtherType1& other) { convert_quantity(other,
*this); return *this; }

    operator MainType() { return value; }
    operator OtherType1() { OtherType1 result; convert_quantity(*this,
result); return result; }

    // operators like ==, /, * etc. not shown here

    MainType value;
};
-------------

Name and inspiration was taken from Martin Fowler's article
http://www.martinfowler.com/ap2/quantity.html.

/Pavel


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