123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- // 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
|