Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:48:51

0001 // Boost.Units - A C++ library for zero-overhead dimensional analysis and 
0002 // unit/quantity manipulation and conversion
0003 //
0004 // Copyright (C) 2003-2008 Matthias Christian Schabel
0005 // Copyright (C) 2008 Steven Watanabe
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See
0008 // accompanying file LICENSE_1_0.txt or copy at
0009 // http://www.boost.org/LICENSE_1_0.txt)
0010 
0011 #ifndef BOOST_UNITS_CONSTANTS_HPP
0012 #define BOOST_UNITS_CONSTANTS_HPP
0013 
0014 #include <boost/config/no_tr1/cmath.hpp>
0015 #include <iosfwd>
0016 #include <iomanip>
0017 
0018 #include <boost/io/ios_state.hpp>
0019 
0020 #include <boost/units/static_constant.hpp>
0021 #include <boost/units/units_fwd.hpp>
0022 #include <boost/units/operators.hpp>
0023 #include <boost/units/static_rational.hpp>
0024 #include <boost/units/detail/one.hpp>
0025 
0026 namespace boost {
0027 
0028 namespace units {
0029 
0030 template<class Base>
0031 struct constant 
0032 { 
0033     typedef typename Base::value_type value_type; 
0034     BOOST_CONSTEXPR operator value_type() const    { return Base().value(); } 
0035     BOOST_CONSTEXPR value_type value() const       { return Base().value(); } 
0036     BOOST_CONSTEXPR value_type uncertainty() const { return Base().uncertainty(); } 
0037     BOOST_CONSTEXPR value_type lower_bound() const { return Base().lower_bound(); } 
0038     BOOST_CONSTEXPR value_type upper_bound() const { return Base().upper_bound(); } 
0039 }; 
0040 
0041 template<class Base>
0042 struct physical_constant 
0043 { 
0044     typedef typename Base::value_type value_type; 
0045     BOOST_CONSTEXPR operator value_type() const    { return Base().value(); } 
0046     BOOST_CONSTEXPR value_type value() const       { return Base().value(); } 
0047     BOOST_CONSTEXPR value_type uncertainty() const { return Base().uncertainty(); } 
0048     BOOST_CONSTEXPR value_type lower_bound() const { return Base().lower_bound(); } 
0049     BOOST_CONSTEXPR value_type upper_bound() const { return Base().upper_bound(); } 
0050 }; 
0051 
0052 #define BOOST_UNITS_DEFINE_HELPER(name, symbol, template_name)  \
0053                                                                 \
0054 template<class T, class Arg1, class Arg2>                       \
0055 struct name ## _typeof_helper<constant<T>, template_name<Arg1, Arg2> >\
0056 {                                                               \
0057     typedef typename name ## _typeof_helper<typename T::value_type, template_name<Arg1, Arg2> >::type type;\
0058 };                                                              \
0059                                                                 \
0060 template<class T, class Arg1, class Arg2>                       \
0061 struct name ## _typeof_helper<template_name<Arg1, Arg2>, constant<T> >\
0062 {                                                               \
0063     typedef typename name ## _typeof_helper<template_name<Arg1, Arg2>, typename T::value_type>::type type;\
0064 };                                                              \
0065                                                                 \
0066 template<class T, class Arg1, class Arg2>                       \
0067 BOOST_CONSTEXPR                                                 \
0068 typename name ## _typeof_helper<typename T::value_type, template_name<Arg1, Arg2> >::type \
0069 operator symbol(const constant<T>& t, const template_name<Arg1, Arg2>& u)\
0070 {                                                               \
0071     return(t.value() symbol u);                                 \
0072 }                                                               \
0073                                                                 \
0074 template<class T, class Arg1, class Arg2>                       \
0075 BOOST_CONSTEXPR                                                 \
0076 typename name ## _typeof_helper<template_name<Arg1, Arg2>, typename T::value_type>::type \
0077 operator symbol(const template_name<Arg1, Arg2>& u, const constant<T>& t)\
0078 {                                                               \
0079     return(u symbol t.value());                                 \
0080 }
0081 
0082 BOOST_UNITS_DEFINE_HELPER(add, +, unit)
0083 BOOST_UNITS_DEFINE_HELPER(add, +, quantity)
0084 BOOST_UNITS_DEFINE_HELPER(subtract, -, unit)
0085 BOOST_UNITS_DEFINE_HELPER(subtract, -, quantity)
0086 BOOST_UNITS_DEFINE_HELPER(multiply, *, unit)
0087 BOOST_UNITS_DEFINE_HELPER(multiply, *, quantity)
0088 BOOST_UNITS_DEFINE_HELPER(divide, /, unit)
0089 BOOST_UNITS_DEFINE_HELPER(divide, /, quantity)
0090 
0091 #undef BOOST_UNITS_DEFINE_HELPER
0092 
0093 #define BOOST_UNITS_DEFINE_HELPER(name, symbol)                     \
0094                                                                     \
0095 template<class T1, class T2>                                        \
0096 struct name ## _typeof_helper<constant<T1>, constant<T2> >          \
0097 {                                                                   \
0098     typedef typename name ## _typeof_helper<typename T1::value_type, typename T2::value_type>::type type;\
0099 };                                                                  \
0100                                                                     \
0101 template<class T1, class T2>                                        \
0102 BOOST_CONSTEXPR                                                     \
0103 typename name ## _typeof_helper<typename T1::value_type, typename T2::value_type>::type \
0104 operator symbol(const constant<T1>& t, const constant<T2>& u)       \
0105 {                                                                   \
0106     return(t.value() symbol u.value());                             \
0107 }                                                                   \
0108                                                                     \
0109 template<class T1, class T2>                                        \
0110 struct name ## _typeof_helper<constant<T1>, T2>                     \
0111 {                                                                   \
0112     typedef typename name ## _typeof_helper<typename T1::value_type, T2>::type type;\
0113 };                                                                  \
0114                                                                     \
0115 template<class T1, class T2>                                        \
0116 struct name ## _typeof_helper<T1, constant<T2> >                    \
0117 {                                                                   \
0118     typedef typename name ## _typeof_helper<T1, typename T2::value_type>::type type;\
0119 };                                                                  \
0120                                                                     \
0121 template<class T1, class T2>                                        \
0122 BOOST_CONSTEXPR                                                     \
0123 typename name ## _typeof_helper<typename T1::value_type, T2>::type  \
0124 operator symbol(const constant<T1>& t, const T2& u)                 \
0125 {                                                                   \
0126     return(t.value() symbol u);                                     \
0127 }                                                                   \
0128                                                                     \
0129 template<class T1, class T2>                                        \
0130 BOOST_CONSTEXPR                                                     \
0131 typename name ## _typeof_helper<T1, typename T2::value_type>::type  \
0132 operator symbol(const T1& t, const constant<T2>& u)                 \
0133 {                                                                   \
0134     return(t symbol u.value());                                     \
0135 }
0136 
0137 BOOST_UNITS_DEFINE_HELPER(add, +)
0138 BOOST_UNITS_DEFINE_HELPER(subtract, -)
0139 BOOST_UNITS_DEFINE_HELPER(multiply, *)
0140 BOOST_UNITS_DEFINE_HELPER(divide, /)
0141 
0142 #undef BOOST_UNITS_DEFINE_HELPER
0143 
0144 #define BOOST_UNITS_DEFINE_HELPER(name, symbol)                     \
0145                                                                     \
0146 template<class T1>                                                  \
0147 struct name ## _typeof_helper<constant<T1>, one>                    \
0148 {                                                                   \
0149     typedef typename name ## _typeof_helper<typename T1::value_type, one>::type type;\
0150 };                                                                  \
0151                                                                     \
0152 template<class T2>                                                  \
0153 struct name ## _typeof_helper<one, constant<T2> >                   \
0154 {                                                                   \
0155     typedef typename name ## _typeof_helper<one, typename T2::value_type>::type type;\
0156 };                                                                  \
0157                                                                     \
0158 template<class T1>                                                  \
0159 BOOST_CONSTEXPR                                                     \
0160 typename name ## _typeof_helper<typename T1::value_type, one>::type \
0161 operator symbol(const constant<T1>& t, const one& u)                \
0162 {                                                                   \
0163     return(t.value() symbol u);                                     \
0164 }                                                                   \
0165                                                                     \
0166 template<class T2>                                                  \
0167 BOOST_CONSTEXPR                                                     \
0168 typename name ## _typeof_helper<one, typename T2::value_type>::type \
0169 operator symbol(const one& t, const constant<T2>& u)                \
0170 {                                                                   \
0171     return(t symbol u.value());                                     \
0172 }
0173 
0174 BOOST_UNITS_DEFINE_HELPER(multiply, *)
0175 BOOST_UNITS_DEFINE_HELPER(divide, /)
0176 
0177 #undef BOOST_UNITS_DEFINE_HELPER
0178 
0179 template<class T1, long N, long D>
0180 struct power_typeof_helper<constant<T1>, static_rational<N,D> >
0181 {
0182     typedef power_typeof_helper<typename T1::value_type, static_rational<N,D> > base;
0183     typedef typename base::type type;
0184     static BOOST_CONSTEXPR type value(const constant<T1>& arg)
0185     {
0186         return base::value(arg.value());
0187     }
0188 };
0189 
0190 #define BOOST_UNITS_DEFINE_HELPER(name, symbol)                     \
0191                                                                     \
0192 template<class T1, class E>                                         \
0193 struct name ## _typeof_helper<constant<T1> >                        \
0194 {                                                                   \
0195     typedef typename name ## _typeof_helper<typename T1::value_type, E>::type type;\
0196 };                                                                  \
0197                                                                     \
0198 template<class T1>                                                  \
0199 BOOST_CONSTEXPR                                                     \
0200 typename name ## _typeof_helper<typename T1::value_type, one>::type \
0201 operator symbol(const constant<T1>& t, const one& u)                \
0202 {                                                                   \
0203     return(t.value() symbol u);                                     \
0204 }                                                                   \
0205                                                                     \
0206 template<class T2>                                                  \
0207 BOOST_CONSTEXPR                                                     \
0208 typename name ## _typeof_helper<one, typename T2::value_type>::type \
0209 operator symbol(const one& t, const constant<T2>& u)                \
0210 {                                                                   \
0211     return(t symbol u.value());                                     \
0212 }
0213 
0214 #define BOOST_UNITS_PHYSICAL_CONSTANT(name, type, value_, uncertainty_)             \
0215 struct name ## _t {                                                                 \
0216     typedef type value_type;                                                        \
0217     BOOST_CONSTEXPR operator value_type() const    { return value_; }               \
0218     BOOST_CONSTEXPR value_type value() const       { return value_; }               \
0219     BOOST_CONSTEXPR value_type uncertainty() const { return uncertainty_; }         \
0220     BOOST_CONSTEXPR value_type lower_bound() const { return value_-uncertainty_; }  \
0221     BOOST_CONSTEXPR value_type upper_bound() const { return value_+uncertainty_; }  \
0222 };                                                                                  \
0223 BOOST_UNITS_STATIC_CONSTANT(name, boost::units::constant<boost::units::physical_constant<name ## _t> >) = { }
0224 
0225 // stream output
0226 template<class Char, class Traits, class Y>
0227 inline
0228 std::basic_ostream<Char,Traits>& operator<<(std::basic_ostream<Char,Traits>& os,const physical_constant<Y>& val)
0229 {
0230     boost::io::ios_precision_saver precision_saver(os);
0231     //boost::io::ios_width_saver width_saver(os);
0232     boost::io::ios_flags_saver flags_saver(os);
0233 
0234     //os << std::setw(21);
0235     typedef typename Y::value_type value_type;
0236     
0237     if (val.uncertainty() > value_type())
0238     {
0239         const double relative_uncertainty = std::abs(val.uncertainty()/val.value());
0240     
0241         const double  exponent = std::log10(relative_uncertainty);
0242         const long digits_of_precision = static_cast<long>(std::ceil(std::abs(exponent)))+3;
0243         
0244         // should try to replicate NIST CODATA syntax 
0245         os << std::setprecision(digits_of_precision) 
0246            //<< std::setw(digits_of_precision+8) 
0247            //<< std::scientific
0248            << val.value();
0249 //           << long(10*(relative_uncertainty/std::pow(Y(10),Y(exponent))));
0250 
0251         os << " (rel. unc. = " 
0252            << std::setprecision(1) 
0253            //<< std::setw(7) 
0254            << std::scientific
0255            << relative_uncertainty << ")";
0256     }
0257     else
0258     {
0259         os << val.value() << " (exact)";
0260     }
0261     
0262     return os;
0263 }
0264 
0265 // stream output
0266 template<class Char, class Traits, class Y>
0267 inline
0268 std::basic_ostream<Char,Traits>& operator<<(std::basic_ostream<Char,Traits>& os,const constant<Y>&)
0269 {
0270     os << Y();
0271     return os;
0272 }
0273 
0274 } // namespace units
0275 
0276 } // namespace boost
0277 
0278 #endif // BOOST_UNITS_CONSTANTS_HPP