
David Greene wrote:
Andy Little wrote:
If kilograms played by the rules its exponent would be 3 , but for whatever historical reasons its 0.
Without the prefix_offset, because kilograms has an exponent of 0, then its unit output would be worked out as 'g', which is plainly wrong.
Does this help?
Why not just give kg anb exponent of "3" like everywhere else and then adjust the other mass exponents accordingly. Why special-case this?
I have been playing around with implementing a unit system. What I have for SI units is something like: namespace boost { namespace unit { namespace si { struct si_tag{}; namespace prefix { typedef power< 10, 6 > mega; typedef power< 10, 3 > kilo; typedef power< 10, 0 > base; typedef power< 10, -3 > milli; typedef kilo k; typedef milli m; } struct length_tag{}; struct mass_tag{}; struct time_tag{}; typedef base_unit_type< length_tag, 0 > length; typedef base_unit_type< mass_tag, 1 > mass; typedef base_unit_type< time_tag, 2 > time; /** @brief length */ typedef base_unit< si_tag, length, prefix::base > meter; typedef scaled_unit< meter, prefix::kilo > km; typedef scaled_unit< meter, prefix::base > m; typedef scaled_unit< meter, prefix::milli > mm; /** @brief mass */ typedef base_unit< si_tag, mass, prefix::kilo > kilogram; typedef scaled_unit< kilogram, prefix::kilo > kg; typedef scaled_unit< kilogram, prefix::base > g; typedef scaled_unit< kilogram, prefix::milli > mg; /** @brief time */ typedef base_unit< si_tag, time, prefix::base > second; typedef scaled_unit< second, prefix::kilo > ks; typedef scaled_unit< second, prefix::base > s; typedef scaled_unit< second, prefix::milli > ms; /** @brief force */ typedef derived_unit< kilogram, meter, per< second >, per< second > > newton; // N = m.kg.s-2 typedef scaled_unit< newton, prefix::kilo > kN; typedef scaled_unit< newton, prefix::base > N; typedef scaled_unit< newton, prefix::milli > mN; }}} With the following unit concepts: namespace boost { namespace unit { template< int Base, int Exponent > struct power{}; /** @brief A single unit in a given unit system. */ template< typename System, typename Dimension, typename Scale, int Exponent = 1 > struct unit{}; /** @brief A fundamental unit type within a unit system. */ template< typename Tag, int Index > struct base_unit_type { }; /** @brief A fundamental unit within a unit system. */ template< typename System, typename Dimension, typename Scale > struct base_unit { }; /** @brief A unit scaled up or down by a given magnitude. */ template< typename Unit, typename Scale > struct scaled_unit{}; /** @brief The inverse (reciprocal) of a unit. */ template< typename Unit > struct per{}; /** @brief A composite unit type. */ template< typename Unit1, typename Unit2 > struct composite_unit{}; struct none{}; /** @brief A unit derived from a series of other units. */ template< typename Unit1, typename Unit2 = none, typename Unit3 = none, typename Unit4 = none, typename Unit5 = none, typename Unit6 = none, typename Unit7 = none, typename Unit8 = none, typename Unit9 = none, typename Unit10 = none > struct derived_unit{}; }} I also have simple type manipulation inside these concepts that can reduce units of the same type, Allowing: namespace si = boost::unit::si; template< typename Unit > void print( const Unit & ) { std::cout << typeid(Unit::type).name() << std::endl << std::endl; } print(si::mm()); print(si::kg()); print(si::hertz()); print(si::tesla()); std::cout << typeid(si::mm() * si::mm()).name() << std::endl << std::endl; print(si::mm() * si::mm() * si::mm()); The last two giving: struct boost::unit::composite_unit<struct boost::unit::unit<struct boost::unit:: si::si_tag,struct boost::unit::base_unit_type<struct boost::unit::si::length_tag ,0>,struct boost::unit::power<10,-3>,1>,struct boost::unit::unit<struct boost::u nit::si::si_tag,struct boost::unit::base_unit_type<struct boost::unit::si::lengt h_tag,0>,struct boost::unit::power<10,-3>,1> > struct boost::unit::unit<struct boost::unit::si::si_tag,struct boost::unit::base _unit_type<struct boost::unit::si::length_tag,0>,struct boost::unit::power<10,-3
,3>
Currently tested on VC8 and will only reduce adjacent similar types. The idea is to support values like this: template< typename ValueUnit, typename ValueType = float > class boost::unit::value; //... boost::unit::value< si::mm > dist( 1.5 ); boost::unit::value< typeof(si::mm() * si::mm()) > dist( dist * dist ); If there is interest, I'd be willing to persue this, especially with Andy's expertise in this area :). At the moment it is just a toy example. I can upload the full code as well. NOTE: It will require a conformant compiler! - Reece _________________________________________________________________ Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/