Boost logo

Boost :

From: Steven Watanabe (steven_at_[hidden])
Date: 2007-02-16 14:30:11


AMDG

Noah Roberts <roberts.noah <at> gmail.com> writes:

> >
> > My question was: Why should x and y store the
> > unit, when that information is just going to
> > be thrown away and replaced by user_selected_unit?
>
> Well, presumably it is used elsewhere.
>
> > Is this converted value going to be used for
> > any other purpose than to output it or convert
> > it back to the base system for more calculation?
>
> No.

Then why go to the trouble of providing
all the arithmetic functions? As far as
I can see runtime_quantity can be a very
basic.

template<class BaseUnit>
struct runtime_unit {
    double conversion_factor_;
    std::string name_;
    friend istream& operator>>(istream& is, runtime_unit& self) {
        //fancy stuff for parsing a unit
    }
};

runtime_unit<SI::force> pound = { ..., "pound" };
runtime_unit<SI::force> dyne = { ..., "dyne" };

template<class BaseUnit, class Unit>
struct static_runtime_unit {
    static runtime_unit& value() {
        static runtime_unit result = { ... };
        return(result);
    }
};

template<class BaseUnit>
class runtime_quantity {
public:
    runtime_quantity(const quantity<BaseUnit>& q) :
        value_(q.value()),
        unit_(static_runtime_unit<BaseUnit,BaseUnit>::value()) {
    }
    friend ostream& operator<<(ostream& os, const runtime_quantity& self) {
        //overly simplified
        return(os << value_ << ' ' << unit_.name_);
    }
    friend istream& operator>>(istream& is, runtime_quantity& self) {
        //overly simplified
        return(is >> value_ >> unit_);
    }
    double value() const {
        return(value_);
    }
    runtime_unit<BaseUnit> unit() const {
        return(unit_);
    }
    BaseUnit quantity() const {
        return(quantity<BaseUnit>::from_value(
            value_ * unit_.conversion_factor_));
    }
private:
    double value_;
    runtime_unit<BaseUnit> unit_;
};

template<class Quantity, class BaseUnit>
runtime_quantity<BaseUnit>
operator*(const runtime_unit<BaseUnit>&, const Quantity&);

> >
> > A few clarifications are in order. I have
> > assumed that the only use for a dynamic
> > unit system is to read and write quantities
> > in units to be determined at runtime.
>
> The other use is to write code like so:
>
> quantity f() { static quantity const C = 9.43 * psi; ... equation
> written with psi constant ... }

I don't understand what is wrong with

quantity<psi_type> f() {
    static quantity<psi_type> const C = 9.43 * psi;
    ... equation written with psi constant ...
}

> >
> > quantity<pressure> p1(psi);
> > quantity<pressure> p2(pascals);
> > p1 = whatever;
> > p2 = p1;
> >
> > Now, what should the unit of p2 be?
>
> pascals. The rule is conversion on assignment. This does cause some
> need to be careful with such things as std containers that work through
> assignment.
>

Right. I can't see a way to make a std container
that holds quantities of different units safe at all.
Explicit conversion is safer.

p2 = runtime_quantity_cast(pascals, p1);

In Christ,
Steven Watanabe


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