Boost logo

Boost-Commit :

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);
 }


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