Boost logo

Boost :

Subject: Re: [boost] Boost::Units - mapping from units object to something else
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2013-09-21 11:20:37


AMDG

On 09/21/2013 05:18 AM, David Hagood wrote:
> On 09/20/2013 11:11 PM, Steven Watanabe wrote:
>> (Other than the obvious typos.) I also have
>> no idea what you mean by "varying types, not typenames"
>
> Example:
> boost::units::si::meter is a constant of type
> unit<length_dimension,si::system>.
>
> boost::units:si::watts is a constant of type
> unit<power_dimension,si::system>.
>
> Since they are constants, any template would have to be of the form
>
> template<const unit_t &unit>
> struct mapper
> {
> static const MyStruct value;
> };
>
> However, since unit_t is variant - unit<length_dimension,si::system>,
> unit<power_dimension,si::system>, etc. - it has to be a template
> parameter as well - and come before the constant.
>
> So now the template would have to be:
>
> template < typename dim_t, typename sys_t, const
> boost::units::unit<dim_t,sys_t> &units>
> struct mapper
> {
> static const MyStruct value;
> };
>
> But now those paramters have to be specified in the use.
>

You don't have to make it that complex:

template<class T>
struct mapper;

template<>
sruct mapper<boost::units::si::power>
{
    static const MyStruct value;
};

...

Usage:
mapper<typeof(boost::units::si::watts)>::value

> The other approach would be to use a function:
> template < typename dim_t, typename sys_t>
> const MyStruct &Map(unit<dim_t,sys_t> const &value);
>
> which isn't bad on invocation:
> const MyStruct &x = Map(meters);
>
> but gets more difficult on definition
>
> template <> const MyStruct
> &Map<length_dimension,si::system>(unit<length_dimension,si::system>
> const &)
> {
> static const MyStruct mymeters(/* parameters */);
> return mymeters;
> }
>
> template <> const MyStruct
> &Map<power_dimension,si::system>(unit<length_dimension,si::system> const &)
> {
> static const MyStruct mywatts(/* parameters */);
> return mywatts;
> }
>
> since for every type you have to go look up the full dimensionality.
>

Don't specialize. Overload.

const MyStruct& Map(si::length);
const MyStruct& Map(si::mass);
const MyStruct& Map(si::power);
...

N.B. si::length = unit<length_dimension, si::system> = typeof(si::meters)

> Now, were there some base type for boost::units::unit
>
> class unit_base
> {
> };
>
>
> template<class Dim,class System, class Enable>
> class unit: public unit_base
> {
> }
>
> Then this whole thing would be simpler, as they my code could use the
> base type to key off. (I would have to handle the fact there are
> multiple definitions in the library, e.g. meter/meters/metre/metres).
>

You shouldn't rely on the object identity. If you
really wanted to do that, you could use void* as
the key, anyway.

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