A
Quantities are implemented by the template<class Unit,class Y = double> class quantity;
This class is templated on both unit type ( For most common value types, the result type of arithmetic operators is the same as the value type itself. For example, the sum of two double precision floating point numbers is another double precision floating point number. However, there are instances where this is not the case. A simple example is given by the natural numbers where the operator arithmetic obeys the following rules (using the standard notation for number systems):
This library is designed to support arbitrary value type algebra for addition,
subtraction, multiplication, division, and rational powers and roots. It
uses Boost.Typeof to deduce the result of these operators. For compilers
that support BOOST_TYPEOF_REGISTER_TYPE(natural); BOOST_TYPEOF_REGISTER_TYPE(integer); BOOST_TYPEOF_REGISTER_TYPE(rational);
Conversion is only meaningful for quantities as it implies the presence of
at least a multiplicative scale factor and, possibly, and affine linear offset.
Macros for simplifying the definition of conversions between units can be
found in
The macro Let's declare a simple base unit: struct foot_base_unit : base_unit<foot_base_unit, length_dimension, 10> { }; Now, we want to be able to convert feet to meters and vice versa. The foot is defined as exactly 0.3048 meters, so we can write the following BOOST_UNITS_DEFINE_CONVERSION_FACTOR(foot_base_unit, meter_base_unit, double, 0.3048);
Alternately, we could use the SI length BOOST_UNITS_DEFINE_CONVERSION_FACTOR(foot_base_unit, SI::length, double, 0.3048); Since the SI unit of length is the meter, these two definitions are equivalent. If these conversions have been defined, then converting between scaled forms of these units will also automatically work.
The macro struct my_unit_tag : boost::units::base_unit<my_unit_tag, boost::units::force_type, 1> {}; // define the conversion factor BOOST_UNITS_DEFINE_CONVERSION_FACTOR(my_unit_tag, SI::force, double, 3.14159265358979323846); // make conversion to SI the default. BOOST_UNITS_DEFAULT_CONVERSION(my_unit_tag, SI::force);
This library is designed to emphasize safety above convenience when performing
operations with dimensioned quantities. Specifically, construction of quantities
is required to fully specify both value and unit. Direct construction from
a scalar value is prohibited (though the static member function To summarize, conversions are allowed under the following conditions : -
implicit conversion of
`quantity<Unit,Y>` to`quantity<Unit,Z>` is allowed if`Y` and`Z` are implicitly convertible. -
assignment between
`quantity<Unit,Y>` and`quantity<Unit,Z>` is allowed if`Y` and`Z` are implicitly convertible. -
explicit conversion between
`quantity<Unit1,Y>` and`quantity<Unit2,Z>` is allowed if`Unit1` and`Unit2` have the same dimensions and if`Y` and`Z` are implicitly convertible. -
implicit conversion between
`quantity<Unit1,Y>` and`quantity<Unit2,Z>` is allowed if`Unit1` reduces to exactly the same combination of base units as`Unit2` and if`Y` and`Z` are convertible. -
assignment between
`quantity<Unit1,Y>` and`quantity<Unit2,Z>` is allowed under the same conditions as implicit conversion. -
`quantity<Unit,Y>` can be directly constructed from a value of type`Y` using the static member function`from_value` . Doing so, naturally, bypasses any type-checking of the newly assigned value, so this method should be used only when absolutely necessary.
Of course, any time implicit conversion is allowed, an explicit conversion is also legal. Because dimensionless quantities have no associated units, they behave as normal scalars, and allow implicit conversion to and from the underlying value type or types that are convertible to/from that value type. |