LCOV - code coverage report
Current view: top level - src/utils - FormattedTable.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #33194 (2f6aab) with base 583127 Lines: 309 337 91.7 %
Date: 2026-07-01 13:50:39 Functions: 27 28 96.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #include "FormattedTable.h"
      11             : #include "MooseError.h"
      12             : #include "MooseUtils.h"
      13             : 
      14             : #include "libmesh/exodusII_io.h"
      15             : 
      16             : #include <iomanip>
      17             : #include <iterator>
      18             : 
      19             : const unsigned short FormattedTable::_column_width = 15;
      20             : const unsigned short FormattedTable::_min_pps_width = 40;
      21             : 
      22             : const unsigned short DEFAULT_CSV_PRECISION = 14;
      23             : const std::string DEFAULT_CSV_DELIMITER = ",";
      24             : 
      25             : template <>
      26             : void
      27      232677 : dataStore(std::ostream & stream, FormattedTable & table, void * context)
      28             : {
      29      232677 :   table.fillEmptyValues();
      30      232677 :   storeHelper(stream, table._data, context);
      31      232677 :   storeHelper(stream, table._align_widths, context);
      32      232677 :   storeHelper(stream, table._column_names, context);
      33      232677 :   storeHelper(stream, table._output_row_index, context);
      34      232677 :   storeHelper(stream, table._headers_output, context);
      35      232677 : }
      36             : 
      37             : template <>
      38             : void
      39       58865 : dataLoad(std::istream & stream, FormattedTable & table, void * context)
      40             : {
      41       58865 :   loadHelper(stream, table._data, context);
      42       58865 :   loadHelper(stream, table._align_widths, context);
      43       58865 :   loadHelper(stream, table._column_names, context);
      44       58865 :   loadHelper(stream, table._output_row_index, context);
      45       58865 :   loadHelper(stream, table._headers_output, context);
      46       58865 : }
      47             : 
      48             : template <>
      49             : void
      50     1614598 : dataStore(std::ostream & stream, std::shared_ptr<TableValueBase> & value_base, void * context)
      51             : {
      52     1614598 :   value_base->store(stream, context);
      53     1614598 : }
      54             : 
      55             : template <>
      56             : void
      57       64852 : dataLoad(std::istream & stream, std::shared_ptr<TableValueBase> & value_base, void * context)
      58             : {
      59       64852 :   std::string type;
      60       64852 :   dataLoad(stream, type, context);
      61       64852 :   if (type == typeid(bool).name())
      62           0 :     TableValue<bool>::load(stream, value_base, context);
      63             : 
      64       64852 :   else if (type == typeid(unsigned short int).name())
      65           0 :     TableValue<unsigned short int>::load(stream, value_base, context);
      66             : 
      67       64852 :   else if (type == typeid(unsigned int).name())
      68         620 :     TableValue<unsigned int>::load(stream, value_base, context);
      69             : 
      70       64232 :   else if (type == typeid(unsigned long int).name())
      71          90 :     TableValue<unsigned long int>::load(stream, value_base, context);
      72             : 
      73       64142 :   else if (type == typeid(unsigned long long int).name())
      74           0 :     TableValue<unsigned long long int>::load(stream, value_base, context);
      75             : 
      76       64142 :   else if (type == typeid(short int).name())
      77           0 :     TableValue<short int>::load(stream, value_base, context);
      78             : 
      79       64142 :   else if (type == typeid(int).name())
      80         224 :     TableValue<int>::load(stream, value_base, context);
      81             : 
      82       63918 :   else if (type == typeid(long int).name())
      83           0 :     TableValue<long int>::load(stream, value_base, context);
      84             : 
      85       63918 :   else if (type == typeid(long long int).name())
      86           0 :     TableValue<long long int>::load(stream, value_base, context);
      87             : 
      88       63918 :   else if (type == typeid(float).name())
      89           0 :     TableValue<float>::load(stream, value_base, context);
      90             : 
      91       63918 :   else if (type == typeid(double).name())
      92       63696 :     TableValue<double>::load(stream, value_base, context);
      93             : 
      94         222 :   else if (type == typeid(long double).name())
      95           0 :     TableValue<long double>::load(stream, value_base, context);
      96             : 
      97         222 :   else if (type == typeid(char).name())
      98           0 :     TableValue<char>::load(stream, value_base, context);
      99             : 
     100         222 :   else if (type == typeid(char *).name())
     101           0 :     TableValue<char *>::load(stream, value_base, context);
     102             : 
     103         222 :   else if (type == typeid(std::string).name())
     104         222 :     TableValue<std::string>::load(stream, value_base, context);
     105             : 
     106             :   else
     107           0 :     mooseError("Unsupported table value type ", demangle(type.c_str()));
     108       64852 : }
     109             : 
     110             : void
     111      458962 : FormattedTable::close()
     112             : {
     113      458962 :   if (!_output_file.is_open())
     114      401491 :     return;
     115       57471 :   _output_file.flush();
     116       57471 :   _output_file.close();
     117       57471 :   _output_file_name = "";
     118             : }
     119             : 
     120             : void
     121       57471 : FormattedTable::open(const std::string & file_name)
     122             : {
     123       57471 :   if (_output_file.is_open() && _output_file_name == file_name)
     124           0 :     return;
     125       57471 :   close();
     126       57471 :   _output_file_name = file_name;
     127             : 
     128       57471 :   std::ios_base::openmode open_flags = std::ios::out;
     129       57471 :   if (_append)
     130        2401 :     open_flags |= std::ios::app;
     131             :   else
     132             :   {
     133       55070 :     open_flags |= std::ios::trunc;
     134       55070 :     _output_row_index = 0;
     135       55070 :     _headers_output = false;
     136             :   }
     137             : 
     138       57471 :   _output_file.open(file_name.c_str(), open_flags);
     139       57471 :   if (_output_file.fail())
     140           0 :     mooseError("Unable to open file ", file_name);
     141             : }
     142             : 
     143      349388 : FormattedTable::FormattedTable()
     144      349388 :   : _output_row_index(0),
     145      349388 :     _headers_output(false),
     146      349388 :     _append(false),
     147      349388 :     _output_time(true),
     148      349388 :     _csv_delimiter(DEFAULT_CSV_DELIMITER),
     149      349388 :     _csv_precision(DEFAULT_CSV_PRECISION),
     150      349388 :     _csv_use_scientific_notation(false)
     151             : {
     152      349388 : }
     153             : 
     154        4744 : FormattedTable::FormattedTable(const FormattedTable & o)
     155        4744 :   : _column_names(o._column_names),
     156        9488 :     _output_file_name(""),
     157        4744 :     _output_row_index(o._output_row_index),
     158        4744 :     _headers_output(o._headers_output),
     159        4744 :     _append(o._append),
     160        4744 :     _output_time(o._output_time),
     161        4744 :     _csv_delimiter(o._csv_delimiter),
     162        4744 :     _csv_precision(o._csv_precision),
     163        4744 :     _csv_use_scientific_notation(o._csv_use_scientific_notation),
     164        9488 :     _column_names_unsorted(o._column_names_unsorted)
     165             : {
     166        4744 :   if (_output_file.is_open())
     167           0 :     mooseError("Copying a FormattedTable with an open stream is not supported");
     168             : 
     169        4744 :   for (const auto & it : o._data)
     170           0 :     _data.emplace_back(it.first, it.second);
     171        4744 : }
     172             : 
     173      344020 : FormattedTable::~FormattedTable() { close(); }
     174             : 
     175             : bool
     176     1312661 : FormattedTable::empty() const
     177             : {
     178     1312661 :   return _data.empty();
     179             : }
     180             : 
     181             : void
     182         976 : FormattedTable::append(bool append_existing_file)
     183             : {
     184         976 :   _append = append_existing_file;
     185         976 : }
     186             : 
     187             : void
     188      351703 : FormattedTable::addRow(Real time)
     189             : {
     190      351703 :   _data.emplace_back(time, std::map<std::string, std::shared_ptr<TableValueBase>>());
     191      351703 : }
     192             : 
     193             : Real
     194      304743 : FormattedTable::getLastTime() const
     195             : {
     196             :   mooseAssert(!empty(), "No Data stored in the FormattedTable");
     197      304743 :   return _data.rbegin()->first;
     198             : }
     199             : 
     200             : void
     201       29360 : FormattedTable::printOmittedRow(std::ostream & out,
     202             :                                 std::map<std::string, unsigned short> & col_widths,
     203             :                                 std::vector<std::string>::iterator & col_begin,
     204             :                                 std::vector<std::string>::iterator & col_end) const
     205             : {
     206       29360 :   printNoDataRow(':', ' ', out, col_widths, col_begin, col_end);
     207       29360 : }
     208             : 
     209             : void
     210      383430 : FormattedTable::printRowDivider(std::ostream & out,
     211             :                                 std::map<std::string, unsigned short> & col_widths,
     212             :                                 std::vector<std::string>::iterator & col_begin,
     213             :                                 std::vector<std::string>::iterator & col_end) const
     214             : {
     215      383430 :   printNoDataRow('+', '-', out, col_widths, col_begin, col_end);
     216      383430 : }
     217             : 
     218             : void
     219      412790 : FormattedTable::printNoDataRow(char intersect_char,
     220             :                                char fill_char,
     221             :                                std::ostream & out,
     222             :                                std::map<std::string, unsigned short> & col_widths,
     223             :                                std::vector<std::string>::iterator & col_begin,
     224             :                                std::vector<std::string>::iterator & col_end) const
     225             : {
     226      412790 :   out.fill(fill_char);
     227      412790 :   out << std::right << intersect_char;
     228      412790 :   if (_output_time)
     229      412790 :     out << std::setw(_column_width + 2) << intersect_char;
     230     1179079 :   for (auto header_it = col_begin; header_it != col_end; ++header_it)
     231      766289 :     out << std::setw(col_widths[*header_it] + 2) << intersect_char;
     232      412790 :   out << "\n";
     233             : 
     234             :   // Clear the fill character
     235      412790 :   out.fill(' ');
     236      412790 : }
     237             : 
     238             : void
     239           0 : FormattedTable::printTable(const std::string & file_name)
     240             : {
     241           0 :   open(file_name);
     242           0 :   printTable(_output_file);
     243           0 : }
     244             : 
     245             : void
     246          15 : FormattedTable::printTable(std::ostream & out, unsigned int last_n_entries)
     247             : {
     248          45 :   printTable(out, last_n_entries, MooseEnum("ENVIRONMENT=-1", "ENVIRONMENT"));
     249          15 : }
     250             : 
     251             : void
     252      124465 : FormattedTable::printTable(std::ostream & out,
     253             :                            unsigned int last_n_entries,
     254             :                            const MooseEnum & suggested_term_width)
     255             : {
     256             :   unsigned short term_width;
     257             : 
     258      124465 :   if (suggested_term_width == "ENVIRONMENT")
     259      124277 :     term_width = MooseUtils::getTermWidth(true);
     260         188 :   else if (suggested_term_width == "AUTO")
     261           0 :     term_width = MooseUtils::getTermWidth(false);
     262             :   else
     263         192 :     term_width = MooseUtils::stringToInteger(suggested_term_width);
     264             : 
     265      124458 :   if (term_width < _min_pps_width)
     266           0 :     term_width = _min_pps_width;
     267             : 
     268      124458 :   std::vector<std::string>::iterator col_it = _column_names.begin();
     269      124458 :   std::vector<std::string>::iterator col_end = _column_names.end();
     270             : 
     271      124458 :   std::vector<std::string>::iterator curr_begin = col_it;
     272      124458 :   std::vector<std::string>::iterator curr_end;
     273      252268 :   while (col_it != col_end)
     274             :   {
     275      127810 :     std::map<std::string, unsigned short> col_widths;
     276      127810 :     unsigned int curr_width = _column_width + 4;
     277      127810 :     unsigned int cols_in_group = 0;
     278      374986 :     while (curr_width < term_width && col_it != col_end)
     279             :     {
     280      247176 :       curr_end = col_it;
     281      247176 :       col_widths[*col_it] = col_it->length() > _column_width ? col_it->length() + 1 : _column_width;
     282             : 
     283      247176 :       curr_width += col_widths[*col_it] + 3;
     284      247176 :       ++col_it;
     285      247176 :       ++cols_in_group;
     286             :     }
     287      127810 :     if (col_it != col_end && cols_in_group >= 2)
     288             :     {
     289             :       // curr_width -= col_widths[*curr_end];
     290        3352 :       col_widths.erase(*curr_end);
     291        3352 :       col_it = curr_end;
     292             :     }
     293             :     else
     294      124458 :       curr_end = col_it;
     295             : 
     296      127810 :     printTablePiece(out, last_n_entries, col_widths, curr_begin, curr_end);
     297      127810 :     curr_begin = curr_end;
     298      127810 :   }
     299      124458 : }
     300             : 
     301             : void
     302      127810 : FormattedTable::printTablePiece(std::ostream & out,
     303             :                                 unsigned int last_n_entries,
     304             :                                 std::map<std::string, unsigned short> & col_widths,
     305             :                                 std::vector<std::string>::iterator & col_begin,
     306             :                                 std::vector<std::string>::iterator & col_end)
     307             : {
     308      127810 :   fillEmptyValues(last_n_entries);
     309             :   /**
     310             :    * Print out the header row
     311             :    */
     312      127810 :   printRowDivider(out, col_widths, col_begin, col_end);
     313      127810 :   out << "|";
     314      127810 :   if (_output_time)
     315      127810 :     out << std::setw(_column_width) << std::left << " time" << " |";
     316      371634 :   for (auto header_it = col_begin; header_it != col_end; ++header_it)
     317      243824 :     out << " " << std::setw(col_widths[*header_it]) << *header_it << "|";
     318      127810 :   out << "\n";
     319      127810 :   printRowDivider(out, col_widths, col_begin, col_end);
     320             : 
     321      127810 :   auto data_it = _data.begin();
     322      127810 :   if (last_n_entries)
     323             :   {
     324      127806 :     if (_data.size() > last_n_entries)
     325             :     {
     326             :       // Print a blank row to indicate that values have been ommited
     327       29360 :       printOmittedRow(out, col_widths, col_begin, col_end);
     328             : 
     329             :       // Jump to the right place in the vector
     330       29360 :       data_it += _data.size() - last_n_entries;
     331             :     }
     332             :   }
     333             :   // Now print the remaining data rows
     334      971929 :   for (; data_it != _data.end(); ++data_it)
     335             :   {
     336      844119 :     out << "|";
     337      844119 :     if (_output_time)
     338      844119 :       out << std::right << std::setw(_column_width) << std::scientific << data_it->first << " |";
     339     2212731 :     for (auto header_it = col_begin; header_it != col_end; ++header_it)
     340             :     {
     341     1368612 :       auto & tmp = data_it->second;
     342     1368612 :       out << std::setw(col_widths[*header_it]) << *tmp[*header_it] << " |";
     343             :     }
     344      844119 :     out << "\n";
     345             :   }
     346             : 
     347      127810 :   printRowDivider(out, col_widths, col_begin, col_end);
     348      127810 : }
     349             : 
     350             : void
     351       57471 : FormattedTable::printCSV(const std::string & file_name, int interval, bool align)
     352             : {
     353       57471 :   fillEmptyValues();
     354             : 
     355       57471 :   open(file_name);
     356             : 
     357       57471 :   if (_output_row_index == 0)
     358             :   {
     359             :     /**
     360             :      * When the alignment option is set to true, the widths of the columns needs to be computed
     361             :      * based on longest of the column name of the data supplied. This is done here by creating a
     362             :      * map
     363             :      * of the widths for each of the columns, including time
     364             :      */
     365       55127 :     if (align)
     366             :     {
     367             :       // Set the initial width to the names of the columns
     368          60 :       _align_widths["time"] = 4;
     369             : 
     370         240 :       for (const auto & col_name : _column_names)
     371         210 :         _align_widths[col_name] = col_name.size();
     372             : 
     373             :       // Loop through the various times
     374         103 :       for (const auto & it : _data)
     375             :       {
     376             :         // Update the time _align_width
     377             :         {
     378          73 :           std::ostringstream oss;
     379          73 :           if (_csv_use_scientific_notation)
     380           0 :             oss << std::scientific;
     381          73 :           oss << std::setprecision(_csv_precision) << it.first;
     382          73 :           unsigned int w = oss.str().size();
     383         292 :           _align_widths["time"] = std::max(_align_widths["time"], w);
     384          73 :         }
     385             : 
     386             :         // Loop through the data for the current time and update the _align_widths
     387         584 :         for (const auto & jt : it.second)
     388             :         {
     389         511 :           std::ostringstream oss;
     390         511 :           if (_csv_use_scientific_notation)
     391           0 :             oss << std::scientific;
     392         511 :           oss << std::setprecision(_csv_precision) << *jt.second;
     393         511 :           unsigned int w = oss.str().size();
     394         511 :           _align_widths[jt.first] = std::max(_align_widths[jt.first], w);
     395         511 :         }
     396             :       }
     397             :     }
     398             : 
     399             :     // Output Header
     400       55127 :     if (!_headers_output)
     401             :     {
     402       55127 :       if (_output_time)
     403             :       {
     404       47912 :         if (align)
     405          90 :           _output_file << std::setw(_align_widths["time"]) << "time";
     406             :         else
     407       47882 :           _output_file << "time";
     408       47912 :         _headers_output = true;
     409             :       }
     410             : 
     411      199813 :       for (const auto & col_name : _column_names)
     412             :       {
     413      144686 :         if (_headers_output)
     414      137471 :           _output_file << _csv_delimiter;
     415             : 
     416      144686 :         if (align)
     417         210 :           _output_file << std::right << std::setw(_align_widths[col_name]) << col_name;
     418             :         else
     419      144476 :           _output_file << col_name;
     420      144686 :         _headers_output = true;
     421             :       }
     422       55127 :       _output_file << "\n";
     423             :     }
     424             :   }
     425             : 
     426     3589220 :   for (; _output_row_index < _data.size(); ++_output_row_index)
     427             :   {
     428     3531749 :     if (_output_row_index % interval == 0)
     429     3531749 :       printRow(_data[_output_row_index], align);
     430             :   }
     431             : 
     432       57471 :   close();
     433       57471 : }
     434             : 
     435             : void
     436     3531749 : FormattedTable::printRow(
     437             :     std::pair<Real, std::map<std::string, std::shared_ptr<TableValueBase>>> & row_data, bool align)
     438             : {
     439     3531749 :   bool first = true;
     440             : 
     441     3531749 :   if (_csv_use_scientific_notation)
     442           8 :     _output_file << std::scientific;
     443             :   else
     444     3531741 :     _output_file << std::defaultfloat;
     445             : 
     446     3531749 :   if (_output_time)
     447             :   {
     448     3342807 :     if (align)
     449          75 :       _output_file << std::setprecision(_csv_precision) << std::right
     450         225 :                    << std::setw(_align_widths["time"]) << row_data.first;
     451             :     else
     452     3342732 :       _output_file << std::setprecision(_csv_precision) << row_data.first;
     453     3342807 :     first = false;
     454             :   }
     455             : 
     456    10996612 :   for (const auto & col_name : _column_names)
     457             :   {
     458     7464863 :     std::map<std::string, std::shared_ptr<TableValueBase>> & tmp = row_data.second;
     459             : 
     460     7464863 :     if (!first)
     461     7275921 :       _output_file << _csv_delimiter;
     462             :     else
     463      188942 :       first = false;
     464             : 
     465     7464863 :     if (align)
     466         525 :       _output_file << std::setprecision(_csv_precision) << std::right
     467         525 :                    << std::setw(_align_widths[col_name]) << *tmp[col_name];
     468             :     else
     469     7464338 :       _output_file << std::setprecision(_csv_precision) << *tmp[col_name];
     470             :   }
     471     3531749 :   _output_file << "\n";
     472     3531749 : }
     473             : 
     474             : // const strings that the gnuplot generator needs
     475             : namespace gnuplot
     476             : {
     477             : const std::string before_terminal = "set terminal ";
     478             : const std::string before_ext = "\nset output 'all";
     479             : const std::string after_ext =
     480             :     "'\nset title 'All Postprocessors'\nset xlabel 'time'\nset ylabel 'values'\nplot";
     481             : }
     482             : 
     483             : void
     484          66 : FormattedTable::makeGnuplot(const std::string & base_file, const std::string & format)
     485             : {
     486          66 :   fillEmptyValues();
     487             : 
     488             :   // TODO: run this once at end of simulation, right now it runs every iteration
     489             :   // TODO: do I need to be more careful escaping column names?
     490             :   // Note: open and close the files each time, having open files may mess with gnuplot
     491             : 
     492             :   // supported filetypes: ps, png
     493          66 :   std::string extension, terminal;
     494          66 :   if (format == "png")
     495             :   {
     496          22 :     extension = ".png";
     497          22 :     terminal = "png";
     498             :   }
     499             : 
     500          44 :   else if (format == "ps")
     501             :   {
     502          22 :     extension = ".ps";
     503          22 :     terminal = "postscript";
     504             :   }
     505             : 
     506          22 :   else if (format == "gif")
     507             :   {
     508          22 :     extension = ".gif";
     509          22 :     terminal = "gif";
     510             :   }
     511             : 
     512             :   else
     513           0 :     mooseError("gnuplot format \"" + format + "\" is not supported.");
     514             : 
     515             :   // Write the data to disk
     516          66 :   std::string dat_name = base_file + ".dat";
     517          66 :   std::ofstream datfile;
     518          66 :   datfile.open(dat_name.c_str(), std::ios::trunc | std::ios::out);
     519          66 :   if (datfile.fail())
     520           0 :     mooseError("Unable to open file ", dat_name);
     521             : 
     522          66 :   datfile << "# time";
     523         132 :   for (const auto & col_name : _column_names)
     524          66 :     datfile << '\t' << col_name;
     525          66 :   datfile << '\n';
     526             : 
     527         165 :   for (auto & data_it : _data)
     528             :   {
     529          99 :     datfile << data_it.first;
     530         198 :     for (const auto & col_name : _column_names)
     531             :     {
     532          99 :       auto & tmp = data_it.second;
     533          99 :       datfile << '\t' << *tmp[col_name];
     534             :     }
     535          99 :     datfile << '\n';
     536             :   }
     537          66 :   datfile.flush();
     538          66 :   datfile.close();
     539             : 
     540             :   // Write the gnuplot script
     541          66 :   std::string gp_name = base_file + ".gp";
     542          66 :   std::ofstream gpfile;
     543          66 :   gpfile.open(gp_name.c_str(), std::ios::trunc | std::ios::out);
     544          66 :   if (gpfile.fail())
     545           0 :     mooseError("Unable to open file ", gp_name);
     546             : 
     547             :   gpfile << gnuplot::before_terminal << terminal << gnuplot::before_ext << extension
     548          66 :          << gnuplot::after_ext;
     549             : 
     550             :   // plot all postprocessors in one plot
     551          66 :   int column = 2;
     552         132 :   for (const auto & col_name : _column_names)
     553             :   {
     554          66 :     gpfile << " '" << dat_name << "' using 1:" << column << " title '" << col_name
     555          66 :            << "' with linespoints";
     556          66 :     column++;
     557          66 :     if (column - 2 < static_cast<int>(_column_names.size()))
     558           0 :       gpfile << ", \\\n";
     559             :   }
     560          66 :   gpfile << "\n\n";
     561             : 
     562             :   // plot the postprocessors individually
     563          66 :   column = 2;
     564         132 :   for (const auto & col_name : _column_names)
     565             :   {
     566          66 :     gpfile << "set output '" << col_name << extension << "'\n";
     567          66 :     gpfile << "set ylabel '" << col_name << "'\n";
     568          66 :     gpfile << "plot '" << dat_name << "' using 1:" << column << " title '" << col_name
     569          66 :            << "' with linespoints\n\n";
     570          66 :     column++;
     571             :   }
     572             : 
     573          66 :   gpfile.flush();
     574          66 :   gpfile.close();
     575          66 : }
     576             : 
     577             : void
     578       21965 : FormattedTable::clear()
     579             : {
     580       21965 :   _data.clear();
     581       21965 :   _output_file.close();
     582       21965 :   _output_row_index = 0;
     583       21965 : }
     584             : 
     585             : void
     586      418024 : FormattedTable::fillEmptyValues(unsigned int last_n_entries)
     587             : {
     588      418024 :   auto begin = _data.begin();
     589      418024 :   auto end = _data.end();
     590      418024 :   if (last_n_entries && (last_n_entries < _data.size()))
     591       29360 :     begin = end - last_n_entries;
     592             : 
     593     6349445 :   for (auto it = begin; it != end; ++it)
     594             :   {
     595     5931421 :     auto & datamap = it->second;
     596     5931421 :     if (datamap.size() != _column_names.size())
     597             :     {
     598        1941 :       for (const auto & col_name : _column_names)
     599        1450 :         if (!datamap[col_name])
     600         907 :           datamap[col_name] =
     601        1814 :               std::dynamic_pointer_cast<TableValueBase>(std::make_shared<TableValue<char>>('0'));
     602             :     }
     603             :     else
     604             :     {
     605    17286237 :       for (auto & [key, val] : datamap)
     606    11355307 :         if (!val)
     607           0 :           val = std::dynamic_pointer_cast<TableValueBase>(std::make_shared<TableValue<char>>('0'));
     608             :     }
     609             :   }
     610      418024 : }
     611             : 
     612             : MooseEnum
     613      133553 : FormattedTable::getWidthModes()
     614             : {
     615      534212 :   return MooseEnum("ENVIRONMENT=-1 AUTO=0 80=80 120=120 160=160", "ENVIRONMENT", true);
     616             : }
     617             : 
     618             : void
     619      124454 : FormattedTable::sortColumns()
     620             : {
     621      124454 :   if (_column_names_unsorted)
     622             :   {
     623       22437 :     std::sort(_column_names.begin(), _column_names.end());
     624       22437 :     _column_names_unsorted = false;
     625             :   }
     626      124454 : }
     627             : 
     628             : std::ostream &
     629     8834085 : operator<<(std::ostream & os, const TableValueBase & value)
     630             : {
     631     8834085 :   value.print(os);
     632     8834085 :   return os;
     633             : }

Generated by: LCOV version 1.14