annotate DEPENDENCIES/generic/include/boost/units/systems/detail/constants.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Boost.Units - A C++ library for zero-overhead dimensional analysis and
Chris@16 2 // unit/quantity manipulation and conversion
Chris@16 3 //
Chris@16 4 // Copyright (C) 2003-2008 Matthias Christian Schabel
Chris@16 5 // Copyright (C) 2008 Steven Watanabe
Chris@16 6 //
Chris@16 7 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 8 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 9 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 10
Chris@16 11 #ifndef BOOST_UNITS_CONSTANTS_HPP
Chris@16 12 #define BOOST_UNITS_CONSTANTS_HPP
Chris@16 13
Chris@16 14 #include <boost/config/no_tr1/cmath.hpp>
Chris@16 15 #include <iosfwd>
Chris@16 16 #include <iomanip>
Chris@16 17
Chris@16 18 #include <boost/io/ios_state.hpp>
Chris@16 19
Chris@16 20 #include <boost/units/static_constant.hpp>
Chris@16 21 #include <boost/units/units_fwd.hpp>
Chris@16 22 #include <boost/units/operators.hpp>
Chris@16 23 #include <boost/units/static_rational.hpp>
Chris@16 24 #include <boost/units/detail/one.hpp>
Chris@16 25
Chris@16 26 namespace boost {
Chris@16 27
Chris@16 28 namespace units {
Chris@16 29
Chris@16 30 template<class Base>
Chris@16 31 struct constant
Chris@16 32 {
Chris@16 33 typedef typename Base::value_type value_type;
Chris@16 34 operator value_type() const { return Base().value(); }
Chris@16 35 value_type value() const { return Base().value(); }
Chris@16 36 value_type uncertainty() const { return Base().uncertainty(); }
Chris@16 37 value_type lower_bound() const { return Base().lower_bound(); }
Chris@16 38 value_type upper_bound() const { return Base().upper_bound(); }
Chris@16 39 };
Chris@16 40
Chris@16 41 template<class Base>
Chris@16 42 struct physical_constant
Chris@16 43 {
Chris@16 44 typedef typename Base::value_type value_type;
Chris@16 45 operator value_type() const { return Base().value(); }
Chris@16 46 value_type value() const { return Base().value(); }
Chris@16 47 value_type uncertainty() const { return Base().uncertainty(); }
Chris@16 48 value_type lower_bound() const { return Base().lower_bound(); }
Chris@16 49 value_type upper_bound() const { return Base().upper_bound(); }
Chris@16 50 };
Chris@16 51
Chris@16 52 #define BOOST_UNITS_DEFINE_HELPER(name, symbol, template_name) \
Chris@16 53 \
Chris@16 54 template<class T, class Arg1, class Arg2> \
Chris@16 55 struct name ## _typeof_helper<constant<T>, template_name<Arg1, Arg2> >\
Chris@16 56 { \
Chris@16 57 typedef typename name ## _typeof_helper<typename T::value_type, template_name<Arg1, Arg2> >::type type;\
Chris@16 58 }; \
Chris@16 59 \
Chris@16 60 template<class T, class Arg1, class Arg2> \
Chris@16 61 struct name ## _typeof_helper<template_name<Arg1, Arg2>, constant<T> >\
Chris@16 62 { \
Chris@16 63 typedef typename name ## _typeof_helper<template_name<Arg1, Arg2>, typename T::value_type>::type type;\
Chris@16 64 }; \
Chris@16 65 \
Chris@16 66 template<class T, class Arg1, class Arg2> \
Chris@16 67 typename name ## _typeof_helper<typename T::value_type, template_name<Arg1, Arg2> >::type \
Chris@16 68 operator symbol(const constant<T>& t, const template_name<Arg1, Arg2>& u)\
Chris@16 69 { \
Chris@16 70 return(t.value() symbol u); \
Chris@16 71 } \
Chris@16 72 \
Chris@16 73 template<class T, class Arg1, class Arg2> \
Chris@16 74 typename name ## _typeof_helper<template_name<Arg1, Arg2>, typename T::value_type>::type \
Chris@16 75 operator symbol(const template_name<Arg1, Arg2>& u, const constant<T>& t)\
Chris@16 76 { \
Chris@16 77 return(u symbol t.value()); \
Chris@16 78 }
Chris@16 79
Chris@16 80 BOOST_UNITS_DEFINE_HELPER(add, +, unit)
Chris@16 81 BOOST_UNITS_DEFINE_HELPER(add, +, quantity)
Chris@16 82 BOOST_UNITS_DEFINE_HELPER(subtract, -, unit)
Chris@16 83 BOOST_UNITS_DEFINE_HELPER(subtract, -, quantity)
Chris@16 84 BOOST_UNITS_DEFINE_HELPER(multiply, *, unit)
Chris@16 85 BOOST_UNITS_DEFINE_HELPER(multiply, *, quantity)
Chris@16 86 BOOST_UNITS_DEFINE_HELPER(divide, /, unit)
Chris@16 87 BOOST_UNITS_DEFINE_HELPER(divide, /, quantity)
Chris@16 88
Chris@16 89 #undef BOOST_UNITS_DEFINE_HELPER
Chris@16 90
Chris@16 91 #define BOOST_UNITS_DEFINE_HELPER(name, symbol) \
Chris@16 92 \
Chris@16 93 template<class T1, class T2> \
Chris@16 94 struct name ## _typeof_helper<constant<T1>, constant<T2> > \
Chris@16 95 { \
Chris@16 96 typedef typename name ## _typeof_helper<typename T1::value_type, typename T2::value_type>::type type;\
Chris@16 97 }; \
Chris@16 98 \
Chris@16 99 template<class T1, class T2> \
Chris@16 100 typename name ## _typeof_helper<typename T1::value_type, typename T2::value_type>::type \
Chris@16 101 operator symbol(const constant<T1>& t, const constant<T2>& u) \
Chris@16 102 { \
Chris@16 103 return(t.value() symbol u.value()); \
Chris@16 104 } \
Chris@16 105 \
Chris@16 106 template<class T1, class T2> \
Chris@16 107 struct name ## _typeof_helper<constant<T1>, T2> \
Chris@16 108 { \
Chris@16 109 typedef typename name ## _typeof_helper<typename T1::value_type, T2>::type type;\
Chris@16 110 }; \
Chris@16 111 \
Chris@16 112 template<class T1, class T2> \
Chris@16 113 struct name ## _typeof_helper<T1, constant<T2> > \
Chris@16 114 { \
Chris@16 115 typedef typename name ## _typeof_helper<T1, typename T2::value_type>::type type;\
Chris@16 116 }; \
Chris@16 117 \
Chris@16 118 template<class T1, class T2> \
Chris@16 119 typename name ## _typeof_helper<typename T1::value_type, T2>::type \
Chris@16 120 operator symbol(const constant<T1>& t, const T2& u) \
Chris@16 121 { \
Chris@16 122 return(t.value() symbol u); \
Chris@16 123 } \
Chris@16 124 \
Chris@16 125 template<class T1, class T2> \
Chris@16 126 typename name ## _typeof_helper<T1, typename T2::value_type>::type \
Chris@16 127 operator symbol(const T1& t, const constant<T2>& u) \
Chris@16 128 { \
Chris@16 129 return(t symbol u.value()); \
Chris@16 130 }
Chris@16 131
Chris@16 132 BOOST_UNITS_DEFINE_HELPER(add, +)
Chris@16 133 BOOST_UNITS_DEFINE_HELPER(subtract, -)
Chris@16 134 BOOST_UNITS_DEFINE_HELPER(multiply, *)
Chris@16 135 BOOST_UNITS_DEFINE_HELPER(divide, /)
Chris@16 136
Chris@16 137 #undef BOOST_UNITS_DEFINE_HELPER
Chris@16 138
Chris@16 139 #define BOOST_UNITS_DEFINE_HELPER(name, symbol) \
Chris@16 140 \
Chris@16 141 template<class T1> \
Chris@16 142 struct name ## _typeof_helper<constant<T1>, one> \
Chris@16 143 { \
Chris@16 144 typedef typename name ## _typeof_helper<typename T1::value_type, one>::type type;\
Chris@16 145 }; \
Chris@16 146 \
Chris@16 147 template<class T2> \
Chris@16 148 struct name ## _typeof_helper<one, constant<T2> > \
Chris@16 149 { \
Chris@16 150 typedef typename name ## _typeof_helper<one, typename T2::value_type>::type type;\
Chris@16 151 }; \
Chris@16 152 \
Chris@16 153 template<class T1> \
Chris@16 154 typename name ## _typeof_helper<typename T1::value_type, one>::type \
Chris@16 155 operator symbol(const constant<T1>& t, const one& u) \
Chris@16 156 { \
Chris@16 157 return(t.value() symbol u); \
Chris@16 158 } \
Chris@16 159 \
Chris@16 160 template<class T2> \
Chris@16 161 typename name ## _typeof_helper<one, typename T2::value_type>::type \
Chris@16 162 operator symbol(const one& t, const constant<T2>& u) \
Chris@16 163 { \
Chris@16 164 return(t symbol u.value()); \
Chris@16 165 }
Chris@16 166
Chris@16 167 BOOST_UNITS_DEFINE_HELPER(multiply, *)
Chris@16 168 BOOST_UNITS_DEFINE_HELPER(divide, /)
Chris@16 169
Chris@16 170 #undef BOOST_UNITS_DEFINE_HELPER
Chris@16 171
Chris@16 172 template<class T1, long N, long D>
Chris@16 173 struct power_typeof_helper<constant<T1>, static_rational<N,D> >
Chris@16 174 {
Chris@16 175 typedef power_typeof_helper<typename T1::value_type, static_rational<N,D> > base;
Chris@16 176 typedef typename base::type type;
Chris@16 177 static type value(const constant<T1>& arg)
Chris@16 178 {
Chris@16 179 return base::value(arg.value());
Chris@16 180 }
Chris@16 181 };
Chris@16 182
Chris@16 183 #define BOOST_UNITS_DEFINE_HELPER(name, symbol) \
Chris@16 184 \
Chris@16 185 template<class T1, class E> \
Chris@16 186 struct name ## _typeof_helper<constant<T1> > \
Chris@16 187 { \
Chris@16 188 typedef typename name ## _typeof_helper<typename T1::value_type, E>::type type;\
Chris@16 189 }; \
Chris@16 190 \
Chris@16 191 template<class T1> \
Chris@16 192 typename name ## _typeof_helper<typename T1::value_type, one>::type \
Chris@16 193 operator symbol(const constant<T1>& t, const one& u) \
Chris@16 194 { \
Chris@16 195 return(t.value() symbol u); \
Chris@16 196 } \
Chris@16 197 \
Chris@16 198 template<class T2> \
Chris@16 199 typename name ## _typeof_helper<one, typename T2::value_type>::type \
Chris@16 200 operator symbol(const one& t, const constant<T2>& u) \
Chris@16 201 { \
Chris@16 202 return(t symbol u.value()); \
Chris@16 203 }
Chris@16 204
Chris@16 205 #define BOOST_UNITS_PHYSICAL_CONSTANT(name, type, value_, uncertainty_) \
Chris@16 206 struct name ## _t { \
Chris@16 207 typedef type value_type; \
Chris@16 208 operator value_type() const { return value_; } \
Chris@16 209 value_type value() const { return value_; } \
Chris@16 210 value_type uncertainty() const { return uncertainty_; } \
Chris@16 211 value_type lower_bound() const { return value_-uncertainty_; } \
Chris@16 212 value_type upper_bound() const { return value_+uncertainty_; } \
Chris@16 213 }; \
Chris@16 214 BOOST_UNITS_STATIC_CONSTANT(name, boost::units::constant<boost::units::physical_constant<name ## _t> >) = { }
Chris@16 215
Chris@16 216 // stream output
Chris@16 217 template<class Char, class Traits, class Y>
Chris@16 218 inline
Chris@16 219 std::basic_ostream<Char,Traits>& operator<<(std::basic_ostream<Char,Traits>& os,const physical_constant<Y>& val)
Chris@16 220 {
Chris@16 221 boost::io::ios_precision_saver precision_saver(os);
Chris@16 222 //boost::io::ios_width_saver width_saver(os);
Chris@16 223 boost::io::ios_flags_saver flags_saver(os);
Chris@16 224
Chris@16 225 //os << std::setw(21);
Chris@16 226 typedef typename Y::value_type value_type;
Chris@16 227
Chris@16 228 if (val.uncertainty() > value_type())
Chris@16 229 {
Chris@16 230 const double relative_uncertainty = std::abs(val.uncertainty()/val.value());
Chris@16 231
Chris@16 232 const double exponent = std::log10(relative_uncertainty);
Chris@16 233 const long digits_of_precision = static_cast<long>(std::ceil(std::abs(exponent)))+3;
Chris@16 234
Chris@16 235 // should try to replicate NIST CODATA syntax
Chris@16 236 os << std::setprecision(digits_of_precision)
Chris@16 237 //<< std::setw(digits_of_precision+8)
Chris@16 238 //<< std::scientific
Chris@16 239 << val.value();
Chris@16 240 // << long(10*(relative_uncertainty/std::pow(Y(10),Y(exponent))));
Chris@16 241
Chris@16 242 os << " (rel. unc. = "
Chris@16 243 << std::setprecision(1)
Chris@16 244 //<< std::setw(7)
Chris@16 245 << std::scientific
Chris@16 246 << relative_uncertainty << ")";
Chris@16 247 }
Chris@16 248 else
Chris@16 249 {
Chris@16 250 os << val.value() << " (exact)";
Chris@16 251 }
Chris@16 252
Chris@16 253 return os;
Chris@16 254 }
Chris@16 255
Chris@16 256 // stream output
Chris@16 257 template<class Char, class Traits, class Y>
Chris@16 258 inline
Chris@16 259 std::basic_ostream<Char,Traits>& operator<<(std::basic_ostream<Char,Traits>& os,const constant<Y>&)
Chris@16 260 {
Chris@16 261 os << Y();
Chris@16 262 return os;
Chris@16 263 }
Chris@16 264
Chris@16 265 } // namespace units
Chris@16 266
Chris@16 267 } // namespace boost
Chris@16 268
Chris@16 269 #endif // BOOST_UNITS_CONSTANTS_HPP