Boost logo

Boost-Commit :

From: steven_watanabe_at_[hidden]
Date: 2007-05-29 16:53:15


Author: steven_watanabe
Date: 2007-05-29 16:53:15 EDT (Tue, 29 May 2007)
New Revision: 4355
URL: http://svn.boost.org/trac/boost/changeset/4355

Log:
Implemented bidirectional affine conversions

Text files modified:
   sandbox/units/boost/units/absolute.hpp | 61 ++++++++++++++++++++++++++++++++++-----
   sandbox/units/boost/units/systems/base_units.hpp | 4 +-
   sandbox/units/libs/units/example/unit_example_20.cpp | 45 -----------------------------
   3 files changed, 54 insertions(+), 56 deletions(-)

Modified: sandbox/units/boost/units/absolute.hpp
==============================================================================
--- sandbox/units/boost/units/absolute.hpp (original)
+++ sandbox/units/boost/units/absolute.hpp 2007-05-29 16:53:15 EDT (Tue, 29 May 2007)
@@ -13,6 +13,8 @@
 
 #include <iosfwd>
 
+#include <boost/type_traits/is_base_and_derived.hpp>
+
 #include <boost/units/conversion.hpp>
 
 namespace boost {
@@ -41,15 +43,47 @@
         value_type val_;
 };
 
+namespace detail {
+
+struct undefined_affine_conversion_base {};
+
+}
+
 template<class From, class To>
-struct affine_conversion_helper {
- //F = 9/5 C + 32
- //5/9 F = C + 32 * 5/9
- //C = 5/9 F - 32 * 5/9
- typedef typename affine_conversion_helper<To, From>::type type;
- static type value() { return(-affine_conversion_helper<To, From>::value() * conversion_factor<type>(From(), To())); }
+struct affine_conversion_helper : detail::undefined_affine_conversion_base {};
+
+namespace detail {
+
+template<bool IsDefined, bool ReverseIsDefined>
+struct affine_conversion_impl;
+
+template<bool ReverseIsDefined>
+struct affine_conversion_impl<true, ReverseIsDefined> {
+ template<class Unit1, class Unit2, class T0, class T1>
+ struct apply {
+ static T1 value(const T0& t0) {
+ return(
+ t0 *
+ conversion_factor(Unit1(), Unit2()) +
+ affine_conversion_helper<typename reduce_unit<Unit1>::type, typename reduce_unit<Unit2>::type>::value());
+ }
+ };
+};
+
+template<>
+struct affine_conversion_impl<false, true> {
+ template<class Unit1, class Unit2, class T0, class T1>
+ struct apply {
+ static T1 value(const T0& t0) {
+ return(
+ (t0 - affine_conversion_helper<typename reduce_unit<Unit2>::type, typename reduce_unit<Unit1>::type>::value()) *
+ conversion_factor(Unit1(), Unit2()));
+ }
+ };
 };
 
+}
+
 template<class Unit1, class T1, class Unit2, class T2>
 struct conversion_helper<quantity<absolute<Unit1>, T1>, quantity<absolute<Unit2>, T2> > {
     typedef quantity<absolute<Unit1>, T1> from_quantity_type;
@@ -57,9 +91,18 @@
     static to_quantity_type convert(const from_quantity_type& source) {
         return(
             to_quantity_type::from_value(
- source.value() *
- conversion_factor(Unit1(), Unit2()) +
- affine_conversion_helper<typename reduce_unit<Unit1>::type, typename reduce_unit<Unit2>::type>::value()));
+ detail::affine_conversion_impl<
+ !boost::is_base_and_derived<
+ detail::undefined_affine_conversion_base,
+ affine_conversion_helper<typename reduce_unit<Unit1>::type, typename reduce_unit<Unit2>::type>
+ >::value,
+ !boost::is_base_and_derived<
+ detail::undefined_affine_conversion_base,
+ affine_conversion_helper<typename reduce_unit<Unit2>::type, typename reduce_unit<Unit1>::type>
+ >::value
+ >::template apply<Unit1, Unit2, T1, T2>::value(source.value())
+ )
+ );
     }
 };
 

