00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #include "Format.hh"
00027 #include "Format.ih"
00028
00029
00030 #include <cmath>
00031 #include <boost/io/ios_state.hpp>
00032 #include <iomanip>
00033 #include <sstream>
00034
00035
00036 #define prefix_
00037
00038
00039 namespace {
00040
00041 char const SIPrefix[] = { 'y', 'z', 'a', 'f', 'p', 'n', 'u', 'm',
00042 ' ',
00043 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' };
00044 unsigned const SIScales = 8;
00045
00046 }
00047
00048 prefix_ std::ostream & senf::format::operator<<(std::ostream & os, eng const & v_)
00049 {
00050 boost::io::ios_base_all_saver ibas (os);
00051 boost::io::ios_fill_saver ifs (os);
00052
00053 os.setf(v_.flags_, v_.mask_);
00054 if (v_.havePrecision_)
00055 os.precision(v_.precision_);
00056 if (v_.haveWidth_)
00057 os.width(v_.width_);
00058 if (v_.haveFill_)
00059 os.fill(v_.fill_);
00060
00061 unsigned prec (os.precision());
00062 if (prec < 4)
00063 prec = 4;
00064 unsigned w (os.width());
00065 char fill (os.fill());
00066 unsigned minw (prec+2+((os.flags() & std::ios_base::showbase) ? 1 : 4));
00067 std::ios_base::fmtflags flags (os.flags());
00068 std::ios_base::fmtflags align (flags & std::ios_base::adjustfield);
00069 if (! std::isnan(v_.d_))
00070 minw += prec+3;
00071
00072 float ref (std::fabs(v_.v_));
00073 float v (v_.v_);
00074 float d (0.0);
00075 if (! std::isnan(v_.d_)) d = std::fabs(v_.d_);
00076 int scale (0);
00077
00078 if (d > ref) ref = d;
00079 while (ref >= 1000.0) {
00080 ref /= 1000.0;
00081 v /= 1000.0;
00082 d /= 1000.0;
00083 scale += 3;
00084 }
00085 while (ref > 0 && ref < 1) {
00086 ref *= 1000.0;
00087 v *= 1000.0;
00088 d *= 1000.0;
00089 scale -= 3;
00090 }
00091
00092 os << std::dec << std::setprecision(prec-3) << std::fixed;
00093 if (w > 0) {
00094 if ((align == 0 || align == std::ios_base::right || align == std::ios_base::internal))
00095 os << std::setw(prec+2+(w>minw ? w-minw : 0));
00096 else
00097 os << std::right << std::setfill(' ') << std::setw(prec+2);
00098 }
00099 else
00100 os << std::right;
00101 os << v;
00102
00103 os << std::setfill('0') << std::noshowpos;
00104 if (! std::isnan(v_.d_)) {
00105 os << "+-";
00106 if (w > 0)
00107 os << std::setw(prec+1);
00108 os << d;
00109 }
00110
00111 if ((flags & std::ios_base::showbase) && unsigned(std::abs(scale/3)) <= SIScales) {
00112 if (w > 0 || scale != 0)
00113 os << SIPrefix[scale/3+SIScales];
00114 }
00115 else if ((flags & std::ios_base::showpoint) || scale != 0)
00116 os << ((flags & std::ios_base::uppercase)?'E':'e')
00117 << std::showpos << std::internal << std::setw(3) << scale;
00118 else if (w > 0)
00119 os << " ";
00120 if (w > minw && align == std::ios_base::left)
00121 os << std::setfill(fill) << std::setw(w-minw) << "";
00122
00123 return os;
00124 }
00125
00126 prefix_ std::string senf::format::detail::dumpintSigned(long long v, unsigned bits)
00127 {
00128 if (v<0) return dumpintUnsigned(-v,bits,-1);
00129 else return dumpintUnsigned(v,bits,+1);
00130 }
00131
00132 prefix_ std::string senf::format::detail::dumpintUnsigned(unsigned long long v, unsigned bits,
00133 int sign)
00134 {
00135 int bytes ((bits+7)/8);
00136 int digs (int(2.4*bytes)+1);
00137 std::stringstream ss;
00138 ss << (sign ? (sign<0 ? "-" : " ") : "")
00139 << "0x" << std::setw(2*bytes) << std::setfill('0') << std::hex
00140 << 1u*v
00141 << " (" << std::setw(digs+(sign ? 1 : 0)) << std::setfill(' ') << std::dec;
00142 if (sign)
00143 ss << sign*static_cast<long long>(v);
00144 else
00145 ss << 1u*v;
00146 ss << ") (";
00147 for (int i (bytes-1); i>=0; --i) {
00148 char c ((v>>(8*i))&0xff);
00149 ss << ((c>=32 && c<=126) ? c : '.');
00150 }
00151 ss << ')';
00152 return ss.str();
00153 }
00154
00155 unsigned int senf::format::IndentHelper::static_level = 0;
00156
00157
00158
00159 #undef prefix_
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171