$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: steven_watanabe_at_[hidden]
Date: 2007-05-28 18:55:05
Author: steven_watanabe
Date: 2007-05-28 18:55:04 EDT (Mon, 28 May 2007)
New Revision: 4339
URL: http://svn.boost.org/trac/boost/changeset/4339
Log:
changed absolute
Text files modified: 
   sandbox/units/boost/units/absolute.hpp                       |    56 ++++++++++++++++++                      
   sandbox/units/boost/units/conversion.hpp                     |    61 +++++++++++++++++++-                    
   sandbox/units/boost/units/quantity.hpp                       |   118 +++++++-------------------------------- 
   sandbox/units/boost/units/systems/base_units.hpp             |    27 ++++++--                                
   sandbox/units/boost/units/systems/temperature/celsius.hpp    |    16 +----                                   
   sandbox/units/boost/units/systems/temperature/fahrenheit.hpp |    14 +---                                    
   sandbox/units/libs/units/example/unit_example_20.cpp         |   100 ++++++++++++++++++---------------       
   7 files changed, 218 insertions(+), 174 deletions(-)
Modified: sandbox/units/boost/units/absolute.hpp
==============================================================================
--- sandbox/units/boost/units/absolute.hpp	(original)
+++ sandbox/units/boost/units/absolute.hpp	2007-05-28 18:55:04 EDT (Mon, 28 May 2007)
@@ -13,6 +13,8 @@
 
 #include <iosfwd>
 
+#include <boost/units/conversion.hpp>
+
 namespace boost {
 
 namespace units {
@@ -39,6 +41,41 @@
         value_type   val_;
 };
 
+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())); }
+};
+
+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;
+    typedef quantity<absolute<Unit2>, T2> to_quantity_type;
+    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()));
+    }
+};
+
+// a macro for consistancy
+#define BOOST_UNITS_DEFINE_AFFINE_CONVERSION(From, To, type_, value_)\
+    namespace boost {\
+    namespace units {\
+    template<>\
+    struct affine_conversion_helper<From, To> {\
+        typedef type_ type;\
+        static type value() {return(value_);}\
+    };\
+    }\
+    }\
+    void boost_units_require_semicolon()
+
 template<class Y>
 absolute<Y> operator+(const absolute<Y>& aval,const Y& rval)
 {
@@ -63,6 +100,25 @@
     return Y(aval1.value()-aval2.value());
 }
 
+template<class U, class T>
+class quantity;
+
+template<class D, class S>
+class unit;
+
+template<class Unit>
+struct reduce_unit;
+
+template<class D, class S>
+struct reduce_unit<absolute<unit<D, S> > > {
+    typedef absolute<typename reduce_unit<unit<D, S> >::type> type;
+};
+
+template<class D, class S, class T>
+quantity<absolute<unit<D, S> >, T> operator*(const T& t, const absolute<unit<D, S> >&) {
+    return(quantity<absolute<unit<D, S> >, T>::from_value(t));
+}
+
 template<class Y>
 std::ostream& operator<<(std::ostream& os,const absolute<Y>& aval)
 {
Modified: sandbox/units/boost/units/conversion.hpp
==============================================================================
--- sandbox/units/boost/units/conversion.hpp	(original)
+++ sandbox/units/boost/units/conversion.hpp	2007-05-28 18:55:04 EDT (Mon, 28 May 2007)
@@ -216,13 +216,68 @@
     }
 };
 
-template<class Y,class FromUnit,class ToUnit>
+namespace detail {
+
+template<class Source, class Dest>
+struct conversion_factor_helper;
+
+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<mpl::size<unit_list>::value>::template apply<
+        typename mpl::begin<unit_list>::type,
+        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<mpl::size<typename L1::type>::value>::template apply<
+        typename mpl::begin<typename L1::type>::type,
+        homogeneous_system<L2>
+    > impl;
+    typedef typename impl::type type;
+    static type convert() {
+        return(impl::value());
+    }
+};
+
+// There is no simple algorithm for doing this conversion
+// other than just defining it as the reverse of the
+// 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<mpl::size<typename L2::type>::value>::template apply<
+        typename mpl::begin<typename L2::type>::type,
+        homogeneous_system<L1>
+    > impl;
+    typedef typename impl::type type;
+    static type value() {
+        return(one() / impl::value());
+    }
+};
+
+}
+
+template<class FromUnit,class ToUnit>
+inline
+typename detail::conversion_factor_helper<FromUnit, ToUnit>::type
+conversion_factor(const FromUnit&,const ToUnit&)
+{
+    return(detail::conversion_factor_helper<FromUnit, ToUnit>::value());
+}
+
+template<class Y, class FromUnit,class ToUnit>
 inline
 Y
 conversion_factor(const FromUnit&,const ToUnit&)
 {
-    // dangerous if conversion is not regular...don't know how to deal with this yet
-    return quantity<ToUnit,Y>(Y(1)*FromUnit()).value();
+    return(static_cast<Y>(detail::conversion_factor_helper<FromUnit, ToUnit>::value()));
 }
 
 } //namespace units
