Squashed 'third_party/boostorg/units/' content from commit 57389b7

Change-Id: Id8ff79c1508f6103e20808f7a038f6a30d113b08
git-subtree-dir: third_party/boostorg/units
git-subtree-split: 57389b7374a6f7a4caf87cc44092bb8d0db65ec6
diff --git a/example/quaternion.cpp b/example/quaternion.cpp
new file mode 100644
index 0000000..a2e3e91
--- /dev/null
+++ b/example/quaternion.cpp
@@ -0,0 +1,232 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2007-2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief quaternion.cpp
+
+\details
+Demonstrate interoperability with Boost.Quaternion.
+
+Output:
+@verbatim
+
+//[quaternion_output_1
++L      = (4,3,2,1) m
+-L      = (-4,-3,-2,-1) m
+L+L     = (8,6,4,2) m
+L-L     = (0,0,0,0) m
+L*L     = (2,24,16,8) m^2
+L/L     = (1,0,0,0) dimensionless 
+L^3     = (-104,102,68,34) m^3
+//]
+
+//[quaternion_output_2
++L      = (4 m,3 m,2 m,1 m)
+-L      = (-4 m,-3 m,-2 m,-1 m)
+L+L     = (8 m,6 m,4 m,2 m)
+L-L     = (0 m,0 m,0 m,0 m)
+L^3     = (-104 m^3,102 m^3,68 m^3,34 m^3)
+//]
+
+@endverbatim
+**/
+
+#include <iostream>
+
+#include <boost/math/quaternion.hpp>
+#include <boost/mpl/list.hpp>
+
+#include <boost/units/pow.hpp>
+#include <boost/units/quantity.hpp>
+#include <boost/units/io.hpp>
+
+#include "test_system.hpp"
+
+#if BOOST_UNITS_HAS_BOOST_TYPEOF
+
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::math::quaternion, 1)
+
+#endif
+
+namespace boost {
+
+namespace units {
+
+//[quaternion_class_snippet_1a
+/// specialize power typeof helper
+template<class Y,long N,long D> 
+struct power_typeof_helper<boost::math::quaternion<Y>,static_rational<N,D> >
+{ 
+    // boost::math::quaternion only supports integer powers
+    BOOST_STATIC_ASSERT(D==1);
+    
+    typedef boost::math::quaternion<
+        typename power_typeof_helper<Y,static_rational<N,D> >::type
+    > type; 
+    
+    static type value(const boost::math::quaternion<Y>& x)  
+    {   
+        return boost::math::pow(x,static_cast<int>(N));
+    }
+};
+//]
+
+//[quaternion_class_snippet_1b
+/// specialize root typeof helper
+template<class Y,long N,long D> 
+struct root_typeof_helper<boost::math::quaternion<Y>,static_rational<N,D> >
+{ 
+    // boost::math::quaternion only supports integer powers
+    BOOST_STATIC_ASSERT(N==1);
+    
+    typedef boost::math::quaternion<
+        typename root_typeof_helper<Y,static_rational<N,D> >::type
+    > type; 
+    
+    static type value(const boost::math::quaternion<Y>& x)  
+    { 
+        return boost::math::pow(x,static_cast<int>(D));
+    }
+};
+//]
+
+//[quaternion_class_snippet_2a
+/// specialize power typeof helper for quaternion<quantity<Unit,Y> >
+template<class Unit,long N,long D,class Y> 
+struct power_typeof_helper<
+    boost::math::quaternion<quantity<Unit,Y> >,
+    static_rational<N,D> >                
+{ 
+    typedef typename power_typeof_helper<
+        Y,
+        static_rational<N,D>
+    >::type     value_type;
+
+    typedef typename power_typeof_helper<
+        Unit,
+        static_rational<N,D>
+    >::type  unit_type;
+
+    typedef quantity<unit_type,value_type>         quantity_type;
+    typedef boost::math::quaternion<quantity_type> type; 
+    
+    static type value(const boost::math::quaternion<quantity<Unit,Y> >& x)  
+    { 
+        const boost::math::quaternion<value_type>   tmp = 
+            pow<static_rational<N,D> >(boost::math::quaternion<Y>(
+                x.R_component_1().value(),
+                x.R_component_2().value(),
+                x.R_component_3().value(),
+                x.R_component_4().value()));
+        
+        return type(quantity_type::from_value(tmp.R_component_1()),
+                    quantity_type::from_value(tmp.R_component_2()),
+                    quantity_type::from_value(tmp.R_component_3()),
+                    quantity_type::from_value(tmp.R_component_4()));
+    }
+};
+//]
+
+//[quaternion_class_snippet_2b
+/// specialize root typeof helper for quaternion<quantity<Unit,Y> >
+template<class Unit,long N,long D,class Y> 
+struct root_typeof_helper<
+    boost::math::quaternion<quantity<Unit,Y> >,
+    static_rational<N,D> >                
+{ 
+    typedef typename root_typeof_helper<
+        Y,
+        static_rational<N,D>
+    >::type      value_type;
+
+    typedef typename root_typeof_helper<
+        Unit,
+        static_rational<N,D>
+    >::type   unit_type;
+
+    typedef quantity<unit_type,value_type>         quantity_type;
+    typedef boost::math::quaternion<quantity_type> type; 
+    
+    static type value(const boost::math::quaternion<quantity<Unit,Y> >& x)  
+    { 
+        const boost::math::quaternion<value_type>   tmp = 
+            root<static_rational<N,D> >(boost::math::quaternion<Y>(
+                x.R_component_1().value(),
+                x.R_component_2().value(),
+                x.R_component_3().value(),
+                x.R_component_4().value()));
+        
+        return type(quantity_type::from_value(tmp.R_component_1()),
+                    quantity_type::from_value(tmp.R_component_2()),
+                    quantity_type::from_value(tmp.R_component_3()),
+                    quantity_type::from_value(tmp.R_component_4()));
+    }
+};
+//]
+
+} // namespace units
+
+} // namespace boost
+
+int main(void)
+{
+    using boost::math::quaternion;
+    using namespace boost::units;
+    using namespace boost::units::test;
+    using boost::units::pow;
+    
+    {
+    //[quaternion_snippet_1
+    typedef quantity<length,quaternion<double> >     length_dimension;
+        
+    length_dimension    L(quaternion<double>(4.0,3.0,2.0,1.0)*meters);
+    //]
+    
+    std::cout << "+L      = " << +L << std::endl
+              << "-L      = " << -L << std::endl
+              << "L+L     = " << L+L << std::endl
+              << "L-L     = " << L-L << std::endl
+              << "L*L     = " << L*L << std::endl
+              << "L/L     = " << L/L << std::endl
+              // unfortunately, without qualification msvc still
+              // finds boost::math::pow by ADL.
+              << "L^3     = " << boost::units::pow<3>(L) << std::endl
+//              << "L^(3/2) = " << pow< static_rational<3,2> >(L) << std::endl
+//              << "3vL     = " << root<3>(L) << std::endl
+//              << "(3/2)vL = " << root< static_rational<3,2> >(L) << std::endl
+              << std::endl;
+    }
+    
+    {
+    //[quaternion_snippet_2
+    typedef quaternion<quantity<length> >     length_dimension;
+        
+    length_dimension    L(4.0*meters,3.0*meters,2.0*meters,1.0*meters);
+    //]
+    
+    std::cout << "+L      = " << +L << std::endl
+              << "-L      = " << -L << std::endl
+              << "L+L     = " << L+L << std::endl
+              << "L-L     = " << L-L << std::endl
+//              << "L*L     = " << L*L << std::endl
+//              << "L/L     = " << L/L << std::endl
+              << "L^3     = " << boost::units::pow<3>(L) << std::endl
+//              << "L^(3/2) = " << pow< static_rational<3,2> >(L) << std::endl
+//              << "3vL     = " << root<3>(L) << std::endl
+//              << "(3/2)vL = " << root< static_rational<3,2> >(L) << std::endl
+              << std::endl;
+    }
+
+    return 0;
+}