Modified: sandbox/units/boost/units/systems/base_units.hpp
==============================================================================
--- sandbox/units/boost/units/systems/base_units.hpp (original)
+++ sandbox/units/boost/units/systems/base_units.hpp 2007-05-29 16:53:15 EDT (Tue, 29 May 2007)
@@ -122,8 +122,8 @@
 BOOST_UNITS_DEFINE_CONVERSION(boost::units::kelvin_tag, boost::units::fahrenheit_tag::unit_type, double, 9.0/5.0);
 BOOST_UNITS_DEFINE_CONVERSION(boost::units::celsius_tag, boost::units::fahrenheit_tag::unit_type, double, 9.0/5.0);
 
-BOOST_UNITS_DEFINE_AFFINE_CONVERSION(boost::units::kelvin_tag::unit_type, boost::units::celsius_tag::unit_type, double, 273.15);
-BOOST_UNITS_DEFINE_AFFINE_CONVERSION(boost::units::kelvin_tag::unit_type, boost::units::fahrenheit_tag::unit_type, double, 273.15 * 9.0 / 5.0 + 32.0);
+BOOST_UNITS_DEFINE_AFFINE_CONVERSION(boost::units::kelvin_tag::unit_type, boost::units::celsius_tag::unit_type, double, -273.15);
+BOOST_UNITS_DEFINE_AFFINE_CONVERSION(boost::units::kelvin_tag::unit_type, boost::units::fahrenheit_tag::unit_type, double, -273.15 * 9.0 / 5.0 + 32.0);
 BOOST_UNITS_DEFINE_AFFINE_CONVERSION(boost::units::celsius_tag::unit_type, boost::units::fahrenheit_tag::unit_type, double, 32.0);
 
 BOOST_UNITS_DEFINE_CONVERSION(boost::units::radian_tag, boost::units::degree_tag::unit_type, double, 180/3.14159265358979323846);

Modified: sandbox/units/libs/units/example/unit_example_20.cpp
==============================================================================
--- sandbox/units/libs/units/example/unit_example_20.cpp (original)
+++ sandbox/units/libs/units/example/unit_example_20.cpp 2007-05-29 16:53:15 EDT (Tue, 29 May 2007)
@@ -44,8 +44,6 @@
 #include <boost/units/systems/si/temperature.hpp>
 #include <boost/units/detail/utility.hpp>
 
-BOOST_UNITS_DEFINE_AFFINE_CONVERSION(boost::units::fahrenheit_tag::unit_type, boost::units::kelvin_tag::unit_type, double, 273.15 + 5.0 / 9.0 * 32.0);
-
 using namespace boost::units;
 
 namespace boost {
@@ -75,48 +73,6 @@
     public mpl::true_
 { };
 
-//template<class Y>
-//class conversion_helper< quantity<unit<temperature_type,fahrenheit::system>,absolute<Y> >,
-// quantity<unit<temperature_type,SI::system>,absolute<Y> > >
-//{
-// public:
-// typedef unit<temperature_type,fahrenheit::system> unit1_type;
-// typedef unit<temperature_type,SI::system> unit2_type;
-//
-// typedef quantity<unit1_type,absolute<Y> > from_quantity_type;
-// typedef quantity<unit2_type,absolute<Y> > to_quantity_type;
-//
-// static
-// to_quantity_type
-// convert(const from_quantity_type& source)
-// {
-// const typename from_quantity_type::value_type& in(source.value());
-//
-// return to_quantity_type::from_value((in.value()-32)*(5.0/9.0) + 273.15);
-// }
-//};
-//
-//template<class Y>
-//class conversion_helper< quantity<unit<temperature_type,fahrenheit::system>,Y>,
-// quantity<unit<temperature_type,SI::system>,Y> >
-//{
-// public:
-// typedef unit<temperature_type,fahrenheit::system> unit1_type;
-// typedef unit<temperature_type,SI::system> unit2_type;
-//
-// typedef quantity<unit1_type,Y> from_quantity_type;
-// typedef quantity<unit2_type,Y> to_quantity_type;
-//
-// static
-// to_quantity_type
-// convert(const from_quantity_type& source)
-// {
-// const typename from_quantity_type::value_type& in(source.value());
-//
-// return to_quantity_type::from_value(in*(5.0/9.0));
-// }
-//};
-
 } // namespace units
 
 } // namespace boost
@@ -189,4 +145,3 @@
         return(-1);
     }
 }
-


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