From: Steven W. <ste...@us...> - 2007-04-20 23:43:18
|
Update of /cvsroot/boost-sandbox/boost-sandbox/boost/units/systems/si In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv10552/boost-sandbox/boost/units/systems/si Modified Files: constants.hpp Log Message: made constants safe to use before main Index: constants.hpp =================================================================== RCS file: /cvsroot/boost-sandbox/boost-sandbox/boost/units/systems/si/constants.hpp,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- constants.hpp 13 Apr 2007 01:38:04 -0000 1.3 +++ constants.hpp 20 Apr 2007 23:43:08 -0000 1.4 @@ -17,64 +17,131 @@ #include <boost/io/ios_state.hpp> +#include <boost/units/static_constant.hpp> + namespace boost { namespace units { -template<class Y> -class value_and_uncertainty -{ - public: - typedef value_and_uncertainty<Y> this_type; - typedef Y value_type; - - value_and_uncertainty(const value_type& val = value_type(), - const value_type& err = value_type()) : - value_(val), - uncertainty_(std::abs(err)) - { } - - value_and_uncertainty(const this_type& source) : - value_(source.value_), - uncertainty_(source.uncertainty_) - { } - - //~value_and_uncertainty() { } - - this_type& operator=(const this_type& source) - { - value_ = source.value_; - uncertainty_ = source.uncertainty_; - - return *this; - } - - operator value_type() const { return value_; } - - value_type value() const { return value_; } - value_type uncertainty() const { return uncertainty_; } - value_type lower_bound() const { return value_-uncertainty_; } - value_type upper_bound() const { return value_+uncertainty_; } +template<class Base> +struct constant : Base {}; - private: - value_type value_, - uncertainty_; -}; +template<class Base> +struct physical_constant : Base {}; + +#define BOOST_UNITS_DEFINE_HELPER(name, symbol, template_name) \ + \ +template<class T, class Arg1, class Arg2> \ +struct name ## _typeof_helper<constant<T>, template_name<Arg1, Arg2> >\ +{ \ + typedef typename name ## _typeof_helper<typename T::value_type, template_name<Arg1, Arg2> >::type type;\ +}; \ + \ +template<class T, class Arg1, class Arg2> \ +struct name ## _typeof_helper<template_name<Arg1, Arg2>, constant<T> >\ +{ \ + typedef typename name ## _typeof_helper<template_name<Arg1, Arg2>, typename T::value_type>::type type;\ +}; \ + \ +template<class T, class Arg1, class Arg2> \ +typename name ## _typeof_helper<typename T::value_type, template_name<Arg1, Arg2> >::type \ +operator symbol(const constant<T>& t, const template_name<Arg1, Arg2>& u)\ +{ \ + return(t.value() symbol u); \ +} \ + \ +template<class T, class Arg1, class Arg2> \ +typename name ## _typeof_helper<typename T::value_type, template_name<Arg1, Arg2> >::type \ +operator symbol(const template_name<Arg1, Arg2>& u, const constant<T>& t)\ +{ \ + return(u symbol t.value()); \ +} + +BOOST_UNITS_DEFINE_HELPER(add, +, unit) +BOOST_UNITS_DEFINE_HELPER(add, +, quantity) +BOOST_UNITS_DEFINE_HELPER(subtract, -, unit) +BOOST_UNITS_DEFINE_HELPER(subtract, -, quantity) +BOOST_UNITS_DEFINE_HELPER(multiply, *, unit) +BOOST_UNITS_DEFINE_HELPER(multiply, *, quantity) +BOOST_UNITS_DEFINE_HELPER(divide, /, unit) +BOOST_UNITS_DEFINE_HELPER(divide, /, quantity) + +#undef BOOST_UNITS_DEFINE_HELPER + +#define BOOST_UNITS_DEFINE_HELPER(name, symbol) \ + \ +template<class T1, class T2> \ +struct name ## _typeof_helper<constant<T1>, constant<T2> > \ +{ \ + typedef typename name ## _typeof_helper<typename T1::value_type, typename T2::value_type>::type type;\ +}; \ + \ +template<class T1, class T2> \ +typename name ## _typeof_helper<typename T1::value_type, typename T2::value_type>::type \ +operator symbol(const constant<T1>& t, const constant<T2>& u) \ +{ \ + return(t.value() symbol u.value()); \ +} \ + \ +template<class T1, class T2> \ +struct name ## _typeof_helper<constant<T1>, T2> \ +{ \ + typedef typename name ## _typeof_helper<typename T1::value_type, T2>::type type;\ +}; \ + \ +template<class T1, class T2> \ +struct name ## _typeof_helper<T1, constant<T2> > \ +{ \ + typedef typename name ## _typeof_helper<T1, typename T2::value_type>::type type;\ +}; \ + \ +template<class T1, class T2> \ +typename name ## _typeof_helper<typename T1::value_type, T2>::type \ +operator symbol(const constant<T1>& t, const T2& u) \ +{ \ + return(t.value() symbol u); \ +} \ + \ +template<class T1, class T2> \ +typename name ## _typeof_helper<T1, typename T2::value_type>::type \ +operator symbol(const T1& t, const constant<T2>& u) \ +{ \ + return(t symbol u.value()); \ +} + +BOOST_UNITS_DEFINE_HELPER(add, +) +BOOST_UNITS_DEFINE_HELPER(subtract, -) +BOOST_UNITS_DEFINE_HELPER(multiply, *) +BOOST_UNITS_DEFINE_HELPER(divide, /) + +#undef BOOST_UNITS_DEFINE_HELPER + +#define BOOST_UNITS_PHYSICAL_CONSTANT(name, type, value_, uncertainty_) \ +struct name ## _t { \ + typedef type value_type; \ + operator value_type() const { return value_; } \ + value_type value() const { return value_; } \ + value_type uncertainty() const { return uncertainty_; } \ + value_type lower_bound() const { return value_-uncertainty_; } \ + value_type upper_bound() const { return value_+uncertainty_; } \ +}; \ +BOOST_UNITS_STATIC_CONSTANT(name, boost::units::constant<boost::units::physical_constant<name ## _t> >) // stream output template<class Y> inline -std::ostream& operator<<(std::ostream& os,const value_and_uncertainty<Y>& val) +std::ostream& operator<<(std::ostream& os,const physical_constant<Y>& val) { boost::io::ios_precision_saver precision_saver(os); //boost::io::ios_width_saver width_saver(os); boost::io::ios_flags_saver flags_saver(os); //os << std::setw(21); + typedef typename Y::value_type value_type; - if (val.uncertainty() > Y(0)) + if (val.uncertainty() > value_type()) { - const Y relative_uncertainty = std::abs(val.uncertainty()/val.value()); + const double relative_uncertainty = std::abs(val.uncertainty()/val.value()); const double exponent = std::log10(relative_uncertainty); const long digits_of_precision = static_cast<long>(std::ceil(std::abs(exponent)))+3; |