LCOV - code coverage report
Current view: top level - src/utils - FormattedTable.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 303 328 92.4 %
Date: 2025-07-17 01:28:37 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      209198 : dataStore(std::ostream & stream, FormattedTable & table, void * context)
      28             : {
      29      209198 :   table.fillEmptyValues();
      30      209198 :   storeHelper(stream, table._data, context);
      31      209198 :   storeHelper(stream, table._align_widths, context);
      32      209198 :   storeHelper(stream, table._column_names, context);
      33      209198 :   storeHelper(stream, table._output_row_index, context);
      34      209198 :   storeHelper(stream, table._headers_output, context);
      35      209198 : }
      36             : 
      37             : template <>
      38             : void
      39       57941 : dataLoad(std::istream & stream, FormattedTable & table, void * context)
      40             : {
      41       57941 :   loadHelper(stream, table._data, context);
      42       57941 :   loadHelper(stream, table._align_widths, context);
      43       57941 :   loadHelper(stream, table._column_names, context);
      44       57941 :   loadHelper(stream, table._output_row_index, context);
      45       57941 :   loadHelper(stream, table._headers_output, context);
      46       57941 : }
      47             : 
      48             : template <>
      49             : void
      50     1573015 : dataStore(std::ostream & stream, std::shared_ptr<TableValueBase> & value_base, void * context)
      51             : {
      52     1573015 :   value_base->store(stream, context);
      53     1573015 : }
      54             : 
      55             : template <>
      56             : void
      57       64470 : dataLoad(std::istream & stream, std::shared_ptr<TableValueBase> & value_base, void * context)
      58             : {
      59       64470 :   std::string type;
      60       64470 :   dataLoad(stream, type, context);
      61       64470 :   if (type == typeid(bool).name())
      62           0 :     TableValue<bool>::load(stream, value_base, context);
      63             : 
      64       64470 :   else if (type == typeid(unsigned short int).name())
      65           0 :     TableValue<unsigned short int>::load(stream, value_base, context);
      66             : 
      67       64470 :   else if (type == typeid(unsigned int).name())
      68         564 :     TableValue<unsigned int>::load(stream, value_base, context);
      69             : 
      70       63906 :   else if (type == typeid(unsigned long int).name())
      71          56 :     TableValue<unsigned long int>::load(stream, value_base, context);
      72             : 
      73       63850 :   else if (type == typeid(unsigned long long int).name())
      74           0 :     TableValue<unsigned long long int>::load(stream, value_base, context);
      75             : 
      76       63850 :   else if (type == typeid(short int).name())
      77           0 :     TableValue<short int>::load(stream, value_base, context);
      78             : 
      79       63850 :   else if (type == typeid(int).name())
      80         370 :     TableValue<int>::load(stream, value_base, context);
      81             : 
      82       63480 :   else if (type == typeid(long int).name())
      83           0 :     TableValue<long int>::load(stream, value_base, context);
      84             : 
      85       63480 :   else if (type == typeid(long long int).name())
      86           0 :     TableValue<long long int>::load(stream, value_base, context);
      87             : 
      88       63480 :   else if (type == typeid(float).name())
      89           0 :     TableValue<float>::load(stream, value_base, context);
      90             : 
      91       63480 :   else if (type == typeid(double).name())
      92       63116 :     TableValue<double>::load(stream, value_base, context);
      93             : 
      94         364 :   else if (type == typeid(long double).name())
      95           0 :     TableValue<long double>::load(stream, value_base, context);
      96             : 
      97         364 :   else if (type == typeid(char).name())
      98           0 :     TableValue<char>::load(stream, value_base, context);
      99             : 
     100         364 :   else if (type == typeid(char *).name())
     101           0 :     TableValue<char *>::load(stream, value_base, context);
     102             : 
     103         364 :   else if (type == typeid(std::string).name())
     104         364 :     TableValue<std::string>::load(stream, value_base, context);
     105             : 
     106             :   else
     107           0 :     mooseError("Unsupported table value type ", demangle(type.c_str()));
     108       64470 : }
     109             : 
     110             : void
     111      325649 : FormattedTable::close()
     112             : {
     113      325649 :   if (!_output_file.is_open())
     114      311264 :     return;
     115       14385 :   _output_file.flush();
     116       14385 :   _output_file.close();
     117       14385 :   _output_file_name = "";
     118             : }
     119             : 
     120             : void
     121       55261 : FormattedTable::open(const std::string & file_name)
     122             : {
     123       55261 :   if (_output_file.is_open() && _output_file_name == file_name)
     124       40616 :     return;
     125       14645 :   close();
     126       14645 :   _output_file_name = file_name;
     127             : 
     128       14645 :   std::ios_base::openmode open_flags = std::ios::out;
     129       14645 :   if (_append)
     130         370 :     open_flags |= std::ios::app;
     131             :   else
     132             :   {
     133       14275 :     open_flags |= std::ios::trunc;
     134       14275 :     _output_row_index = 0;
     135       14275 :     _headers_output = false;
     136             :   }
     137             : 
     138       14645 :   _output_file.open(file_name.c_str(), open_flags);
     139       14645 :   if (_output_file.fail())
     140           0 :     mooseError("Unable to open file ", file_name);
     141             : }
     142             : 
     143      321588 : FormattedTable::FormattedTable()
     144      321588 :   : _output_row_index(0),
     145      321588 :     _headers_output(false),
     146      321588 :     _append(false),
     147      321588 :     _output_time(true),
     148      321588 :     _csv_delimiter(DEFAULT_CSV_DELIMITER),
     149      321588 :     _csv_precision(DEFAULT_CSV_PRECISION)
     150             : {
     151      321588 : }
     152             : 
     153        3591 : FormattedTable::FormattedTable(const FormattedTable & o)
     154        3591 :   : _column_names(o._column_names),
     155        3591 :     _output_file_name(""),
     156        3591 :     _output_row_index(o._output_row_index),
     157        3591 :     _headers_output(o._headers_output),
     158        3591 :     _append(o._append),
     159        3591 :     _output_time(o._output_time),
     160        3591 :     _csv_delimiter(o._csv_delimiter),
     161        3591 :     _csv_precision(o._csv_precision),
     162        7182 :     _column_names_unsorted(o._column_names_unsorted)
     163             : {
     164        3591 :   if (_output_file.is_open())
     165           0 :     mooseError("Copying a FormattedTable with an open stream is not supported");
     166             : 
     167        3591 :   for (const auto & it : o._data)
     168           0 :     _data.emplace_back(it.first, it.second);
     169        3591 : }
     170             : 
     171      311004 : FormattedTable::~FormattedTable() { close(); }
     172             : 
     173             : bool
     174     1269024 : FormattedTable::empty() const
     175             : {
     176     1269024 :   return _data.empty();
     177             : }
     178             : 
     179             : void
     180         832 : FormattedTable::append(bool append_existing_file)
     181             : {
     182         832 :   _append = append_existing_file;
     183         832 : }
     184             : 
     185             : void
     186      336051 : FormattedTable::addRow(Real time)
     187             : {
     188      336051 :   _data.emplace_back(time, std::map<std::string, std::shared_ptr<TableValueBase>>());
     189      336051 : }
     190             : 
     191             : Real
     192      294039 : FormattedTable::getLastTime()
     193             : {
     194             :   mooseAssert(!empty(), "No Data stored in the FormattedTable");
     195      294039 :   return _data.rbegin()->first;
     196             : }
     197             : 
     198             : void
     199       32416 : FormattedTable::printOmittedRow(std::ostream & out,
     200             :                                 std::map<std::string, unsigned short> & col_widths,
     201             :                                 std::vector<std::string>::iterator & col_begin,
     202             :                                 std::vector<std::string>::iterator & col_end) const
     203             : {
     204       32416 :   printNoDataRow(':', ' ', out, col_widths, col_begin, col_end);
     205       32416 : }
     206             : 
     207             : void
     208      379608 : FormattedTable::printRowDivider(std::ostream & out,
     209             :                                 std::map<std::string, unsigned short> & col_widths,
     210             :                                 std::vector<std::string>::iterator & col_begin,
     211             :                                 std::vector<std::string>::iterator & col_end) const
     212             : {
     213      379608 :   printNoDataRow('+', '-', out, col_widths, col_begin, col_end);
     214      379608 : }
     215             : 
     216             : void
     217      412024 : FormattedTable::printNoDataRow(char intersect_char,
     218             :                                char fill_char,
     219             :                                std::ostream & out,
     220             :                                std::map<std::string, unsigned short> & col_widths,
     221             :                                std::vector<std::string>::iterator & col_begin,
     222             :                                std::vector<std::string>::iterator & col_end) const
     223             : {
     224      412024 :   out.fill(fill_char);
     225      412024 :   out << std::right << intersect_char;
     226      412024 :   if (_output_time)
     227      412024 :     out << std::setw(_column_width + 2) << intersect_char;
     228     1175983 :   for (auto header_it = col_begin; header_it != col_end; ++header_it)
     229      763959 :     out << std::setw(col_widths[*header_it] + 2) << intersect_char;
     230      412024 :   out << "\n";
     231             : 
     232             :   // Clear the fill character
     233      412024 :   out.fill(' ');
     234      412024 : }
     235             : 
     236             : void
     237           0 : FormattedTable::printTable(const std::string & file_name)
     238             : {
     239           0 :   open(file_name);
     240           0 :   printTable(_output_file);
     241           0 : }
     242             : 
     243             : void
     244           4 : FormattedTable::printTable(std::ostream & out, unsigned int last_n_entries)
     245             : {
     246           4 :   printTable(out, last_n_entries, MooseEnum("ENVIRONMENT=-1", "ENVIRONMENT"));
     247           4 : }
     248             : 
     249             : void
     250      122193 : FormattedTable::printTable(std::ostream & out,
     251             :                            unsigned int last_n_entries,
     252             :                            const MooseEnum & suggested_term_width)
     253             : {
     254             :   unsigned short term_width;
     255             : 
     256      122193 :   if (suggested_term_width == "ENVIRONMENT")
     257      121805 :     term_width = MooseUtils::getTermWidth(true);
     258         388 :   else if (suggested_term_width == "AUTO")
     259           0 :     term_width = MooseUtils::getTermWidth(false);
     260             :   else
     261         390 :     term_width = MooseUtils::stringToInteger(suggested_term_width);
     262             : 
     263      122187 :   if (term_width < _min_pps_width)
     264           0 :     term_width = _min_pps_width;
     265             : 
     266      122187 :   std::vector<std::string>::iterator col_it = _column_names.begin();
     267      122187 :   std::vector<std::string>::iterator col_end = _column_names.end();
     268             : 
     269      122187 :   std::vector<std::string>::iterator curr_begin = col_it;
     270      122187 :   std::vector<std::string>::iterator curr_end;
     271      248723 :   while (col_it != col_end)
     272             :   {
     273      126536 :     std::map<std::string, unsigned short> col_widths;
     274      126536 :     unsigned int curr_width = _column_width + 4;
     275      126536 :     unsigned int cols_in_group = 0;
     276      372845 :     while (curr_width < term_width && col_it != col_end)
     277             :     {
     278      246309 :       curr_end = col_it;
     279      246309 :       col_widths[*col_it] = col_it->length() > _column_width ? col_it->length() + 1 : _column_width;
     280             : 
     281      246309 :       curr_width += col_widths[*col_it] + 3;
     282      246309 :       ++col_it;
     283      246309 :       ++cols_in_group;
     284             :     }
     285      126536 :     if (col_it != col_end && cols_in_group >= 2)
     286             :     {
     287             :       // curr_width -= col_widths[*curr_end];
     288        4349 :       col_widths.erase(*curr_end);
     289        4349 :       col_it = curr_end;
     290             :     }
     291             :     else
     292      122187 :       curr_end = col_it;
     293             : 
     294      126536 :     printTablePiece(out, last_n_entries, col_widths, curr_begin, curr_end);
     295      126536 :     curr_begin = curr_end;
     296      126536 :   }
     297      122187 : }
     298             : 
     299             : void
     300      126536 : FormattedTable::printTablePiece(std::ostream & out,
     301             :                                 unsigned int last_n_entries,
     302             :                                 std::map<std::string, unsigned short> & col_widths,
     303             :                                 std::vector<std::string>::iterator & col_begin,
     304             :                                 std::vector<std::string>::iterator & col_end)
     305             : {
     306      126536 :   fillEmptyValues(last_n_entries);
     307             :   /**
     308             :    * Print out the header row
     309             :    */
     310      126536 :   printRowDivider(out, col_widths, col_begin, col_end);
     311      126536 :   out << "|";
     312      126536 :   if (_output_time)
     313      126536 :     out << std::setw(_column_width) << std::left << " time" << " |";
     314      368496 :   for (auto header_it = col_begin; header_it != col_end; ++header_it)
     315      241960 :     out << " " << std::setw(col_widths[*header_it]) << *header_it << "|";
     316      126536 :   out << "\n";
     317      126536 :   printRowDivider(out, col_widths, col_begin, col_end);
     318             : 
     319      126536 :   auto data_it = _data.begin();
     320      126536 :   if (last_n_entries)
     321             :   {
     322      126534 :     if (_data.size() > last_n_entries)
     323             :     {
     324             :       // Print a blank row to indicate that values have been ommited
     325       32416 :       printOmittedRow(out, col_widths, col_begin, col_end);
     326             : 
     327             :       // Jump to the right place in the vector
     328       32416 :       data_it += _data.size() - last_n_entries;
     329             :     }
     330             :   }
     331             :   // Now print the remaining data rows
     332      992480 :   for (; data_it != _data.end(); ++data_it)
     333             :   {
     334      865944 :     out << "|";
     335      865944 :     if (_output_time)
     336      865944 :       out << std::right << std::setw(_column_width) << std::scientific << data_it->first << " |";
     337     2247348 :     for (auto header_it = col_begin; header_it != col_end; ++header_it)
     338             :     {
     339     1381404 :       auto & tmp = data_it->second;
     340     1381404 :       out << std::setw(col_widths[*header_it]) << *tmp[*header_it] << " |";
     341             :     }
     342      865944 :     out << "\n";
     343             :   }
     344             : 
     345      126536 :   printRowDivider(out, col_widths, col_begin, col_end);
     346      126536 : }
     347             : 
     348             : void
     349       55261 : FormattedTable::printCSV(const std::string & file_name, int interval, bool align)
     350             : {
     351       55261 :   fillEmptyValues();
     352             : 
     353       55261 :   open(file_name);
     354             : 
     355       55261 :   if (_output_row_index == 0)
     356             :   {
     357             :     /**
     358             :      * When the alignment option is set to true, the widths of the columns needs to be computed
     359             :      * based on longest of the column name of the data supplied. This is done here by creating a
     360             :      * map
     361             :      * of the widths for each of the columns, including time
     362             :      */
     363       14484 :     if (align)
     364             :     {
     365             :       // Set the initial width to the names of the columns
     366           8 :       _align_widths["time"] = 4;
     367             : 
     368          64 :       for (const auto & col_name : _column_names)
     369          56 :         _align_widths[col_name] = col_name.size();
     370             : 
     371             :       // Loop through the various times
     372          16 :       for (const auto & it : _data)
     373             :       {
     374             :         // Update the time _align_width
     375             :         {
     376           8 :           std::ostringstream oss;
     377           8 :           oss << std::setprecision(_csv_precision) << it.first;
     378           8 :           unsigned int w = oss.str().size();
     379           8 :           _align_widths["time"] = std::max(_align_widths["time"], w);
     380           8 :         }
     381             : 
     382             :         // Loop through the data for the current time and update the _align_widths
     383          64 :         for (const auto & jt : it.second)
     384             :         {
     385          56 :           std::ostringstream oss;
     386          56 :           oss << std::setprecision(_csv_precision) << *jt.second;
     387          56 :           unsigned int w = oss.str().size();
     388          56 :           _align_widths[jt.first] = std::max(_align_widths[jt.first], w);
     389          56 :         }
     390             :       }
     391             :     }
     392             : 
     393             :     // Output Header
     394       14484 :     if (!_headers_output)
     395             :     {
     396       14468 :       if (_output_time)
     397             :       {
     398        8726 :         if (align)
     399           8 :           _output_file << std::setw(_align_widths["time"]) << "time";
     400             :         else
     401        8718 :           _output_file << "time";
     402        8726 :         _headers_output = true;
     403             :       }
     404             : 
     405       62056 :       for (const auto & col_name : _column_names)
     406             :       {
     407       47588 :         if (_headers_output)
     408       41846 :           _output_file << _csv_delimiter;
     409             : 
     410       47588 :         if (align)
     411          56 :           _output_file << std::right << std::setw(_align_widths[col_name]) << col_name;
     412             :         else
     413       47532 :           _output_file << col_name;
     414       47588 :         _headers_output = true;
     415             :       }
     416       14468 :       _output_file << "\n";
     417             :     }
     418             :   }
     419             : 
     420      266203 :   for (; _output_row_index < _data.size(); ++_output_row_index)
     421             :   {
     422      210942 :     if (_output_row_index % interval == 0)
     423      210942 :       printRow(_data[_output_row_index], align);
     424             :   }
     425             : 
     426       55261 :   _output_file.flush();
     427       55261 : }
     428             : 
     429             : void
     430      210942 : FormattedTable::printRow(
     431             :     std::pair<Real, std::map<std::string, std::shared_ptr<TableValueBase>>> & row_data, bool align)
     432             : {
     433      210942 :   bool first = true;
     434             : 
     435      210942 :   if (_output_time)
     436             :   {
     437       49090 :     if (align)
     438          32 :       _output_file << std::setprecision(_csv_precision) << std::right
     439          32 :                    << std::setw(_align_widths["time"]) << row_data.first;
     440             :     else
     441       49058 :       _output_file << std::setprecision(_csv_precision) << row_data.first;
     442       49090 :     first = false;
     443             :   }
     444             : 
     445     1126365 :   for (const auto & col_name : _column_names)
     446             :   {
     447      915423 :     std::map<std::string, std::shared_ptr<TableValueBase>> & tmp = row_data.second;
     448             : 
     449      915423 :     if (!first)
     450      753571 :       _output_file << _csv_delimiter;
     451             :     else
     452      161852 :       first = false;
     453             : 
     454      915423 :     if (align)
     455         224 :       _output_file << std::setprecision(_csv_precision) << std::right
     456         224 :                    << std::setw(_align_widths[col_name]) << *tmp[col_name];
     457             :     else
     458      915199 :       _output_file << std::setprecision(_csv_precision) << *tmp[col_name];
     459             :   }
     460      210942 :   _output_file << "\n";
     461      210942 : }
     462             : 
     463             : // const strings that the gnuplot generator needs
     464             : namespace gnuplot
     465             : {
     466             : const std::string before_terminal = "set terminal ";
     467             : const std::string before_ext = "\nset output 'all";
     468             : const std::string after_ext =
     469             :     "'\nset title 'All Postprocessors'\nset xlabel 'time'\nset ylabel 'values'\nplot";
     470             : }
     471             : 
     472             : void
     473          66 : FormattedTable::makeGnuplot(const std::string & base_file, const std::string & format)
     474             : {
     475          66 :   fillEmptyValues();
     476             : 
     477             :   // TODO: run this once at end of simulation, right now it runs every iteration
     478             :   // TODO: do I need to be more careful escaping column names?
     479             :   // Note: open and close the files each time, having open files may mess with gnuplot
     480             : 
     481             :   // supported filetypes: ps, png
     482          66 :   std::string extension, terminal;
     483          66 :   if (format == "png")
     484             :   {
     485          22 :     extension = ".png";
     486          22 :     terminal = "png";
     487             :   }
     488             : 
     489          44 :   else if (format == "ps")
     490             :   {
     491          22 :     extension = ".ps";
     492          22 :     terminal = "postscript";
     493             :   }
     494             : 
     495          22 :   else if (format == "gif")
     496             :   {
     497          22 :     extension = ".gif";
     498          22 :     terminal = "gif";
     499             :   }
     500             : 
     501             :   else
     502           0 :     mooseError("gnuplot format \"" + format + "\" is not supported.");
     503             : 
     504             :   // Write the data to disk
     505          66 :   std::string dat_name = base_file + ".dat";
     506          66 :   std::ofstream datfile;
     507          66 :   datfile.open(dat_name.c_str(), std::ios::trunc | std::ios::out);
     508          66 :   if (datfile.fail())
     509           0 :     mooseError("Unable to open file ", dat_name);
     510             : 
     511          66 :   datfile << "# time";
     512         132 :   for (const auto & col_name : _column_names)
     513          66 :     datfile << '\t' << col_name;
     514          66 :   datfile << '\n';
     515             : 
     516         165 :   for (auto & data_it : _data)
     517             :   {
     518          99 :     datfile << data_it.first;
     519         198 :     for (const auto & col_name : _column_names)
     520             :     {
     521          99 :       auto & tmp = data_it.second;
     522          99 :       datfile << '\t' << *tmp[col_name];
     523             :     }
     524          99 :     datfile << '\n';
     525             :   }
     526          66 :   datfile.flush();
     527          66 :   datfile.close();
     528             : 
     529             :   // Write the gnuplot script
     530          66 :   std::string gp_name = base_file + ".gp";
     531          66 :   std::ofstream gpfile;
     532          66 :   gpfile.open(gp_name.c_str(), std::ios::trunc | std::ios::out);
     533          66 :   if (gpfile.fail())
     534           0 :     mooseError("Unable to open file ", gp_name);
     535             : 
     536             :   gpfile << gnuplot::before_terminal << terminal << gnuplot::before_ext << extension
     537          66 :          << gnuplot::after_ext;
     538             : 
     539             :   // plot all postprocessors in one plot
     540          66 :   int column = 2;
     541         132 :   for (const auto & col_name : _column_names)
     542             :   {
     543          66 :     gpfile << " '" << dat_name << "' using 1:" << column << " title '" << col_name
     544          66 :            << "' with linespoints";
     545          66 :     column++;
     546          66 :     if (column - 2 < static_cast<int>(_column_names.size()))
     547           0 :       gpfile << ", \\\n";
     548             :   }
     549          66 :   gpfile << "\n\n";
     550             : 
     551             :   // plot the postprocessors individually
     552          66 :   column = 2;
     553         132 :   for (const auto & col_name : _column_names)
     554             :   {
     555          66 :     gpfile << "set output '" << col_name << extension << "'\n";
     556          66 :     gpfile << "set ylabel '" << col_name << "'\n";
     557          66 :     gpfile << "plot '" << dat_name << "' using 1:" << column << " title '" << col_name
     558          66 :            << "' with linespoints\n\n";
     559          66 :     column++;
     560             :   }
     561             : 
     562          66 :   gpfile.flush();
     563          66 :   gpfile.close();
     564          66 : }
     565             : 
     566             : void
     567       16504 : FormattedTable::clear()
     568             : {
     569       16504 :   _data.clear();
     570       16504 :   _output_file.close();
     571       16504 :   _output_row_index = 0;
     572       16504 : }
     573             : 
     574             : void
     575      391061 : FormattedTable::fillEmptyValues(unsigned int last_n_entries)
     576             : {
     577      391061 :   auto begin = _data.begin();
     578      391061 :   auto end = _data.end();
     579      391061 :   if (last_n_entries && (last_n_entries < _data.size()))
     580       32416 :     begin = end - last_n_entries;
     581             : 
     582     7237009 :   for (auto it = begin; it != end; ++it)
     583             :   {
     584     6845948 :     auto & datamap = it->second;
     585     6845948 :     if (datamap.size() != _column_names.size())
     586             :     {
     587         213 :       for (const auto & col_name : _column_names)
     588         154 :         if (!datamap[col_name])
     589          59 :           datamap[col_name] =
     590         118 :               std::dynamic_pointer_cast<TableValueBase>(std::make_shared<TableValue<char>>('0'));
     591             :     }
     592             :     else
     593             :     {
     594    19976839 :       for (auto & [key, val] : datamap)
     595    13130950 :         if (!val)
     596           0 :           val = std::dynamic_pointer_cast<TableValueBase>(std::make_shared<TableValue<char>>('0'));
     597             :     }
     598             :   }
     599      391061 : }
     600             : 
     601             : MooseEnum
     602      147199 : FormattedTable::getWidthModes()
     603             : {
     604      147199 :   return MooseEnum("ENVIRONMENT=-1 AUTO=0 80=80 120=120 160=160", "ENVIRONMENT", true);
     605             : }
     606             : 
     607             : void
     608      122195 : FormattedTable::sortColumns()
     609             : {
     610      122195 :   if (_column_names_unsorted)
     611             :   {
     612       21625 :     std::sort(_column_names.begin(), _column_names.end());
     613       21625 :     _column_names_unsorted = false;
     614             :   }
     615      122195 : }
     616             : 
     617             : std::ostream &
     618     2296982 : operator<<(std::ostream & os, const TableValueBase & value)
     619             : {
     620     2296982 :   value.print(os);
     621     2296982 :   return os;
     622             : }

Generated by: LCOV version 1.14