constants.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 202 行

HPP
202
字号
// Boost.Units - A C++ library for zero-overhead dimensional analysis and // unit/quantity manipulation and conversion//// Copyright (C) 2003-2008 Matthias Christian Schabel// Copyright (C) 2008 Steven Watanabe//// Distributed under the Boost Software License, Version 1.0. (See// accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)#ifndef BOOST_UNITS_CONSTANTS_HPP#define BOOST_UNITS_CONSTANTS_HPP#include <boost/config/no_tr1/cmath.hpp>#include <iosfwd>#include <iomanip>#include <boost/io/ios_state.hpp>#include <boost/units/static_constant.hpp>#include <boost/units/units_fwd.hpp>#include <boost/units/operators.hpp>namespace boost {namespace units {template<class Base>struct constant {     typedef typename Base::value_type value_type;     operator value_type() const    { return Base().value(); }     value_type value() const       { return Base().value(); }     value_type uncertainty() const { return Base().uncertainty(); }     value_type lower_bound() const { return Base().lower_bound(); }     value_type upper_bound() const { return Base().upper_bound(); } }; template<class Base>struct physical_constant {     typedef typename Base::value_type value_type;     operator value_type() const    { return Base().value(); }     value_type value() const       { return Base().value(); }     value_type uncertainty() const { return Base().uncertainty(); }     value_type lower_bound() const { return Base().lower_bound(); }     value_type upper_bound() const { return Base().upper_bound(); } }; #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 outputtemplate<class Char, class Traits, class Y>inlinestd::basic_ostream<Char,Traits>& operator<<(std::basic_ostream<Char,Traits>& 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() > value_type())    {        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;                // should try to replicate NIST CODATA syntax         os << std::setprecision(digits_of_precision)            //<< std::setw(digits_of_precision+8)            //<< std::scientific           << val.value();//           << long(10*(relative_uncertainty/std::pow(Y(10),Y(exponent))));        os << " (rel. unc. = "            << std::setprecision(1)            //<< std::setw(7)            << std::scientific           << relative_uncertainty << ")";    }    else    {        os << val.value() << " (exact)";    }        return os;}// stream outputtemplate<class Char, class Traits, class Y>inlinestd::basic_ostream<Char,Traits>& operator<<(std::basic_ostream<Char,Traits>& os,const constant<Y>&){    os << Y();    return os;}} // namespace units} // namespace boost#endif // BOOST_UNITS_CONSTANTS_HPP

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?