Chris@16: // Boost.Units - A C++ library for zero-overhead dimensional analysis and Chris@16: // unit/quantity manipulation and conversion Chris@16: // Chris@16: // Copyright (C) 2003-2008 Matthias Christian Schabel Chris@16: // Copyright (C) 2008 Steven Watanabe Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_UNITS_CONSTANTS_HPP Chris@16: #define BOOST_UNITS_CONSTANTS_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: namespace units { Chris@16: Chris@16: template Chris@16: struct constant Chris@16: { Chris@16: typedef typename Base::value_type value_type; Chris@16: operator value_type() const { return Base().value(); } Chris@16: value_type value() const { return Base().value(); } Chris@16: value_type uncertainty() const { return Base().uncertainty(); } Chris@16: value_type lower_bound() const { return Base().lower_bound(); } Chris@16: value_type upper_bound() const { return Base().upper_bound(); } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct physical_constant Chris@16: { Chris@16: typedef typename Base::value_type value_type; Chris@16: operator value_type() const { return Base().value(); } Chris@16: value_type value() const { return Base().value(); } Chris@16: value_type uncertainty() const { return Base().uncertainty(); } Chris@16: value_type lower_bound() const { return Base().lower_bound(); } Chris@16: value_type upper_bound() const { return Base().upper_bound(); } Chris@16: }; Chris@16: Chris@16: #define BOOST_UNITS_DEFINE_HELPER(name, symbol, template_name) \ Chris@16: \ Chris@16: template \ Chris@16: struct name ## _typeof_helper, template_name >\ Chris@16: { \ Chris@16: typedef typename name ## _typeof_helper >::type type;\ Chris@16: }; \ Chris@16: \ Chris@16: template \ Chris@16: struct name ## _typeof_helper, constant >\ Chris@16: { \ Chris@16: typedef typename name ## _typeof_helper, typename T::value_type>::type type;\ Chris@16: }; \ Chris@16: \ Chris@16: template \ Chris@16: typename name ## _typeof_helper >::type \ Chris@16: operator symbol(const constant& t, const template_name& u)\ Chris@16: { \ Chris@16: return(t.value() symbol u); \ Chris@16: } \ Chris@16: \ Chris@16: template \ Chris@16: typename name ## _typeof_helper, typename T::value_type>::type \ Chris@16: operator symbol(const template_name& u, const constant& t)\ Chris@16: { \ Chris@16: return(u symbol t.value()); \ Chris@16: } Chris@16: Chris@16: BOOST_UNITS_DEFINE_HELPER(add, +, unit) Chris@16: BOOST_UNITS_DEFINE_HELPER(add, +, quantity) Chris@16: BOOST_UNITS_DEFINE_HELPER(subtract, -, unit) Chris@16: BOOST_UNITS_DEFINE_HELPER(subtract, -, quantity) Chris@16: BOOST_UNITS_DEFINE_HELPER(multiply, *, unit) Chris@16: BOOST_UNITS_DEFINE_HELPER(multiply, *, quantity) Chris@16: BOOST_UNITS_DEFINE_HELPER(divide, /, unit) Chris@16: BOOST_UNITS_DEFINE_HELPER(divide, /, quantity) Chris@16: Chris@16: #undef BOOST_UNITS_DEFINE_HELPER Chris@16: Chris@16: #define BOOST_UNITS_DEFINE_HELPER(name, symbol) \ Chris@16: \ Chris@16: template \ Chris@16: struct name ## _typeof_helper, constant > \ Chris@16: { \ Chris@16: typedef typename name ## _typeof_helper::type type;\ Chris@16: }; \ Chris@16: \ Chris@16: template \ Chris@16: typename name ## _typeof_helper::type \ Chris@16: operator symbol(const constant& t, const constant& u) \ Chris@16: { \ Chris@16: return(t.value() symbol u.value()); \ Chris@16: } \ Chris@16: \ Chris@16: template \ Chris@16: struct name ## _typeof_helper, T2> \ Chris@16: { \ Chris@16: typedef typename name ## _typeof_helper::type type;\ Chris@16: }; \ Chris@16: \ Chris@16: template \ Chris@16: struct name ## _typeof_helper > \ Chris@16: { \ Chris@16: typedef typename name ## _typeof_helper::type type;\ Chris@16: }; \ Chris@16: \ Chris@16: template \ Chris@16: typename name ## _typeof_helper::type \ Chris@16: operator symbol(const constant& t, const T2& u) \ Chris@16: { \ Chris@16: return(t.value() symbol u); \ Chris@16: } \ Chris@16: \ Chris@16: template \ Chris@16: typename name ## _typeof_helper::type \ Chris@16: operator symbol(const T1& t, const constant& u) \ Chris@16: { \ Chris@16: return(t symbol u.value()); \ Chris@16: } Chris@16: Chris@16: BOOST_UNITS_DEFINE_HELPER(add, +) Chris@16: BOOST_UNITS_DEFINE_HELPER(subtract, -) Chris@16: BOOST_UNITS_DEFINE_HELPER(multiply, *) Chris@16: BOOST_UNITS_DEFINE_HELPER(divide, /) Chris@16: Chris@16: #undef BOOST_UNITS_DEFINE_HELPER Chris@16: Chris@16: #define BOOST_UNITS_DEFINE_HELPER(name, symbol) \ Chris@16: \ Chris@16: template \ Chris@16: struct name ## _typeof_helper, one> \ Chris@16: { \ Chris@16: typedef typename name ## _typeof_helper::type type;\ Chris@16: }; \ Chris@16: \ Chris@16: template \ Chris@16: struct name ## _typeof_helper > \ Chris@16: { \ Chris@16: typedef typename name ## _typeof_helper::type type;\ Chris@16: }; \ Chris@16: \ Chris@16: template \ Chris@16: typename name ## _typeof_helper::type \ Chris@16: operator symbol(const constant& t, const one& u) \ Chris@16: { \ Chris@16: return(t.value() symbol u); \ Chris@16: } \ Chris@16: \ Chris@16: template \ Chris@16: typename name ## _typeof_helper::type \ Chris@16: operator symbol(const one& t, const constant& u) \ Chris@16: { \ Chris@16: return(t symbol u.value()); \ Chris@16: } Chris@16: Chris@16: BOOST_UNITS_DEFINE_HELPER(multiply, *) Chris@16: BOOST_UNITS_DEFINE_HELPER(divide, /) Chris@16: Chris@16: #undef BOOST_UNITS_DEFINE_HELPER Chris@16: Chris@16: template Chris@16: struct power_typeof_helper, static_rational > Chris@16: { Chris@16: typedef power_typeof_helper > base; Chris@16: typedef typename base::type type; Chris@16: static type value(const constant& arg) Chris@16: { Chris@16: return base::value(arg.value()); Chris@16: } Chris@16: }; Chris@16: Chris@16: #define BOOST_UNITS_DEFINE_HELPER(name, symbol) \ Chris@16: \ Chris@16: template \ Chris@16: struct name ## _typeof_helper > \ Chris@16: { \ Chris@16: typedef typename name ## _typeof_helper::type type;\ Chris@16: }; \ Chris@16: \ Chris@16: template \ Chris@16: typename name ## _typeof_helper::type \ Chris@16: operator symbol(const constant& t, const one& u) \ Chris@16: { \ Chris@16: return(t.value() symbol u); \ Chris@16: } \ Chris@16: \ Chris@16: template \ Chris@16: typename name ## _typeof_helper::type \ Chris@16: operator symbol(const one& t, const constant& u) \ Chris@16: { \ Chris@16: return(t symbol u.value()); \ Chris@16: } Chris@16: Chris@16: #define BOOST_UNITS_PHYSICAL_CONSTANT(name, type, value_, uncertainty_) \ Chris@16: struct name ## _t { \ Chris@16: typedef type value_type; \ Chris@16: operator value_type() const { return value_; } \ Chris@16: value_type value() const { return value_; } \ Chris@16: value_type uncertainty() const { return uncertainty_; } \ Chris@16: value_type lower_bound() const { return value_-uncertainty_; } \ Chris@16: value_type upper_bound() const { return value_+uncertainty_; } \ Chris@16: }; \ Chris@16: BOOST_UNITS_STATIC_CONSTANT(name, boost::units::constant >) = { } Chris@16: Chris@16: // stream output Chris@16: template Chris@16: inline Chris@16: std::basic_ostream& operator<<(std::basic_ostream& os,const physical_constant& val) Chris@16: { Chris@16: boost::io::ios_precision_saver precision_saver(os); Chris@16: //boost::io::ios_width_saver width_saver(os); Chris@16: boost::io::ios_flags_saver flags_saver(os); Chris@16: Chris@16: //os << std::setw(21); Chris@16: typedef typename Y::value_type value_type; Chris@16: Chris@16: if (val.uncertainty() > value_type()) Chris@16: { Chris@16: const double relative_uncertainty = std::abs(val.uncertainty()/val.value()); Chris@16: Chris@16: const double exponent = std::log10(relative_uncertainty); Chris@16: const long digits_of_precision = static_cast(std::ceil(std::abs(exponent)))+3; Chris@16: Chris@16: // should try to replicate NIST CODATA syntax Chris@16: os << std::setprecision(digits_of_precision) Chris@16: //<< std::setw(digits_of_precision+8) Chris@16: //<< std::scientific Chris@16: << val.value(); Chris@16: // << long(10*(relative_uncertainty/std::pow(Y(10),Y(exponent)))); Chris@16: Chris@16: os << " (rel. unc. = " Chris@16: << std::setprecision(1) Chris@16: //<< std::setw(7) Chris@16: << std::scientific Chris@16: << relative_uncertainty << ")"; Chris@16: } Chris@16: else Chris@16: { Chris@16: os << val.value() << " (exact)"; Chris@16: } Chris@16: Chris@16: return os; Chris@16: } Chris@16: Chris@16: // stream output Chris@16: template Chris@16: inline Chris@16: std::basic_ostream& operator<<(std::basic_ostream& os,const constant&) Chris@16: { Chris@16: os << Y(); Chris@16: return os; Chris@16: } Chris@16: Chris@16: } // namespace units Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #endif // BOOST_UNITS_CONSTANTS_HPP