42 orig_fmt_string(fmt_string), cur_arg_number(0) {
56 insertField(ss.str());
66 insertField(ss.str());
75 if(width) ss << std::setw(width);
76 ss << std::fixed << std::setprecision(frac_precision) << v;
80 if(width) ss << std::setw(width);
81 ss << std::scientific << std::setprecision(frac_precision) << v;
85 ss.unsetf(std::ios::fixed | std::ios::scientific);
86 if(width) ss << std::setw(width);
87 ss << std::setprecision(frac_precision) << v;
99 bool is_neg = (v < 0.0);
102 double log_10 = log10(av);
104 double exp_sign_cor = (log_10 < 0.0) ? -1.0 : 1.0;
106 log_10 = floor(fabs(log_10));
107 double scale = pow(10, -1.0 * exp_sign_cor * log_10);
109 double mant = av * scale;
111 int ilog_10 = rint(log_10);
115 ilog_10 = ilog_10 * ((exp_sign_cor < 0.0) ? -1 : 1);
117 while(((ilog_10 % 3) != 0) || (mant < 1.0)) {
122 int whole = rint(floor(mant));
123 int frac = rint((mant - floor(mant)) * pow(10.0, frac_precision));
124 ss << (is_neg ?
'-' :
' ') << std::setw(3) << whole <<
separator << std::setfill(
'0') << std::setw(frac_precision) << frac <<
'e' << ilog_10 ;
128 insertField(ss.str());
133 std::stringstream ss;
135 ss << std::setw(width);
138 insertField(ss.str());
143 std::stringstream ss;
145 insertField(ss.str());
149 void Format::insertField(
const std::string & s) {
151 if(cur_arg_number > max_field_num) {
152 std::stringstream ss;
153 ss <<
"Too many arguments (" << (cur_arg_number + 1) <<
") passed to Format.";
154 throw BadFormat(ss.str(), *
this);
158 std::stringstream fpat;
159 fpat <<
"%" << cur_arg_number <<
"\\D";
161 std::regex re(fpat.str());
162 int pattern_length = fpat.str().size() - 2;
164 std::list<int> match_positions;
165 for(
auto sri = std::sregex_iterator(fmt_string.begin(), fmt_string.end(), re);
166 sri != std::sregex_iterator();
168 std::smatch m = *sri;
169 int fpos = m.position();
171 if(find(escape_positions.begin(), escape_positions.end(), fpos) == escape_positions.end()) {
173 match_positions.push_front(fpos);
177 for(
auto p : match_positions) {
178 fmt_string.replace(p, pattern_length, s);
183 void Format::initialScan() {
186 for(i = 0, j = 0; i < (orig_fmt_string.size() - 1); i++, j++) {
187 if(orig_fmt_string[i] ==
'%') {
188 if(orig_fmt_string[i+1] ==
'%') {
189 escape_positions.push_back(fmt_string.size());
190 fmt_string.push_back(
'%');
193 else if(isdigit(orig_fmt_string[i+1])) {
194 int fnum = atoi(orig_fmt_string.substr(i+1).c_str());
195 if(fnum > max_field_num) max_field_num = fnum;
196 fmt_string.push_back(
'%');
201 fmt_string.push_back(orig_fmt_string[i]);
204 fmt_string.push_back(orig_fmt_string[orig_fmt_string.size() - 1]);
208 fmt_string = orig_fmt_string;
213 const std::string &
Format::str(
bool check_for_filled_out)
const {
Not much else is spelled that way, so we're probably not going to have too many collisions with code ...