Ticket #7261: measurement.hpp.diff

File measurement.hpp.diff, 9.7 KB (added by Paul A. Bristow, 10 years ago)

Diff for changes to /example/measurement.hpp to honor width

  • .hpp

    old new  
    1 // Boost.Units - A C++ library for zero-overhead dimensional analysis and 
     1// Boost.Units - A C++ library for zero-overhead dimensional analysis and
    22// unit/quantity manipulation and conversion
    33//
    44// Copyright (C) 2003-2008 Matthias Christian Schabel
     
    1919#include <boost/io/ios_state.hpp>
    2020#include <boost/units/static_rational.hpp>
    2121
     22#include <boost/type_traits.hpp>
     23
    2224namespace boost {
    2325
    2426namespace units {
     
    3537
    3638template<class Y>
    3739class measurement
    38 {   
     40{
    3941    public:
    4042        typedef measurement<Y>                  this_type;
    4143        typedef Y                               value_type;
    42        
     44
    4345        measurement(const value_type& val = value_type(),
    44                     const value_type& err = value_type()) : 
     46                    const value_type& err = value_type()) :
    4547            value_(val),
    46             uncertainty_(std::abs(err)) 
     48            uncertainty_(std::abs(err))
    4749        { }
    48        
    49         measurement(const this_type& source) : 
     50
     51        measurement(const this_type& source) :
    5052            value_(source.value_),
    51             uncertainty_(source.uncertainty_) 
     53            uncertainty_(source.uncertainty_)
    5254        { }
    53        
     55
    5456        //~measurement() { }
    55        
     57
    5658        this_type& operator=(const this_type& source)
    5759        {
    5860            if (this == &source) return *this;
    59            
     61
    6062            value_ = source.value_;
    6163            uncertainty_ = source.uncertainty_;
    62            
     64
    6365            return *this;
    6466        }
    65        
     67
    6668        operator value_type() const    { return value_; }
    67        
     69
    6870        value_type value() const       { return value_; }
    6971        value_type uncertainty() const { return uncertainty_; }
    7072        value_type lower_bound() const { return value_-uncertainty_; }
    7173        value_type upper_bound() const { return value_+uncertainty_; }
    72        
    73         this_type& operator+=(const value_type& val)           
    74         { 
    75             value_ += val; 
    76             return *this; 
     74
     75        this_type& operator+=(const value_type& val)
     76        {
     77            value_ += val;
     78            return *this;
    7779        }
    78        
    79         this_type& operator-=(const value_type& val)           
    80         { 
    81             value_ -= val; 
    82             return *this; 
     80
     81        this_type& operator-=(const value_type& val)
     82        {
     83            value_ -= val;
     84            return *this;
    8385        }
    84        
    85         this_type& operator*=(const value_type& val)           
    86         { 
    87             value_ *= val; 
    88             uncertainty_ *= val; 
    89             return *this; 
     86
     87        this_type& operator*=(const value_type& val)
     88        {
     89            value_ *= val;
     90            uncertainty_ *= val;
     91            return *this;
    9092        }
    91        
    92         this_type& operator/=(const value_type& val)           
    93         { 
    94             value_ /= val; 
    95             uncertainty_ /= val; 
    96             return *this; 
     93
     94        this_type& operator/=(const value_type& val)
     95        {
     96            value_ /= val;
     97            uncertainty_ /= val;
     98            return *this;
    9799        }
    98        
     100
    99101        this_type& operator+=(const this_type& /*source*/);
    100         this_type& operator-=(const this_type& /*source*/);       
    101         this_type& operator*=(const this_type& /*source*/);       
     102        this_type& operator-=(const this_type& /*source*/);
     103        this_type& operator*=(const this_type& /*source*/);
    102104        this_type& operator/=(const this_type& /*source*/);
    103105
     106
     107
    104108    private:
    105109        value_type          value_,
    106110                            uncertainty_;
    107 };
     111}; // class measurement
    108112
    109 }
     113} // namespace units
     114}  // namespace boost
    110115
    111 }
    112 
    113116#if BOOST_UNITS_HAS_BOOST_TYPEOF
    114 
    115 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::measurement, 1)
    116 
     117  BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::measurement, 1)
    117118#endif
    118119
    119120namespace boost {
    120 
    121121namespace units {
    122122
    123123template<class Y>
     
    127127{
    128128    uncertainty_ = std::sqrt(sqr(uncertainty_)+sqr(source.uncertainty_));
    129129    value_ += source.value_;
    130    
     130
    131131    return *this;
    132132}
    133133
     
    138138{
    139139    uncertainty_ = std::sqrt(sqr(uncertainty_)+sqr(source.uncertainty_));
    140140    value_ -= source.value_;
    141    
     141
    142142    return *this;
    143143}
    144144
     
    151151              std::sqrt(sqr(uncertainty_/value_)+
    152152                        sqr(source.uncertainty_/source.value_));
    153153    value_ *= source.value_;
    154    
     154
    155155    return *this;
    156156}
    157157
     
    164164              std::sqrt(sqr(uncertainty_/value_)+
    165165                        sqr(source.uncertainty_/source.value_));
    166166    value_ /= source.value_;
    167    
     167
    168168    return *this;
    169169}
    170170
     
    268268}
    269269
    270270/// specialize power typeof helper
    271 template<class Y,long N,long D> 
     271template<class Y,long N,long D>
    272272struct power_typeof_helper<measurement<Y>,static_rational<N,D> >
    273 { 
     273{
    274274    typedef measurement<
    275275        typename power_typeof_helper<Y,static_rational<N,D> >::type
    276     > type; 
    277    
    278     static type value(const measurement<Y>& x) 
    279     { 
     276    > type;
     277
     278    static type value(const measurement<Y>& x)
     279    {
    280280        const static_rational<N,D>  rat;
    281281
    282282        const Y m = Y(rat.numerator())/Y(rat.denominator()),
    283283                newval = std::pow(x.value(),m),
    284284                err = newval*std::sqrt(std::pow(m*x.uncertainty()/x.value(),2));
    285        
     285
    286286        return type(newval,err);
    287287    }
    288288};
    289289
    290290/// specialize root typeof helper
    291 template<class Y,long N,long D> 
    292 struct root_typeof_helper<measurement<Y>,static_rational<N,D> >               
    293 { 
     291template<class Y,long N,long D>
     292struct root_typeof_helper<measurement<Y>,static_rational<N,D> >
     293{
    294294    typedef measurement<
    295295        typename root_typeof_helper<Y,static_rational<N,D> >::type
    296     > type; 
    297    
    298     static type value(const measurement<Y>& x) 
    299     { 
     296    > type;
     297
     298    static type value(const measurement<Y>& x)
     299    {
    300300        const static_rational<N,D>  rat;
    301301
    302302        const Y m = Y(rat.denominator())/Y(rat.numerator()),
    303303                newval = std::pow(x.value(),m),
    304304                err = newval*std::sqrt(std::pow(m*x.uncertainty()/x.value(),2));
    305        
     305
    306306        return type(newval,err);
    307307    }
    308308};
     
    310310// stream output
    311311template<class Y>
    312312inline
    313 std::ostream& operator<<(std::ostream& os,const measurement<Y>& val)
     313std::ostream& operator<<(std::ostream& os, const measurement<Y>& val)
    314314{
    315315    boost::io::ios_precision_saver precision_saver(os);
    316316    boost::io::ios_flags_saver flags_saver(os);
    317    
    318     os << val.value() << "(+/-" << val.uncertainty() << ")";
    319    
     317    std::streamsize w = os.width();
     318    if (w > 0)
     319    { // Need to output both as one string to avoid disrupting column width.
     320      std::ostringstream oss;
     321      oss << val.value() << "(+/-" << val.uncertainty() << ")";
     322      os.width(w);
     323      os << oss.str();
     324    }
     325    else
     326    { // Output direct to os.
     327       os << val.value() << "(+/-" << val.uncertainty() << ")";
     328    }
    320329    return os;
    321330}
    322331
     332// Specialization of autoprefix_norm for UDT boost::units::measurement<Y>
     333// See io.hpp.
     334
     335// Note that autoprefix_norm_impl is in the boost::units namespace,
     336// but autoprefix_norm being specialized is in the UDT namespace (here measd).
     337// If the UDT is parameterized for floating-point type (FPT), as the
     338// example measurement, then its type can be used as a template parameter
     339// to autoprefix_norm_impl, but if not then double or other FPT is needed.
     340// This type *must* be convertible to double.
     341// If this may involve loss of precision then a warning will be issued.
     342/*
     343
     344using  boost::units::measd;
     345using boost::units::autoprefix_norm_impl;
     346
     347autoprefix_norm_impl<measd, true>::type
     348autoprefix_norm(const measd & arg)
     349{
     350  return autoprefix_norm_impl<double, true>::call(arg);
     351}
     352// Specialization of autoprefix_norm for UDT boost::units::measurement<float>
     353// Warns "conversion from 'long double' to 'double', possible loss of data"
     354autoprefix_norm_impl<boost::units::measurement<float>, true>::type
     355autoprefix_norm(const boost::units::measurement<float> & arg)
     356{
     357  return autoprefix_norm_impl<double, true>::call(arg); // double or float (long double warns of loss)
     358}
     359
     360// Specialization of autoprefix_norm for UDT boost::units::measurement<double>
     361// Warns "conversion from 'long double' to 'double', possible loss of data"
     362autoprefix_norm_impl<double, true>::type
     363autoprefix_norm(const boost::units::measurement<double> & arg)
     364{
     365  return autoprefix_norm_impl<double, true>::call(arg); // double or float (long double warns of loss)
     366}
     367
     368// This specialization is required to get autoprefix to work with this class.
     369//template<class Y>
     370//typename autoprefix_norm_impl<boost::units::measurement<Y>, true>::type
     371//autoprefix_norm(const boost::units::measurement<Y> & arg)
     372//{
     373//  return autoprefix_norm_impl<double, true>::call(arg);
     374//}
     375*/
     376
     377using boost::units::autoprefix_norm_impl;
     378using boost::units::measurement; // Might be in another namespace?
     379
     380template<class Y>
     381typename autoprefix_norm_impl<measurement<Y>, true>::type
     382autoprefix_norm(const measurement<Y> & arg)
     383{
     384  // If measurement was not parameterized on floating-point type, might use
     385  // `return autoprefix_norm_impl<double, true>::call(arg);`
     386  // but must be conertible to `double`.
     387  return autoprefix_norm_impl<Y, true>::call(arg);
     388}
     389
     390
    323391} // namespace units
    324 
    325392} // namespace boost
    326393
    327394#endif // BOOST_UNITS_MEASUREMENT_HPP