Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r55151 - in trunk: boost/units/detail libs/units/test
From: steven_at_[hidden]
Date: 2009-07-25 01:30:09


Author: steven_watanabe
Date: 2009-07-25 01:30:08 EDT (Sat, 25 Jul 2009)
New Revision: 55151
URL: http://svn.boost.org/trac/boost/changeset/55151

Log:
Fix bug in handling of chained conversions involving a non-base homogeneous unit.
Text files modified:
   trunk/boost/units/detail/conversion_impl.hpp | 84 ++++++++++++++++++++++-----------------
   trunk/libs/units/test/test_default_conversion.cpp | 39 +++++++++++++-----
   2 files changed, 76 insertions(+), 47 deletions(-)

Modified: trunk/boost/units/detail/conversion_impl.hpp
==============================================================================
--- trunk/boost/units/detail/conversion_impl.hpp (original)
+++ trunk/boost/units/detail/conversion_impl.hpp 2009-07-25 01:30:08 EDT (Sat, 25 Jul 2009)
@@ -215,7 +215,7 @@
         typedef typename Begin::item source_pair;
         typedef typename source_pair::value_type exponent;
         typedef typename source_pair::tag_type source;
- typedef typename get_default_conversion<source>::type new_source;
+ typedef typename reduce_unit<typename get_default_conversion<source>::type>::type new_source;
         typedef typename get_default_conversion_impl<N-1>::template apply<typename Begin::next> next_iteration;
         typedef typename multiply_typeof_helper<typename power_typeof_helper<new_source, exponent>::type, typename next_iteration::unit_type>::type unit_type;
         typedef call_base_unit_converter<source, new_source> conversion;
@@ -353,33 +353,41 @@
 
 template<class D, class L1, class L2>
 struct conversion_factor_helper<unit<D, homogeneous_system<L1> >, unit<D, homogeneous_system<L2> > >
