LCOV - code coverage report
Current view: top level - include/ioutils - textTable.hpp (source / functions) Coverage Total Hit
Test: mxlib Lines: 96.3 % 27 26
Test Date: 2026-08-30 22:23:37 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /** \file textTable.hpp
       2              :  * \brief declares and defines a simple text table manager
       3              :  *
       4              :  * \author Jared R. Males (jaredmales@gmail.com)
       5              :  *
       6              :  * \ingroup asciiutils
       7              :  *
       8              :  */
       9              : 
      10              : //***********************************************************************//
      11              : // Copyright 2015, 2016, 2017 Jared R. Males (jaredmales@gmail.com)
      12              : //
      13              : // This file is part of mxlib.
      14              : //
      15              : // mxlib is free software: you can redistribute it and/or modify
      16              : // it under the terms of the GNU General Public License as published by
      17              : // the Free Software Foundation, either version 3 of the License, or
      18              : // (at your option) any later version.
      19              : //
      20              : // mxlib is distributed in the hope that it will be useful,
      21              : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      22              : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      23              : // GNU General Public License for more details.
      24              : //
      25              : // You should have received a copy of the GNU General Public License
      26              : // along with mxlib.  If not, see <http://www.gnu.org/licenses/>.
      27              : //***********************************************************************//
      28              : 
      29              : #ifndef textTable_hpp
      30              : #define textTable_hpp
      31              : 
      32              : #include <string>
      33              : #include <sstream>
      34              : 
      35              : #include "../mxlib.hpp"
      36              : 
      37              : #include "stringUtils.hpp"
      38              : 
      39              : /// The mxlib c++ namespace
      40              : namespace mx
      41              : {
      42              : namespace ioutils
      43              : {
      44              : 
      45              : /** \addtogroup asciiutils
      46              :  * @{
      47              :  */
      48              : 
      49              : /// An ascii table formatter
      50              : /** Manages a table of string content, including word-wrapping within cells.
      51              :  * Contents are output to an ostream line by line with a table structure.
      52              :  *
      53              :  * \todo have ability to add whole row, with a variadic template to handle different types
      54              :  * \todo allow non-wrapping (i.e. unlimited width) columns
      55              :  * \todo headers and footers
      56              :  * \todo add centering (h and v) and right and bottom justification
      57              :  * \todo have a latex() setup function
      58              :  * \todo add sort capability, with vector of column choices to sort first by column N, then M, etc.
      59              :  */
      60              : struct textTable
      61              : {
      62              :     std::vector<int> m_colWidths; ///< The widths of each column, not including the separator.
      63              : 
      64              :     /// The table cells.
      65              :     /** Organized as rows.cells.lines, where a cell could be multiple lines.
      66              :      */
      67              :     std::vector<std::vector<std::vector<std::string>>> m_rows;
      68              : 
      69              :     std::string m_lineStart; ///< Text to print at the beginning of the line.
      70              : 
      71              :     std::string m_lineEnd; ///< Text to print at the end of the line.
      72              : 
      73              :     std::string m_colSep; ///< Text to print between each column.
      74              : 
      75              :     std::string m_rowSep; ///< Text to print between each row.
      76              : 
      77              :     /// Add one cell to the table, overwriting if it already exists.
      78              :     void addCell( size_t row,             ///< [in] the row of the cell.
      79              :                   size_t col,             ///< [in] the column of the cell.
      80              :                   const std::string &cell ///< [in] the new contents of the cell, will be wrapped.
      81              :     );
      82              : 
      83              :     void addCell( size_t row,      ///< [in] the row of the cell.
      84              :                   size_t col,      ///< [in] the column of the cell.
      85              :                   const char *cell ///< [in] the new contents of the cell, will be wrapped.
      86              :     );
      87              : 
      88              :     /// Add one cell to the table, overwriting if it already exists.
      89              :     template <typename typeT>
      90              :     void addCell( size_t row,        ///< [in] the row of the cell.
      91              :                   size_t col,        ///< [in] the column of the cell.
      92              :                   const typeT &cell, ///< [in] the new contents of the cell, will be wrapped.
      93              :                   int precision = 0 );
      94              : 
      95              :     /// Output the table to a stream
      96              :     /** Prints the table to the stream, with separators, etc.
      97              :      *
      98              :      * \tparam iosT is a std::ostream-like type.
      99              :      */
     100              :     template <typename iosT>
     101              :     void outPut( iosT &ios /**< [in] a std::ostream-like stream.*/ );
     102              : };
     103              : 
     104              : template <typename typeT>
     105              : void textTable::addCell( size_t row, size_t col, const typeT &cell, int precision )
     106              : {
     107              :     addCell( row, col, convertToString<typeT>( cell, precision ) );
     108              : }
     109              : 
     110              : template <typename iosT>
     111            2 : void textTable::outPut( iosT &ios )
     112              : {
     113            2 :     std::string line;
     114              : 
     115            2 :     size_t width = 0;
     116           12 :     for( size_t i = 0; i < m_colWidths.size(); ++i )
     117           10 :         width += m_colWidths[i];
     118            2 :     width += m_colWidths.size() * ( m_colSep.length() - 1 ); //+100;
     119              : 
     120            2 :     line.resize( width, ' ' );
     121              : 
     122            5 :     for( size_t i = 0; i < m_rows.size(); ++i )
     123              :     {
     124            3 :         size_t rowL = 0;
     125           18 :         for( size_t j = 0; j < m_colWidths.size(); ++j )
     126              :         {
     127           15 :             if( m_rows[i][j].size() > rowL )
     128            3 :                 rowL = m_rows[i][j].size();
     129              :         }
     130              : 
     131            6 :         for( size_t k = 0; k < rowL; ++k )
     132              :         {
     133              :             // line.insert( 0, line.length(), ' ');
     134            3 :             line.clear();
     135            3 :             line.resize( width, ' ' );
     136              :             // line.replace(0, width, width, ' ');
     137              : 
     138            3 :             size_t startPos = 0;
     139           18 :             for( size_t j = 0; j < m_colWidths.size(); ++j )
     140              :             {
     141           15 :                 if( m_rows[i][j].size() > k )
     142           13 :                     line.replace( startPos, m_rows[i][j][k].length(), m_rows[i][j][k] );
     143           15 :                 startPos += m_colWidths[j];
     144              : 
     145           15 :                 if( j < m_colWidths.size() - 1 )
     146           12 :                     line.replace( startPos, m_colSep.length(), m_colSep );
     147           15 :                 startPos += m_colSep.length();
     148              :             }
     149              : 
     150            3 :             ios << m_lineStart << line << m_lineEnd << "\n";
     151              :         }
     152              : 
     153            3 :         if( m_rowSep.length() > 0 )
     154            0 :             ios << m_rowSep << "\n";
     155              :     }
     156            2 : }
     157              : 
     158              : extern template void textTable::outPut<std::ostream>( std::ostream &ios );
     159              : 
     160              : /// @}
     161              : 
     162              : } // namespace ioutils
     163              : } // namespace mx
     164              : 
     165              : #endif // textTable_hpp
        

Generated by: LCOV version 2.0-1