| 222 | namespace { // restrict scope of helper functions to local translation unit |
| 223 | |
| 224 | vector<string> doubleColumn(string name, const vector<double>& comp, |
| 225 | int rows, int width) |
| 226 | { |
| 227 | // extract data for processing |
| 228 | vector<double> data; |
| 229 | vector<string> raw; |
| 230 | string notation = fmt::format("{{:{}.{}g}}", width, (width - 1) / 2); |
| 231 | int csize = static_cast<int>(comp.size()); |
| 232 | int dots = csize + 1; |
| 233 | if (csize <= rows) { |
| 234 | for (const auto& val : comp) { |
| 235 | data.push_back(val); |
| 236 | raw.push_back(boost::trim_copy(fmt::format(fmt::runtime(notation), val))); |
| 237 | } |
| 238 | } else { |
| 239 | dots = (rows + 1) / 2; |
| 240 | for (int row = 0; row < dots; row++) { |
| 241 | data.push_back(comp[row]); |
| 242 | raw.push_back(boost::trim_copy( |
| 243 | fmt::format(fmt::runtime(notation), comp[row]))); |
| 244 | } |
| 245 | for (int row = csize - rows / 2; row < csize; row++) { |
| 246 | data.push_back(comp[row]); |
| 247 | raw.push_back(boost::trim_copy( |
| 248 | fmt::format(fmt::runtime(notation), comp[row]))); |
| 249 | } |
| 250 | } |
| 251 | |
| 252 | // determine notation; all entries use identical formatting |
| 253 | bool isFloat = false; |
| 254 | bool isScientific = false; |
| 255 | size_t head = 0; |
| 256 | size_t tail = 0; |
| 257 | size_t exp = 0; |
| 258 | for (const auto& repr : raw) { |
| 259 | string name = repr; |
| 260 | if (name[0] == '-') { |
| 261 | // leading negative sign is not considered |
| 262 | name = name.substr(1); |
| 263 | } |
| 264 | if (name.find('e') != string::npos) { |
| 265 | // scientific notation |
| 266 | if (!isScientific) { |
| 267 | head = 1; |
| 268 | tail = name.find('e') - name.find('.'); |
| 269 | exp = 4; // size of exponent |
| 270 | } else { |
| 271 | tail = std::max(tail, name.find('e') - name.find('.')); |
| 272 | } |
| 273 | isFloat = true; |
| 274 | isScientific = true; |
| 275 | } else if (name.find('.') != string::npos) { |
| 276 | // floating point notation |
| 277 | isFloat = true; |
| 278 | if (!isScientific) { |
| 279 | head = std::max(head, name.find('.')); |
| 280 | tail = std::max(tail, name.size() - name.find('.')); |
| 281 | } |