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/measurement.hpp b/example/measurement.hpp
new file mode 100644
index 0000000..7206302
--- /dev/null
+++ b/example/measurement.hpp
@@ -0,0 +1,344 @@
+// 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) 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)
+
+#ifndef BOOST_UNITS_MEASUREMENT_HPP
+#define BOOST_UNITS_MEASUREMENT_HPP
+
+#include <cmath>
+#include <cstdlib>
+#include <iomanip>
+#include <iostream>
+
+#include <boost/io/ios_state.hpp>
+#include <boost/units/static_rational.hpp>
+
+namespace boost {
+
+namespace units {
+
+namespace sqr_namespace /**/ {
+
+template<class Y>
+constexpr
+Y sqr(Y val)
+{ return val*val; }
+
+} // namespace
+
+using sqr_namespace::sqr;
+
+template<class Y>
+class measurement
+{    
+    public:
+        typedef measurement<Y>                  this_type;
+        typedef Y                               value_type;
+        
+        constexpr measurement(const value_type& val = value_type(),
+                    const value_type& err = value_type()) : 
+            value_(val),
+            uncertainty_(std::abs(err)) 
+        { }
+        
+        constexpr measurement(const this_type& source) : 
+            value_(source.value_),
+            uncertainty_(source.uncertainty_) 
+        { }
+        
+        //~measurement() { }
+        
+        constexpr this_type& operator=(const this_type& source)
+        {
+            if (this == &source) return *this;
+            
+            value_ = source.value_;
+            uncertainty_ = source.uncertainty_;
+            
+            return *this;
+        }
+        
+        constexpr operator value_type() const    { return value_; }
+        
+        constexpr value_type value() const       { return value_; }
+        constexpr value_type uncertainty() const { return uncertainty_; }
+        constexpr value_type lower_bound() const { return value_-uncertainty_; }
+        constexpr value_type upper_bound() const { return value_+uncertainty_; }
+        
+        constexpr this_type& operator+=(const value_type& val)            
+        { 
+            value_ += val; 
+            return *this; 
+        }
+        
+        constexpr this_type& operator-=(const value_type& val)            
+        { 
+            value_ -= val; 
+            return *this; 
+        }
+        
+        constexpr this_type& operator*=(const value_type& val)            
+        { 
+            value_ *= val; 
+            uncertainty_ *= val; 
+            return *this; 
+        }
+        
+        constexpr this_type& operator/=(const value_type& val)            
+        { 
+            value_ /= val; 
+            uncertainty_ /= val; 
+            return *this; 
+        }
+        
+        constexpr this_type& operator+=(const this_type& /*source*/);
+        constexpr this_type& operator-=(const this_type& /*source*/);        
+        constexpr this_type& operator*=(const this_type& /*source*/);        
+        constexpr this_type& operator/=(const this_type& /*source*/);
+
+    private:
+        value_type          value_,
+                            uncertainty_;
+};
+
+}
+
+}
+
+#if BOOST_UNITS_HAS_BOOST_TYPEOF
+
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::measurement, 1)
+
+#endif
+
+namespace boost {
+
+namespace units {
+
+template<class Y>
+inline
+constexpr
+measurement<Y>&
+measurement<Y>::operator+=(const this_type& source)
+{
+    uncertainty_ = std::sqrt(sqr(uncertainty_)+sqr(source.uncertainty_));
+    value_ += source.value_;
+    
+    return *this;
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>&
+measurement<Y>::operator-=(const this_type& source)
+{
+    uncertainty_ = std::sqrt(sqr(uncertainty_)+sqr(source.uncertainty_));
+    value_ -= source.value_;
+    
+    return *this;
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>&
+measurement<Y>::operator*=(const this_type& source)
+{
+    uncertainty_ = (value_*source.value_)*
+              std::sqrt(sqr(uncertainty_/value_)+
+                        sqr(source.uncertainty_/source.value_));
+    value_ *= source.value_;
+    
+    return *this;
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>&
+measurement<Y>::operator/=(const this_type& source)
+{
+    uncertainty_ = (value_/source.value_)*
+              std::sqrt(sqr(uncertainty_/value_)+
+                        sqr(source.uncertainty_/source.value_));
+    value_ /= source.value_;
+    
+    return *this;
+}
+
+// value_type op measurement
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator+(Y lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs,Y(0))+=rhs);
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator-(Y lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs,Y(0))-=rhs);
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator*(Y lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs,Y(0))*=rhs);
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator/(Y lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs,Y(0))/=rhs);
+}
+
+// measurement op value_type
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator+(const measurement<Y>& lhs,Y rhs)
+{
+    return (measurement<Y>(lhs)+=measurement<Y>(rhs,Y(0)));
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator-(const measurement<Y>& lhs,Y rhs)
+{
+    return (measurement<Y>(lhs)-=measurement<Y>(rhs,Y(0)));
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator*(const measurement<Y>& lhs,Y rhs)
+{
+    return (measurement<Y>(lhs)*=measurement<Y>(rhs,Y(0)));
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator/(const measurement<Y>& lhs,Y rhs)
+{
+    return (measurement<Y>(lhs)/=measurement<Y>(rhs,Y(0)));
+}
+
+// measurement op measurement
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator+(const measurement<Y>& lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs)+=rhs);
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator-(const measurement<Y>& lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs)-=rhs);
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator*(const measurement<Y>& lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs)*=rhs);
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator/(const measurement<Y>& lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs)/=rhs);
+}
+
+/// specialize power typeof helper
+template<class Y,long N,long D> 
+struct power_typeof_helper<measurement<Y>,static_rational<N,D> >
+{ 
+    typedef measurement<
+        typename power_typeof_helper<Y,static_rational<N,D> >::type
+    > type; 
+    
+    static constexpr type value(const measurement<Y>& x)  
+    { 
+        const static_rational<N,D>  rat;
+
+        const Y m = Y(rat.numerator())/Y(rat.denominator()),
+                newval = std::pow(x.value(),m),
+                err = newval*std::sqrt(std::pow(m*x.uncertainty()/x.value(),2));
+        
+        return type(newval,err);
+    }
+};
+
+/// specialize root typeof helper
+template<class Y,long N,long D> 
+struct root_typeof_helper<measurement<Y>,static_rational<N,D> >                
+{ 
+    typedef measurement<
+        typename root_typeof_helper<Y,static_rational<N,D> >::type
+    > type; 
+    
+    static constexpr type value(const measurement<Y>& x)  
+    { 
+        const static_rational<N,D>  rat;
+
+        const Y m = Y(rat.denominator())/Y(rat.numerator()),
+                newval = std::pow(x.value(),m),
+                err = newval*std::sqrt(std::pow(m*x.uncertainty()/x.value(),2));
+        
+        return type(newval,err);
+    }
+};
+
+// stream output
+template<class Y>
+inline
+std::ostream& operator<<(std::ostream& os,const measurement<Y>& val)
+{
+    boost::io::ios_precision_saver precision_saver(os);
+    boost::io::ios_flags_saver flags_saver(os);
+    
+    os << val.value() << "(+/-" << val.uncertainty() << ")";
+    
+    return os;
+}
+
+} // namespace units
+
+} // namespace boost
+
+#endif // BOOST_UNITS_MEASUREMENT_HPP