From: g0dil Date: Wed, 30 Sep 2009 20:24:08 +0000 (+0000) Subject: Utils: Add senf::format::eng format manipulation members X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=c9d8ba8de7801af854581eb9e175d7b4f19ece3d;p=senf.git Utils: Add senf::format::eng format manipulation members git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1469 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/Utils/Format.cc b/senf/Utils/Format.cc index 3373bb8..78d3e8d 100644 --- a/senf/Utils/Format.cc +++ b/senf/Utils/Format.cc @@ -50,20 +50,29 @@ prefix_ std::ostream & senf::format::operator<<(std::ostream & os, eng const & v boost::io::ios_base_all_saver ibas (os); boost::io::ios_fill_saver ifs (os); + os.setf(v_.flags_, v_.mask_); + if (v_.havePrecision_) + os.precision(v_.precision_); + if (v_.haveWidth_) + os.width(v_.width_); + if (v_.haveFill_) + os.fill(v_.fill_); + unsigned prec (os.precision()); if (prec < 4) prec = 4; unsigned w (os.width()); char fill (os.fill()); unsigned minw (prec+2+((os.flags() & std::ios_base::showbase) ? 1 : 4)); - std::ios_base::fmtflags align (os.flags() & std::ios_base::adjustfield); - if (! std::isnan(v_.d)) + std::ios_base::fmtflags flags (os.flags()); + std::ios_base::fmtflags align (flags & std::ios_base::adjustfield); + if (! std::isnan(v_.d_)) minw += prec+3; - double ref (std::fabs(v_.v)); - double v (v_.v); - double d (0.0); - if (! std::isnan(v_.d)) d = std::fabs(v_.d); + float ref (std::fabs(v_.v_)); + float v (v_.v_); + float d (0.0); + if (! std::isnan(v_.d_)) d = std::fabs(v_.d_); int scale (0); if (d > ref) ref = d; @@ -82,9 +91,8 @@ prefix_ std::ostream & senf::format::operator<<(std::ostream & os, eng const & v os << std::dec << std::setprecision(prec-3) << std::fixed; if (w > 0) { - if ((align == 0 || align == std::ios_base::right || align == std::ios_base::internal) - && w > minw) - os << std::setw(prec+2+w-minw); + if ((align == 0 || align == std::ios_base::right || align == std::ios_base::internal)) + os << std::setw(prec+2+(w>minw ? w-minw : 0)); else os << std::right << std::setfill(' ') << std::setw(prec+2); } @@ -93,19 +101,19 @@ prefix_ std::ostream & senf::format::operator<<(std::ostream & os, eng const & v os << v; os << std::setfill('0') << std::noshowpos; - if (! std::isnan(v_.d)) { + if (! std::isnan(v_.d_)) { os << "+-"; if (w > 0) os << std::setw(prec+1); os << d; } - if ((os.flags() & std::ios_base::showbase) && unsigned(std::abs(scale/3)) <= SIScales) { + if ((flags & std::ios_base::showbase) && unsigned(std::abs(scale/3)) <= SIScales) { if (w > 0 || scale != 0) os << SIPrefix[scale/3+SIScales]; } - else if ((os.flags() & std::ios_base::showpoint) || scale != 0) - os << ((os.flags() & std::ios_base::uppercase)?'E':'e') + else if ((flags & std::ios_base::showpoint) || scale != 0) + os << ((flags & std::ios_base::uppercase)?'E':'e') << std::showpos << std::internal << std::setw(3) << scale; else if (w > 0) os << " "; diff --git a/senf/Utils/Format.cci b/senf/Utils/Format.cci index ed1ad85..7871b7d 100644 --- a/senf/Utils/Format.cci +++ b/senf/Utils/Format.cci @@ -30,10 +30,126 @@ #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// -prefix_ senf::format::eng::eng(double v_, double d_) - : v (v_), d (d_) +prefix_ senf::format::eng::eng(float v, float d) + : v_ (v), d_ (d), haveWidth_ (false), width_ (0), havePrecision_ (false), precision_ (0), + haveFill_ (false), fill_ (' '), mask_ (), flags_ () {} +prefix_ senf::format::eng const & senf::format::eng::setw(unsigned w) + const +{ + haveWidth_ = true; + width_ = w; + return *this; +} + +prefix_ senf::format::eng const & senf::format::eng::setprecision(unsigned p) + const +{ + havePrecision_ = true; + precision_ = p; + return *this; +} + +prefix_ senf::format::eng const & senf::format::eng::setfill(char c) + const +{ + haveFill_ = true; + fill_ = c; + return *this; +} + +prefix_ senf::format::eng const & senf::format::eng::showbase() + const +{ + mask_ |= std::ios_base::showbase; + flags_ |= std::ios_base::showbase; + return *this; +} + +prefix_ senf::format::eng const & senf::format::eng::noshowbase() + const +{ + mask_ |= std::ios_base::showbase; + flags_ &= ~std::ios_base::showbase; + return *this; +} + +prefix_ senf::format::eng const & senf::format::eng::showpos() + const +{ + mask_ |= std::ios_base::showpos; + flags_ |= std::ios_base::showpos; + return *this; +} + +prefix_ senf::format::eng const & senf::format::eng::noshowpos() + const +{ + mask_ |= std::ios_base::showpos; + flags_ &= ~std::ios_base::showpos; + return *this; +} + +prefix_ senf::format::eng const & senf::format::eng::showpoint() + const +{ + mask_ |= std::ios_base::showpoint; + flags_ |= std::ios_base::showpoint; + return *this; +} + +prefix_ senf::format::eng const & senf::format::eng::noshowpoint() + const +{ + mask_ |= std::ios_base::showpoint; + flags_ &= ~std::ios_base::showpoint; + return *this; +} + +prefix_ senf::format::eng const & senf::format::eng::uppercase() + const +{ + mask_ |= std::ios_base::uppercase; + flags_ |= std::ios_base::uppercase; + return *this; +} + +prefix_ senf::format::eng const & senf::format::eng::nouppercase() + const +{ + mask_ |= std::ios_base::uppercase; + flags_ &= ~std::ios_base::uppercase; + return *this; +} + +prefix_ senf::format::eng const & senf::format::eng::left() + const +{ + mask_ |= std::ios_base::adjustfield; + flags_ &= ~std::ios_base::adjustfield; + flags_ |= std::ios_base::left; + return *this; +} + +prefix_ senf::format::eng const & senf::format::eng::internal() + const +{ + mask_ |= std::ios_base::adjustfield; + flags_ &= ~std::ios_base::adjustfield; + flags_ |= std::ios_base::internal; + return *this; +} + +prefix_ senf::format::eng const & senf::format::eng::right() + const +{ + mask_ |= std::ios_base::adjustfield; + flags_ &= ~std::ios_base::adjustfield; + flags_ |= std::ios_base::right; + return *this; +} + ///////////////////////////////cci.e/////////////////////////////////////// #undef prefix_ diff --git a/senf/Utils/Format.hh b/senf/Utils/Format.hh index beb5008..7e0b364 100644 --- a/senf/Utils/Format.hh +++ b/senf/Utils/Format.hh @@ -59,47 +59,60 @@ namespace format { senf::format::eng supports several formating options: - \par \c std::setw() + \par \c std::\c setw If the width is set >0, the output will be padded internally. If the width is set to more than the minimal required output width including internal padding, the output is padded on the left or right depending on the streams \c ajustfield setting (changed with \c std::left, \c std:;right or \c std::interal). If the \c adjustfield is set to \c internal, padding is added between the sign and the number. - \par \c std::\c setprecision() + \par \c std::\c setprecision The default stream precision is 6. This will schow values with 6 significant digits. The count includes the number of digits in front of the decimal point. - \par \c std::\c showbase + \par \c std::\c showbase, \c std::\c noshowbase If the \c showbase flag is set, Instead of writing out the scale exponent in numeric form, output the corresponding SI prefix. - \par \c std::\c showpos + \par \c std::\c showpos, \c std::\c noshowpos If the \c showpos flag is set, positive values will have a '+' sign. - \par \c std::\c showpoint + \par \c std::\c showpoint, \c std::\c noshowpoint If the \c showpoint flag is set, the exponent will be output even if it is 0. Otherwise, if \c width is set, the exponent will be replaced with 4 blanks. - \par \c std::\c uppercase + \par \c std::\c uppercase, \c std::\c nouppercase If the \c uppercase flag is set, the exponent letter will be an uppercase 'E' instead of 'e'. SI prefixes are \e not uppercased, since some SI prefixes differ only in case. - \par \c std::\c setfill() + \par \c std::\c setfill The fill character is honored for the outside padding but \e not for the internal padding. + \par \c std::\c left, \c std::\c internal, \c std::\c right + The alignment flags specify the external padding but do not affect the internal + padding. + + All these flags may optionally be set by calling members of the senf::format::eng() return + value with the same name. + Examples: \code - os << senf::format::eng(1.23); - -> "1.230" - os << std::setw(1) << senf::format::eng(1.23); - -> " 1.230 " - os << std::setw(25) << std::setprecision(5) << std::showpos << std::uppercase - << std::internal << senf::format::eng(12345,67); - -> "+ 12.35+-000.07E+03" - os << std::showbase << senf::format::eng(12345,67); - -> "12.345+-0.067k" + os << senf::format::eng(1.23); + -> "1.230" + + os << std::setw(1) << senf::format::eng(1.23); + -> " 1.230 " + + os << std::setw(25) << std::setprecision(5) << std::showpos << std::uppercase + << std::internal << senf::format::eng(12345,67); + -> "+ 12.35+-000.07E+03" + + os << std::showbase << senf::format::eng(12345,67); + -> "12.345+-0.067k" + + senf::str(senf::format::eng(12.345,67).setw().setprecision(5).showpoint().uppercase()) + -> " 12.35+-67.00E+00" \endcode \param[in] v value @@ -107,16 +120,46 @@ namespace format { \ingroup senf_utils_format */ - streamable_type eng(double v, double d=NAN); + streamable_type eng(float v, float d=NAN); #else - struct eng + class eng { - eng(double v_, double d_ = std::numeric_limits::quiet_NaN()); + public: + eng(float v, float d = std::numeric_limits::quiet_NaN()); + + eng const & setw(unsigned w = 1) const; + eng const & setprecision(unsigned p) const; + eng const & setfill(char c) const; + + eng const & showbase() const; + eng const & noshowbase() const; + eng const & showpos() const; + eng const & noshowpos() const; + eng const & showpoint() const; + eng const & noshowpoint() const; + eng const & uppercase() const; + eng const & nouppercase() const; + eng const & left() const; + eng const & internal() const; + eng const & right() const; + + private: + float v_; + float d_; + + mutable bool haveWidth_; + mutable unsigned width_; + mutable bool havePrecision_; + mutable unsigned precision_; + mutable bool haveFill_; + mutable char fill_; + mutable std::ios_base::fmtflags mask_; + mutable std::ios_base::fmtflags flags_; + + friend std::ostream & operator<<(std::ostream & os, eng const & v); - double v; - double d; }; std::ostream & operator<<(std::ostream & os, eng const & v); diff --git a/senf/Utils/Format.test.cc b/senf/Utils/Format.test.cc index 996fe38..ef1a2a2 100644 --- a/senf/Utils/Format.test.cc +++ b/senf/Utils/Format.test.cc @@ -31,6 +31,7 @@ #include #include "Format.hh" #include +#include "String.hh" #include #include @@ -112,6 +113,23 @@ BOOST_AUTO_UNIT_TEST(formatEng) ss << std::showbase << senf::format::eng(12345,67); BOOST_CHECK_EQUAL( ss.str(), "12.345+-0.067k" ); } + + // class member formatting + BOOST_CHECK_EQUAL( senf::str(senf::format::eng(12345, 67) + .setw() + .setprecision(5) + .setfill('0') + .showbase() + .showpos() + .internal()), + "+012.35+-000.07k" ); + + BOOST_CHECK_EQUAL( senf::str(senf::format::eng(12.345, 67) + .setw() + .setprecision(5) + .showpoint() + .uppercase()), + " 12.35+-067.00E+00" ); } BOOST_AUTO_UNIT_TEST(dumpint) diff --git a/senf/Utils/Statistics.cc b/senf/Utils/Statistics.cc index 730898d..a22a57e 100644 --- a/senf/Utils/Statistics.cc +++ b/senf/Utils/Statistics.cc @@ -86,22 +86,20 @@ senf::StatisticsBase::output(unsigned n) prefix_ void senf::StatisticsBase::consoleList(unsigned level, std::ostream & os) const { - os << boost::format("%s%-5d%|15t| %12s %19.5g %12s\n") - % std::string(2*level,' ') - % rank() - % boost::io::group(std::setw(1),senf::format::eng(min())) - % boost::io::group(std::setw(1),senf::format::eng(avg(),dev())) - % boost::io::group(std::setw(1),senf::format::eng(max())); + namespace fmt = senf::format; + + os << boost::format("%s%-5d%|15t| %12.5g %19.5g %12.5g\n") + % std::string(2*level,' ') % rank() + % fmt::eng(min()).setw() % fmt::eng(avg(),dev()).setw() % fmt::eng(max()).setw(); { OutputMap::const_iterator i (outputs_.begin()); OutputMap::const_iterator i_end (outputs_.end()); for (; i != i_end; ++i) - os << boost::format(" %3d %12s %19.5g %12s\n") + os << boost::format(" %3d %12.5g %19.5g %12.5g\n") % i->second.n - % boost::io::group(std::setw(1),senf::format::eng(i->second.min/i->second.n)) - % boost::io::group(std::setw(1),senf::format::eng(i->second.avg/i->second.n, - i->second.dev/i->second.n)) - % boost::io::group(std::setw(1),senf::format::eng(i->second.max/i->second.n)); + % fmt::eng(i->second.min).setw() + % fmt::eng(i->second.avg, i->second.dev).setw() + % fmt::eng(i->second.max).setw(); } { Children::const_iterator i (children_.begin()); @@ -130,7 +128,11 @@ prefix_ void senf::StatisticsBase::generateOutput() i->second.max += j->max; i->second.dev += j->dev; } - i->second.signal(i->second.min/n, i->second.avg/n, i->second.max/n, i->second.dev/n); + i->second.min /= n; + i->second.avg /= n; + i->second.max /= n; + i->second.dev /= n; + i->second.signal(i->second.min, i->second.avg, i->second.max, i->second.dev); } } @@ -208,7 +210,7 @@ prefix_ senf::Statistics::Statistics() prefix_ void senf::Statistics::consoleList(std::ostream & os) { - os << "RANK WIN MIN AVG MAX\n"; + os << "RANK WIN MIN AVG MAX\n"; StatisticsBase::consoleList(0, os); } diff --git a/senf/Utils/Statistics.cci b/senf/Utils/Statistics.cci index d58a9bd..0ed4fbd 100644 --- a/senf/Utils/Statistics.cci +++ b/senf/Utils/Statistics.cci @@ -92,7 +92,7 @@ prefix_ void senf::StatisticsBase::OutputEntry::consoleList(std::ostream & os) // senf::StatisticsBase prefix_ senf::StatisticsBase::StatisticsBase() - : min_ (0.0f), avg_ (0.0f), max_ (0.0f), maxQueueLen_ (0u) + : min_ (0.0f), avg_ (0.0f), max_ (0.0f), dev_ (0.0f), maxQueueLen_ (0u) {} prefix_ senf::StatisticsBase::~StatisticsBase()