diff options
Diffstat (limited to 'src/boost/libs/units/example/measurement.hpp')
-rw-r--r-- | src/boost/libs/units/example/measurement.hpp | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/src/boost/libs/units/example/measurement.hpp b/src/boost/libs/units/example/measurement.hpp new file mode 100644 index 00000000..72063023 --- /dev/null +++ b/src/boost/libs/units/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 |