File indexing completed on 2025-01-19 09:48:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
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
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
0232 boost::io::ios_flags_saver flags_saver(os);
0233
0234
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
0245 os << std::setprecision(digits_of_precision)
0246
0247
0248 << val.value();
0249
0250
0251 os << " (rel. unc. = "
0252 << std::setprecision(1)
0253
0254 << std::scientific
0255 << relative_uncertainty << ")";
0256 }
0257 else
0258 {
0259 os << val.value() << " (exact)";
0260 }
0261
0262 return os;
0263 }
0264
0265
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 }
0275
0276 }
0277
0278 #endif