diff --git a/include/VariadicTable.h b/include/VariadicTable.h index 585c83d..416883d 100644 --- a/include/VariadicTable.h +++ b/include/VariadicTable.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include /** * Used to specify the column format @@ -56,12 +58,28 @@ class VariadicTable VariadicTable(std::vector headers, unsigned int static_column_size = 0, unsigned int cell_padding = 1) - : _headers(headers), + : //_headers(headers), _num_columns(std::tuple_size::value), _static_column_size(static_column_size), _cell_padding(cell_padding) { assert(headers.size() == _num_columns); + _headers.emplace_back(headers); + _precision.resize(_num_columns,2); + _column_format.resize(_num_columns,VariadicTableColumnFormat::AUTO); + } + + /** + * Add a row of sub-headers + * + * Easiest to use like: + * table.addHeader({h1, h2, h3}); + * + * @param data A vector of header strings to add + */ + void addHeader(std::vector subheaders) { + assert(subheaders.size() == _num_columns); + _headers.emplace_back(subheaders); } /** @@ -94,18 +112,21 @@ class VariadicTable stream << std::string(total_width, '-') << "\n"; // Print out the headers - stream << "|"; - for (unsigned int i = 0; i < _num_columns; i++) - { - // Must find the center of the column - auto half = _column_sizes[i] / 2; - half -= _headers[i].size() / 2; + for (unsigned int j = 0; j < (unsigned int) _headers.size(); j++) + { + stream << "|"; + for (unsigned int i = 0; i < _num_columns; i++) + { + // Must find the center of the column + auto half = _column_sizes[i] / 2; + half -= _headers[j][i].size() / 2; - stream << std::string(_cell_padding, ' ') << std::setw(_column_sizes[i]) << std::left - << std::string(half, ' ') + _headers[i] << std::string(_cell_padding, ' ') << "|"; - } + stream << std::string(_cell_padding, ' ') << std::setw(_column_sizes[i]) << std::left + << std::string(half, ' ') + _headers[j][i] << std::string(_cell_padding, ' ') << "|"; + } - stream << "\n"; + stream << "\n"; + } // Print out the line below the header stream << std::string(total_width, '-') << "\n"; @@ -276,7 +297,28 @@ class VariadicTable if (data == 0) return 1; - return std::log10(data) + 1; + return std::log10(data) + 2; //+ 1 minus sign + } + +/** + * Try to find the size the column will take up + * + * If the datatype is a float - let's get it's length ( before the decimal point) + */ + template + size_t sizeOfData(const T & data, + typename std::enable_if::value>::type * /*dummy*/ = nullptr) + { + if (data == 0) + return 1; + + auto p = size_t(std::log10(std::abs(data))); + if (p > 0 ) { + p++; + } else { + p=1; + } + return p + 3; // 1 minus sign, 1 for decimal point and 2 standard precision } /** @@ -314,10 +356,17 @@ class VariadicTable sizes[I] = sizeOfData(std::get(t)); // Override for Percent - if (!_column_format.empty()) - if (_column_format[I] == VariadicTableColumnFormat::PERCENT) - sizes[I] = 6; // 100.00 - + if (!_column_format.empty()) { + if (_column_format[I] == VariadicTableColumnFormat::PERCENT){ + sizes[I] = -3 + 1 + sizes[I] + 1 + 2; // // +1 (sign) +x (numbers before decimal point) +1 (decimal point) +2 (numbers after decimal point) + } + else if (_column_format[I] == VariadicTableColumnFormat::SCIENTIFIC){ + sizes[I] = 1 + 1 + 1 + _precision[I] + 1 + 1 + 3; // +1 (sign) +1 (number before decimal point) +1 (decimal point) +X (numbers after decimal point) +5 (e-123) + } + else if (_column_format[I] == VariadicTableColumnFormat::FIXED){ + sizes[I] = -3 + 1 + sizes[I] + 1 + _precision[I]; // +1 (sign) +x (numbers before decimal point) +1 (decimal point) +X (numbers after decimal point) + } + } // Continue the recursion size_each(std::forward(t), sizes, std::integral_constant()); } @@ -342,8 +391,12 @@ class VariadicTable std::vector column_sizes(_num_columns); // Start with the size of the headers - for (unsigned int i = 0; i < _num_columns; i++) - _column_sizes[i] = _headers[i].size(); + for (unsigned int j = 0; j < (unsigned int) _headers.size(); j++) + { + for (unsigned int i = 0; i < _num_columns; i++) { + _column_sizes[i] = std::max(_column_sizes[i], (unsigned int) _headers[j][i].size()); + } + } // Grab the size of each entry of each row and see if it's bigger for (auto & row : _data) @@ -356,7 +409,7 @@ class VariadicTable } /// The column headers - std::vector _headers; + std::vector > _headers; /// Number of columns in the table unsigned int _num_columns; diff --git a/src/main.C b/src/main.C index 5e5bf3b..5332f9a 100644 --- a/src/main.C +++ b/src/main.C @@ -5,50 +5,48 @@ main() { // Tiny Table { - VariadicTable vt({"Name", "Weight", "Age", "Brother"}, - 10); + VariadicTable vt({"Name", "Weight", "Age", "Brother"},12); - vt.addRow({"Cody", 180.2, 40, "John"}); - vt.addRow({"David", 175.3, 38, "Andrew"}); - vt.addRow({"Robert", 140.3, 27, "Fande"}); + vt.addRow("Cody", 180.2, 40, "John"); + vt.addRow("David", 175.3, 38, "Andrew"); + vt.addRow("Robert", 140.3, 27, "Fande"); vt.print(std::cout); } // More Data { - VariadicTable vt({"Section", "Self", "Children", "Total"}, - 12); + VariadicTable vt({"Section", "Self", "Children", "Total"}); - vt.setColumnFormat({VariadicTableColumnFormat::AUTO, + vt.setColumnFormat( {VariadicTableColumnFormat::AUTO, VariadicTableColumnFormat::SCIENTIFIC, VariadicTableColumnFormat::FIXED, VariadicTableColumnFormat::PERCENT}); vt.setColumnPrecision({1, 3, 3, 2}); - vt.addRow({"Root", 0.004525, 0.051815, 0.05634}); - vt.addRow({" MooseApp::setup", 1e-05, 0.037072, 0.037082}); - vt.addRow({" FileMesh::init", 3e-06, 0.001548, 0.001551}); - vt.addRow({" FileMesh::readMesh", 0.001548, 0, 0.001548}); - vt.addRow({" FileMesh::prepare", 5.1e-05, 0.000192, 0.000243}); - vt.addRow({" FEProblem::init", 6.7e-05, 0.002233, 0.0023}); - vt.addRow({" FEProblem::EquationSystems::Init", 0.002051, 0, 0.002051}); - vt.addRow({" MooseApp::execute", 0, 0.014732, 0.014732}); - vt.addRow({" FEProblem::initialSetup", 0.000376, 0.003268, 0.003644}); - vt.addRow({" FEProblem::projectSolution", 0.000144, 0, 0.000144}); - vt.addRow({" FEProblem::solve", 0.001181, 0.004169, 0.00535}); - vt.addRow({" FEProblem::computeResidualSys", 7e-06, 0.003489, 0.003496}); - vt.addRow({" FEProblem::computeResidualInternal", 1.3e-05, 0.003476, 0.003489}); - vt.addRow({" FEProblem::computeResidualTags", 4.9e-05, 0.003427, 0.003476}); - vt.addRow({" AuxiliarySystem::computeNodalVars", 0.000209, 1e-06, 0.00021}); - vt.addRow({" FEProblem::computeJacobianInternal", 1e-06, 0.000605, 0.000606}); - vt.addRow({" FEProblem::computeJacobianTags", 1e-05, 0.000595, 0.000605}); - vt.addRow({" Console::outputStep", 6e-05, 0, 6e-05}); - vt.addRow({" FEProblem::outputStep", 8.7e-05, 0.005496, 0.005583}); - vt.addRow({" PerfGraphOutput::outputStep", 4.3e-05, 0, 4.3e-05}); - vt.addRow({" Exodus::outputStep", 0.005395, 0, 0.005395}); - vt.addRow({" Console::outputStep", 5.8e-05, 0, 5.8e-05}); + vt.addRow("Root", 0.004525, 0.051815, 0.05634); + vt.addRow(" MooseApp::setup", 1e-05, 0.037072, 0.037082); + vt.addRow(" FileMesh::init", 3e-06, 0.001548, 0.001551); + vt.addRow(" FileMesh::readMesh", 0.001548, 0, 0.001548); + vt.addRow(" FileMesh::prepare", 5.1e-05, 0.000192, 0.000243); + vt.addRow(" FEProblem::init", 6.7e-05, 0.002233, 0.0023); + vt.addRow(" FEProblem::EquationSystems::Init", 0.002051, 0, 0.002051); + vt.addRow(" MooseApp::execute", 0, 0.014732, 0.014732); + vt.addRow(" FEProblem::initialSetup", 0.000376, 0.003268, 0.003644); + vt.addRow(" FEProblem::projectSolution", 0.000144, 0, 0.000144); + vt.addRow(" FEProblem::solve", 0.001181, 0.004169, 0.00535); + vt.addRow(" FEProblem::computeResidualSys", 7e-06, 0.003489, 0.003496); + vt.addRow(" FEProblem::computeResidualInternal", 1.3e-05, 0.003476, 0.003489); + vt.addRow(" FEProblem::computeResidualTags", 4.9e-05, 0.003427, 0.003476); + vt.addRow(" AuxiliarySystem::computeNodalVars", 0.000209, 1e-06, 0.00021); + vt.addRow(" FEProblem::computeJacobianInternal", 1e-06, 0.000605, 0.000606); + vt.addRow(" FEProblem::computeJacobianTags", 1e-05, 0.000595, 0.000605); + vt.addRow(" Console::outputStep", 6e-05, 0, 6e-05); + vt.addRow(" FEProblem::outputStep", 8.7e-05, 0.005496, 0.005583); + vt.addRow(" PerfGraphOutput::outputStep", 4.3e-05, 0, 4.3e-05); + vt.addRow(" Exodus::outputStep", 0.005395, 0, 0.005395); + vt.addRow(" Console::outputStep", 5.8e-05, 0, 5.8e-05); vt.print(std::cout); }