-{
- typedef typename reduce_unit<unit<D, homogeneous_system<L1> > >::type source_unit;
- typedef typename source_unit::system_type::type unit_list;
- typedef typename detail::conversion_impl<unit_list::size::value>::template apply<
- unit_list,
- homogeneous_system<L2>
- > impl;
- typedef typename impl::type type;
- static type value()
- {
- return(impl::value());
- }
+ : conversion_factor_helper<
+ typename reduce_unit<unit<D, homogeneous_system<L1> > >::type,
+ typename reduce_unit<unit<D, homogeneous_system<L2> > >::type
+ >
+{
+ //typedef typename reduce_unit<unit<D, homogeneous_system<L1> > >::type source_unit;
+ //typedef typename source_unit::system_type::type unit_list;
+ //typedef typename detail::conversion_impl<unit_list::size::value>::template apply<
+ // unit_list,
+ // homogeneous_system<L2>
+ //> impl;
+ //typedef typename impl::type type;
+ //static type value()
+ //{
+ // return(impl::value());
+ //}
 };
 
 template<class D, class L1, class L2>
 struct conversion_factor_helper<unit<D, heterogeneous_system<L1> >, unit<D, homogeneous_system<L2> > >
-{
- typedef typename detail::conversion_impl<L1::type::size::value>::template apply<
- typename L1::type,
- homogeneous_system<L2>
- > impl;
- typedef eval_scale_list<typename L1::scale> scale;
- typedef typename multiply_typeof_helper<typename impl::type, typename scale::type>::type type;
- static type value()
- {
- return(impl::value() * scale::value());
- }
+ : conversion_factor_helper<
+ typename reduce_unit<unit<D, heterogeneous_system<L1> > >::type,
+ typename reduce_unit<unit<D, homogeneous_system<L2> > >::type
+ >
+{
+ //typedef typename detail::conversion_impl<L1::type::size::value>::template apply<
+ // typename L1::type,
+ // homogeneous_system<L2>
+ //> impl;
+ //typedef eval_scale_list<typename L1::scale> scale;
+ //typedef typename multiply_typeof_helper<typename impl::type, typename scale::type>::type type;
+ //static type value()
+ //{
+ // return(impl::value() * scale::value());
+ //}
 };
 
 // There is no simple algorithm for doing this conversion
@@ -387,18 +395,22 @@
 // heterogeneous->homogeneous case
 template<class D, class L1, class L2>
 struct conversion_factor_helper<unit<D, homogeneous_system<L1> >, unit<D, heterogeneous_system<L2> > >
-{
- typedef typename detail::conversion_impl<L2::type::size::value>::template apply<
- typename L2::type,
- homogeneous_system<L1>
- > impl;
- typedef eval_scale_list<typename L2::scale> scale;
- typedef typename multiply_typeof_helper<typename impl::type, typename scale::type>::type type;
- static type value()
- {
- one numerator;
- return(numerator / (impl::value() * scale::value()));
- }
+ : conversion_factor_helper<
+ typename reduce_unit<unit<D, homogeneous_system<L1> > >::type,
+ typename reduce_unit<unit<D, heterogeneous_system<L2> > >::type
+ >
+{
+ //typedef typename detail::conversion_impl<L2::type::size::value>::template apply<
+ // typename L2::type,
+ // homogeneous_system<L1>
+ //> impl;
+ //typedef eval_scale_list<typename L2::scale> scale;
+ //typedef typename multiply_typeof_helper<typename impl::type, typename scale::type>::type type;
+ //static type value()
+ //{
+ // one numerator;
+ // return(numerator / (impl::value() * scale::value()));
+ //}
 };
 
 /// Requires that all possible conversions

Modified: trunk/libs/units/test/test_default_conversion.cpp
==============================================================================
--- trunk/libs/units/test/test_default_conversion.cpp (original)
+++ trunk/libs/units/test/test_default_conversion.cpp 2009-07-25 01:30:08 EDT (Sat, 25 Jul 2009)
@@ -12,42 +12,46 @@
 
 #include <boost/units/base_dimension.hpp>
 #include <boost/units/base_unit.hpp>
+#include <boost/units/make_system.hpp>
 #include <boost/units/scaled_base_unit.hpp>
 #include <boost/units/conversion.hpp>
 #include <boost/units/unit.hpp>
 
 struct dimension1_tag : boost::units::base_dimension<dimension1_tag, 1> {};
-
-typedef dimension1_tag::dimension_type dimension1;
-
 struct dimension2_tag : boost::units::base_dimension<dimension2_tag, 2> {};
 
+typedef dimension1_tag::dimension_type dimension1;
 typedef dimension2_tag::dimension_type dimension2;
-
 typedef boost::mpl::times<dimension1, dimension2>::type dimension12;
 
 struct unit1_tag : boost::units::base_unit<unit1_tag, dimension1, 1> {};
-
 struct unit2_tag : boost::units::base_unit<unit2_tag, dimension1, 2> {};
-
 struct unit3_tag : boost::units::base_unit<unit3_tag, dimension1, 3> {};
-
 struct unit4_tag : boost::units::base_unit<unit4_tag, dimension2, 4> {};
-
 struct unit5_tag : boost::units::base_unit<unit5_tag, dimension12, 5> {};
+struct unit6_tag : boost::units::base_unit<unit6_tag, dimension1, 6> {};
+struct unit7_tag : boost::units::base_unit<unit7_tag, dimension1, 7> {};
 
 BOOST_UNITS_DEFINE_CONVERSION_FACTOR(unit1_tag, unit2_tag, double, 2.0);
-
 BOOST_UNITS_DEFINE_CONVERSION_FACTOR(unit2_tag, unit3_tag, double, 3.0);
+BOOST_UNITS_DEFINE_CONVERSION_FACTOR(unit6_tag, unit3_tag, double, 5.0);
+BOOST_UNITS_DEFINE_CONVERSION_FACTOR(unit7_tag, unit1_tag, double, 7.0);
 
 typedef boost::units::multiply_typeof_helper<unit3_tag::unit_type, unit4_tag::unit_type>::type unit34_type;
 BOOST_UNITS_DEFINE_CONVERSION_FACTOR(unit5_tag, unit34_type , double, 5.0);
 
-BOOST_UNITS_DEFAULT_CONVERSION(unit1_tag, unit2_tag);
+template<class BaseUnit>
+struct make_unit {
+ typedef boost::units::unit<
+ typename BaseUnit::dimension_type,
+ typename boost::units::make_system<BaseUnit>::type> type;
+};
 
+BOOST_UNITS_DEFAULT_CONVERSION(unit1_tag, unit2_tag);
 BOOST_UNITS_DEFAULT_CONVERSION(unit3_tag, unit2_tag);
-
 BOOST_UNITS_DEFAULT_CONVERSION(unit5_tag, unit34_type);
+BOOST_UNITS_DEFAULT_CONVERSION(unit6_tag, make_unit<unit3_tag>::type);
+BOOST_UNITS_DEFAULT_CONVERSION(unit7_tag, make_unit<unit1_tag>::type);
 
 int test_main(int, char*[]) {
     double value1 = boost::units::conversion_factor(unit3_tag::unit_type(), unit1_tag::unit_type());
@@ -57,5 +61,18 @@
     typedef boost::units::scaled_base_unit<unit5_tag, boost::units::scale<2, boost::units::static_rational<1> > > scaled_unit5_tag;
     double value3 = boost::units::conversion_factor(scaled_unit5_tag::unit_type() / unit4_tag::unit_type(), unit1_tag::unit_type());
     BOOST_CHECK(std::abs(value3 - 10.0/6.0) < .0000000001);
+
+ // check homogeneous unit conversions
+ double value4 = boost::units::conversion_factor(make_unit<unit3_tag>::type(), make_unit<unit1_tag>::type());
+ BOOST_CHECK(std::abs(value4 - 1.0/6.0) < .0000000001);
+ double value5 = boost::units::conversion_factor(unit3_tag::unit_type(), make_unit<unit1_tag>::type());
+ BOOST_CHECK(std::abs(value5 - 1.0/6.0) < .0000000001);
+ double value6 = boost::units::conversion_factor(make_unit<unit3_tag>::type(), unit1_tag::unit_type());
+ BOOST_CHECK(std::abs(value6 - 1.0/6.0) < .0000000001);
+
+ // check chained homogeneous conversions
+ double value7 = boost::units::conversion_factor(unit6_tag::unit_type(), unit7_tag::unit_type());
+ BOOST_CHECK(std::abs(value7 - 5.0/42.0) < .0000000001);
+
     return(0);
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk