$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: steven_at_[hidden]
Date: 2007-08-27 15:57:18
Author: steven_watanabe
Date: 2007-08-27 15:57:18 EDT (Mon, 27 Aug 2007)
New Revision: 39017
URL: http://svn.boost.org/trac/boost/changeset/39017
Log:
Made BOOST_UNITS_DEFAULT_CONVERSION support scaling and made conversions work when only some base_units use it
Text files modified: 
   sandbox/units/boost/units/conversion.hpp                  |    81 +++++++++++++++++++++++++++++---------- 
   sandbox/units/libs/units/test/test_default_conversion.cpp |    35 +++++++++++++---                        
   2 files changed, 88 insertions(+), 28 deletions(-)
Modified: sandbox/units/boost/units/conversion.hpp
==============================================================================
--- sandbox/units/boost/units/conversion.hpp	(original)
+++ sandbox/units/boost/units/conversion.hpp	2007-08-27 15:57:18 EDT (Mon, 27 Aug 2007)
@@ -80,8 +80,47 @@
 /// INTERNAL ONLY
 struct undefined_base_unit_converter_base {};
 
+/// INTERNAL ONLY
+struct no_default_conversion {};
+
+/// INTERNAL ONLY
 template<class BaseUnit>
-struct get_default_conversion;
+struct unscaled_get_default_conversion : no_default_conversion {};
+
+/// INTERNAL ONLY
+template<bool is_defined>
+struct unscaled_get_default_conversion_impl;
+
+/// INTERNAL ONLY
+template<>
+struct unscaled_get_default_conversion_impl<true>
+{
+    template<class T>
+    struct apply
+    {
+        typedef typename unscaled_get_default_conversion<typename unscale<T>::type>::type type;
+    };
+};
+
+/// INTERNAL ONLY
+template<>
+struct unscaled_get_default_conversion_impl<false>
+{
+    template<class T>
+    struct apply
+    {
+        typedef typename T::unit_type type;
+    };
+};
+
+/// INTERNAL ONLY
+template<class BaseUnit>
+struct get_default_conversion
+{
+    typedef typename unscaled_get_default_conversion_impl<
+        !boost::is_base_and_derived<no_default_conversion, unscaled_get_default_conversion<typename unscale<BaseUnit>::type> >::value
+    >::template apply<BaseUnit>::type type;
+};
 
 /// INTERNAL ONLY
 template<class Source, class Destination>
@@ -412,16 +451,16 @@
 /// no direct conversion is available.
 /// Source is a base unit.  Dest is any unit with the
 /// same dimensions.
-#define BOOST_UNITS_DEFAULT_CONVERSION(Source, Dest)\
-    namespace boost {\
-    namespace units {\
-    template<>\
-    struct get_default_conversion<Source>\
-    {\
-        typedef Dest type;\
-    };\
-    }\
-    }\
+#define BOOST_UNITS_DEFAULT_CONVERSION(Source, Dest)                \
+    namespace boost {                                               \
+    namespace units {                                               \
+    template<>                                                      \
+    struct unscaled_get_default_conversion<unscale<Source>::type>   \
+    {                                                               \
+        typedef Dest type;                                          \
+    };                                                              \
+    }                                                               \
+    }                                                               \
     void boost_units_require_semicolon()
 
 /// Specifies the default conversion to be applied when
@@ -429,16 +468,16 @@
 /// Params is a PP Sequence of template arguments.
 /// Source is a base unit.  Dest is any unit with the
 /// same dimensions.
-#define BOOST_UNITS_DEFAULT_CONVERSION_TEMPLATE(Params, Source, Dest)\
-    namespace boost {\
-    namespace units {\
-    template<BOOST_PP_SEQ_ENUM(Params)>\
-    struct get_default_conversion<Source>\
-    {\
-        typedef Dest type;\
-    };\
-    }\
-    }\
+#define BOOST_UNITS_DEFAULT_CONVERSION_TEMPLATE(Params, Source, Dest)   \
+    namespace boost {                                                   \
+    namespace units {                                                   \
+    template<BOOST_PP_SEQ_ENUM(Params)>                                 \
+    struct unscaled_get_default_conversion<Source>                      \
+    {                                                                   \
+        typedef Dest type;                                              \
+    };                                                                  \
+    }                                                                   \
+    }                                                                   \
     void boost_units_require_semicolon()
 
 namespace detail {
Modified: sandbox/units/libs/units/test/test_default_conversion.cpp
==============================================================================
--- sandbox/units/libs/units/test/test_default_conversion.cpp	(original)
+++ sandbox/units/libs/units/test/test_default_conversion.cpp	2007-08-27 15:57:18 EDT (Mon, 27 Aug 2007)
@@ -12,29 +12,50 @@
 
 #include <boost/units/base_dimension.hpp>
 #include <boost/units/base_unit.hpp>
+#include <boost/units/scaled_base_unit.hpp>
 #include <boost/units/conversion.hpp>
 #include <boost/units/unit.hpp>
 
-struct dimension_tag : boost::units::base_dimension<dimension_tag, 1> {};
+struct dimension1_tag : boost::units::base_dimension<dimension1_tag, 1> {};
 
-typedef dimension_tag::dimension_type dimension;
+typedef dimension1_tag::dimension_type dimension1;
 
-struct unit1_tag : boost::units::base_unit<unit1_tag, dimension, 1> {}; 
+struct dimension2_tag : boost::units::base_dimension<dimension2_tag, 2> {};
 
-struct unit2_tag : boost::units::base_unit<unit2_tag, dimension, 2> {};
+typedef dimension2_tag::dimension_type dimension2;
 
-struct unit3_tag : boost::units::base_unit<unit3_tag, dimension, 3> {};
+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> {};
 
 BOOST_UNITS_DEFINE_BASE_CONVERSION(unit1_tag, unit2_tag, double, 2.0);
 
 BOOST_UNITS_DEFINE_BASE_CONVERSION(unit2_tag, unit3_tag, double, 3.0);
 
+typedef boost::units::multiply_typeof_helper<unit3_tag::unit_type, unit4_tag::unit_type>::type unit34_type;
+BOOST_UNITS_DEFINE_CONVERSION(unit5_tag, unit34_type , double, 5.0);
+
 BOOST_UNITS_DEFAULT_CONVERSION(unit1_tag, unit2_tag::unit_type);
 
 BOOST_UNITS_DEFAULT_CONVERSION(unit3_tag, unit2_tag::unit_type);
 
+BOOST_UNITS_DEFAULT_CONVERSION(unit5_tag, unit34_type);
+
 int test_main(int, char*[]) {
-    double value = boost::units::conversion_factor(unit3_tag::unit_type(), unit1_tag::unit_type());
-    BOOST_CHECK(std::abs(value - 1.0/6.0) < .0000000001);
+    double value1 = boost::units::conversion_factor(unit3_tag::unit_type(), unit1_tag::unit_type());
+    BOOST_CHECK(std::abs(value1 - 1.0/6.0) < .0000000001);
+    double value2 = boost::units::conversion_factor(unit5_tag::unit_type() / unit4_tag::unit_type(), unit1_tag::unit_type());
+    BOOST_CHECK(std::abs(value2 - 5.0/6.0) < .0000000001);
+    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);
     return(0);
 }