Modified: sandbox/units/boost/units/quantity.hpp
==============================================================================
--- sandbox/units/boost/units/quantity.hpp	(original)
+++ sandbox/units/boost/units/quantity.hpp	2007-05-28 18:55:04 EDT (Mon, 28 May 2007)
@@ -67,16 +67,13 @@
 template<class Unit,class Y = double>
 class quantity
 {
+        enum { force_instantiation_of_unit = sizeof(Unit) };
     public:
         typedef quantity<Unit,Y>                        this_type;
         
         typedef Y                                       value_type;
-        typedef typename get_system<Unit>::type         system_type;
-        typedef typename get_dimension<Unit>::type      dimension_type;
-        typedef unit<dimension_type,system_type>        unit_type;
-
-        BOOST_STATIC_ASSERT((detail::check_system<system_type,dimension_type>::value == true));
-         
+        typedef Unit        unit_type;
+ 
         quantity() : val_() 
         { 
             BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
@@ -100,7 +97,7 @@
 
         /// implicit conversion between value types is allowed if allowed for value types themselves
         template<class YY>
-        quantity(const quantity<unit<dimension_type,system_type>,YY>& source,
+        quantity(const quantity<Unit,YY>& source,
             typename boost::enable_if<detail::is_non_narrowing_conversion<YY, Y> >::type* = 0) :
             val_(source.value())
         { 
@@ -109,7 +106,7 @@
 
         /// implicit conversion between value types is not allowed if not allowed for value types themselves
         template<class YY>
-        explicit quantity(const quantity<unit<dimension_type,system_type>,YY>& source,
+        explicit quantity(const quantity<Unit,YY>& source,
             typename boost::disable_if<detail::is_non_narrowing_conversion<YY, Y> >::type* = 0) :
             val_(static_cast<Y>(source.value()))
         { 
@@ -120,7 +117,7 @@
 
         /// implicit conversion between value types is allowed if allowed for value types themselves
         template<class YY>
-        quantity(const quantity<unit<dimension_type,system_type>,YY>& source) :
+        quantity(const quantity<Unit,YY>& source) :
             val_(source.value())
         { 
             BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
@@ -131,7 +128,7 @@
         
         /// implicit assignment between value types is allowed if allowed for value types themselves
         template<class YY>
-        this_type& operator=(const quantity<unit<dimension_type,system_type>,YY>& source)
+        this_type& operator=(const quantity<Unit,YY>& source)
         {
             BOOST_STATIC_ASSERT((boost::is_convertible<YY, Y>::value == true));
 
@@ -143,31 +140,33 @@
         #ifndef BOOST_NO_SFINAE
 
         /// explicit conversion between different unit systems is allowed if implicit conversion is disallowed
-        template<class System2,class Dim2,class YY> 
+        template<class Unit2,class YY> 
         explicit
-        quantity(const quantity<unit<Dim2,System2>,YY>& source, 
+        quantity(const quantity<Unit2,YY>& source, 
                  typename boost::disable_if<
                     mpl::and_<
-                        is_implicitly_convertible<unit<Dim2,System2>,unit_type>,
+                        //is_implicitly_convertible should be undefined when the
+                        //units are not convertible at all
+                        typename is_implicitly_convertible<Unit2,Unit>::type,
                         detail::is_non_narrowing_conversion<YY, Y>
                     >
                  >::type* = 0)
-             : val_(conversion_helper<quantity<unit<Dim2,System2>,YY>,this_type>::convert(source).value())
+             : val_(conversion_helper<quantity<Unit2,YY>,this_type>::convert(source).value())
         {
             BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
             BOOST_STATIC_ASSERT((boost::is_convertible<YY,Y>::value == true));
         }
 
         /// implicit conversion between different unit systems is allowed if each fundamental dimension is implicitly convertible
-        template<class System2,class Dim2,class YY> 
-        quantity(const quantity<unit<Dim2,System2>,YY>& source, 
+        template<class Unit2,class YY> 
+        quantity(const quantity<Unit2,YY>& source, 
                  typename boost::enable_if<
                      mpl::and_<
-                         is_implicitly_convertible<unit<Dim2,System2>,unit_type>,
+                         typename is_implicitly_convertible<Unit2,Unit>::type,
                          detail::is_non_narrowing_conversion<YY, Y>
                      >
                  >::type* = 0)
-             : val_(conversion_helper<quantity<unit<Dim2,System2>,YY>,this_type>::convert(source).value())
+             : val_(conversion_helper<quantity<Unit2,YY>,this_type>::convert(source).value())
         {
             BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
             BOOST_STATIC_ASSERT((boost::is_convertible<YY,Y>::value == true));
@@ -177,9 +176,9 @@
 
         /// without SFINAE we can't distinguish between explicit and implicit conversions so 
         /// the conversion is always explicit
-        template<class System2,class Dim2,class YY> 
-        explicit quantity(const quantity<unit<Dim2,System2>,YY>& source)
-             : val_(conversion_helper<quantity<unit<Dim2,System2>,YY>,this_type>::convert(source).value())
+        template<class Unit2,class YY> 
+        explicit quantity(const quantity<Unit2,YY>& source)
+             : val_(conversion_helper<quantity<Unit2,YY>,this_type>::convert(source).value())
         {
             BOOST_UNITS_CHECK_LAYOUT_COMPATIBILITY(this_type, Y);
             BOOST_STATIC_ASSERT((boost::is_convertible<YY,Y>::value == true));
@@ -188,13 +187,11 @@
         #endif
         
         /// implicit assignment between different unit systems is allowed if each fundamental dimension is implicitly convertible 
-        template<class System2,class Dim2,class YY>
-        this_type& operator=(const quantity<unit<Dim2,System2>,YY>& source)
+        template<class Unit2,class YY>
+        this_type& operator=(const quantity<Unit2,YY>& source)
         {
-            typedef unit_type                       unit1_type;
-            typedef unit<Dim2,System2>              unit2_type;
             
-            BOOST_STATIC_ASSERT((is_implicitly_convertible<unit2_type,unit1_type>::value == true));
+            BOOST_STATIC_ASSERT((is_implicitly_convertible<Unit2,unit_type>::value == true));
             BOOST_STATIC_ASSERT((boost::is_convertible<YY,Y>::value == true));
             
             *this = this_type(source);
@@ -454,75 +451,6 @@
     using std::swap;
     swap(quantity_cast<Y&>(lhs),quantity_cast<Y&>(rhs));
 }
-//
-///// utility class to simplify construction of dimensionless quantities
-//template<class System,class Y>
-//struct dimensionless_quantity
-//{
-//    typedef quantity<typename dimensionless_unit<System>::type,Y>   type;
-//};
-//
-///// check that a type is a quantity
-//template<typename T>
-//struct is_quantity :
-//    public mpl::false_
-//{ };
-//
-//template<class Unit,
-//         class Y>
-//struct is_quantity< quantity<Unit,Y> > : 
-//    public mpl::true_
-//{ };
-//
-///// check that a type is a quantity of the specified dimension
-//template<class T,class Dim>
-//struct is_quantity_of_dimension :
-//    public mpl::false_
-//{ };
-//
-//template<class Dim,class System,class Y>
-//struct is_quantity_of_dimension< quantity< unit<Dim,System>,Y>,Dim > :
-//    public mpl::true_
-//{ };
-//
-///// check that a type is a dimensionless quantity
-//template<class T>
-//struct is_dimensionless_quantity :
-//    public is_quantity_of_dimension<T,dimensionless_type>
-//{ };
-//
-///// check that a type is a quantity in a specified system
-//template<class T,class System>
-//struct is_quantity_of_system :
-//    public mpl::false_
-//{ };
-//
-//template<class Dim,
-//         class System,
-//         class Y>
-//struct is_quantity_of_system< quantity< unit<Dim,System>,Y>,System > :
-//    public mpl::true_
-//{ };
-//
-///// check that a type is dimensionless
-//template<class System,class Y>
-//struct is_dimensionless< quantity<unit<dimensionless_type,System>,Y> > :
-//    public mpl::true_
-//{ };
-//
-///// get dimension
-//template<class Unit,class Y>
-//struct get_dimension< quantity<Unit,Y> >
-//{
-//    typedef typename get_dimension<Unit>::type  type;
-//};
-//
-///// get system
-//template<class Unit,class Y>
-//struct get_system< quantity<Unit,Y> >
-//{
-//    typedef typename get_system<Unit>::type     type;
-//};
 
 /// specialize unary plus typeof helper
 template<class Unit,class Y>
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-28 18:55:04 EDT (Mon, 28 May 2007)
@@ -16,6 +16,7 @@
 #include <boost/units/config.hpp>
 #include <boost/units/base_unit.hpp>
 #include <boost/units/scaled_base_unit.hpp>
+#include <boost/units/absolute.hpp>
 #include <boost/units/systems/physical_units.hpp>
 
 namespace boost {
@@ -76,35 +77,39 @@
     static std::string name() { return("kelvin"); }
     static std::string symbol() { return("K"); }
 };
-struct fahrenheit_tag : public base_unit<fahrenheit_tag, temperature_type, -8> {
+struct celsius_tag : public base_unit<celsius_tag, temperature_type, -8> {
+    static std::string name() { return("celsius"); }
+    static std::string symbol() { return("C"); }
+};
+struct fahrenheit_tag : public base_unit<fahrenheit_tag, temperature_type, -7> {
     static std::string name() { return("fahrenheit"); }
     static std::string symbol() { return("F"); }
 };
 
-struct mole_tag : public base_unit<mole_tag, amount_type, -7> {
+struct mole_tag : public base_unit<mole_tag, amount_type, -6> {
     static std::string name() { return("mole"); }
     static std::string symbol() { return("mol"); }
 };
 
-struct candela_tag : public base_unit<candela_tag, luminous_intensity_type, -6> {
+struct candela_tag : public base_unit<candela_tag, luminous_intensity_type, -5> {
     static std::string name() { return("candela"); }
     static std::string symbol() { return("cd"); }
 };
 
-struct radian_tag : public base_unit<radian_tag, plane_angle_type, -5> {
+struct radian_tag : public base_unit<radian_tag, plane_angle_type, -4> {
     static std::string name() { return("radian"); }
     static std::string symbol() { return("rad"); }
 };
-struct degree_tag : public base_unit<degree_tag, plane_angle_type, -4> {
+struct degree_tag : public base_unit<degree_tag, plane_angle_type, -3> {
     static std::string name() { return("degree"); }
     static std::string symbol() { return("deg"); }
 };
-struct gradian_tag : public base_unit<gradian_tag, plane_angle_type, -3> {
+struct gradian_tag : public base_unit<gradian_tag, plane_angle_type, -2> {
     static std::string name() { return("gradian"); }
     static std::string symbol() { return("grad"); }
 };
 
-struct steradian_tag : public base_unit<steradian_tag, solid_angle_type, -2> {
+struct steradian_tag : public base_unit<steradian_tag, solid_angle_type, -1> {
     static std::string name() { return("steradian"); }
     static std::string symbol() { return("sr"); }
 };
@@ -113,6 +118,14 @@
 
 }
 
+BOOST_UNITS_DEFINE_CONVERSION(boost::units::kelvin_tag, boost::units::celsius_tag::unit_type, one, one());
+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::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);
 BOOST_UNITS_DEFINE_CONVERSION(boost::units::radian_tag, boost::units::gradian_tag::unit_type, double, 200/3.14159265358979323846);
 BOOST_UNITS_DEFINE_CONVERSION(boost::units::degree_tag, boost::units::gradian_tag::unit_type, double, 10/9.);
Modified: sandbox/units/boost/units/systems/temperature/celsius.hpp
==============================================================================
--- sandbox/units/boost/units/systems/temperature/celsius.hpp	(original)
+++ sandbox/units/boost/units/systems/temperature/celsius.hpp	2007-05-28 18:55:04 EDT (Mon, 28 May 2007)
@@ -14,10 +14,10 @@
 #include <string>
 
 #include <boost/units/absolute.hpp>
-#include <boost/units/io.hpp>
 #include <boost/units/static_constant.hpp>
-#include <boost/units/system.hpp>
+#include <boost/units/make_system.hpp>
 #include <boost/units/systems/physical_units.hpp>
+#include <boost/units/systems/base_units.hpp>
 
 namespace boost {
 
@@ -25,9 +25,7 @@
 
 namespace celsius {
 
-struct system_tag : public ordinal<111> { };
-
-typedef homogeneous_system<system_tag>  system;
+typedef make_system<celsius_tag>::type system;
 
 typedef unit<temperature_type,system>   temperature;
 
@@ -35,15 +33,9 @@
 BOOST_UNITS_STATIC_CONSTANT(degrees,temperature);
 
 } // namespace celsius
-
-template<> struct base_unit_info<temperature_dim,celsius::system_tag>
-{
-    static std::string name()               { return "Celsius"; }
-    static std::string symbol()             { return "C"; }
-};
         
 } // namespace units
 
 } // namespace boost
 
-#endif // BOOST_UNITS_CELSIUS_HPP
\ No newline at end of file
+#endif // BOOST_UNITS_CELSIUS_HPP
Modified: sandbox/units/boost/units/systems/temperature/fahrenheit.hpp
==============================================================================
--- sandbox/units/boost/units/systems/temperature/fahrenheit.hpp	(original)
+++ sandbox/units/boost/units/systems/temperature/fahrenheit.hpp	2007-05-28 18:55:04 EDT (Mon, 28 May 2007)
@@ -16,8 +16,8 @@
 #include <boost/units/absolute.hpp>
 #include <boost/units/io.hpp>
 #include <boost/units/static_constant.hpp>
-#include <boost/units/system.hpp>
 #include <boost/units/systems/physical_units.hpp>
+#include <boost/units/systems/base_unit.hpp>
 
 namespace boost {
 
@@ -25,9 +25,7 @@
 
 namespace fahrenheit {
 
-struct system_tag : public ordinal<110> { };
-
-typedef homogeneous_system<system_tag>  system;
+typedef make_system<fahrenheit_tag>::type system;
 
 typedef unit<temperature_type,system>   temperature;
 
@@ -36,14 +34,8 @@
 
 } // namespace fahrenheit
 
-template<> struct base_unit_info<temperature_dim,fahrenheit::system_tag>
-{
-    static std::string name()               { return "Fahrenheit"; }
-    static std::string symbol()             { return "F"; }
-};
-
 } // namespace units
 
 } // namespace boost
 
-#endif // BOOST_UNITS_FAHRENHEIT_HPP
\ No newline at end of file
+#endif // BOOST_UNITS_FAHRENHEIT_HPP
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-28 18:55:04 EDT (Mon, 28 May 2007)
@@ -44,6 +44,8 @@
 #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 {
@@ -67,47 +69,53 @@
     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;
+template<>
+struct is_implicitly_convertible<absolute< unit<temperature_type,fahrenheit::system> >,
+                                  absolute< unit<temperature_type,SI::system> > > : 
+    public mpl::true_
+{ };
 
-        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));
-        }
-};
+//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
 
@@ -117,16 +125,16 @@
 {
     std::stringstream sstream1, sstream2;
     
-    quantity<fahrenheit::temperature,absolute<> >   T1p(absolute<>(32)*fahrenheit::degrees);
-    quantity<fahrenheit::temperature>               T1v(32*fahrenheit::degrees);
+    quantity<absolute<fahrenheit::temperature> >   T1p(32.0*absolute<fahrenheit::temperature>());
+    quantity<fahrenheit::temperature>               T1v(32.0*fahrenheit::degrees);
     
-    quantity<SI::temperature,absolute<> >           T2p(T1p);
-    quantity<SI::temperature,absolute<> >           T3p = T1p;
+    quantity<absolute<SI::temperature> >           T2p(T1p);
+    quantity<absolute<SI::temperature> >           T3p = T1p;
     quantity<SI::temperature>                       T2v(T1v);
     quantity<SI::temperature>                       T3v = T1v;
     
-    typedef conversion_helper<quantity<fahrenheit::temperature,absolute<> >,
-                              quantity<SI::temperature,absolute<> > >           absolute_conv_type;
+    typedef conversion_helper<quantity<absolute<fahrenheit::temperature> >,
+                              quantity<absolute<SI::temperature> > >           absolute_conv_type;
     typedef conversion_helper<quantity<fahrenheit::temperature,double>,
                               quantity<SI::temperature,double> >                relative_conv_type;