NCBI C++ ToolKit
table_printer.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef UTIL___TABLE_PRINTER__HPP
2 #define UTIL___TABLE_PRINTER__HPP
3 
4 /* $Id: table_printer.hpp 72358 2016-05-03 17:12:04Z ivanov $
5 * ===========================================================================
6 *
7 * PUBLIC DOMAIN NOTICE
8 * National Center for Biotechnology Information
9 *
10 * This software/database is a "United States Government Work" under the
11 * terms of the United States Copyright Act. It was written as part of
12 * the author's official duties as a United States Government employee and
13 * thus cannot be copyrighted. This software/database is freely available
14 * to the public for use. The National Library of Medicine and the U.S.
15 * Government have not placed any restriction on its use or reproduction.
16 *
17 * Although all reasonable efforts have been taken to ensure the accuracy
18 * and reliability of the software and data, the NLM and the U.S.
19 * Government do not and cannot warrant the performance or results that
20 * may be obtained by using this software or data. The NLM and the U.S.
21 * Government disclaim all warranties, express or implied, including
22 * warranties of performance, merchantability or fitness for any particular
23 * purpose.
24 *
25 * Please cite the author in any work or product based on this material.
26 *
27 * ===========================================================================
28 *
29 * Author: Michael Kornbluh
30 *
31 * File Description:
32 * Prints out neatly-aligned ASCII tables.
33 *
34 * ===========================================================================
35 */
36 
37 #include <corelib/ncbistd.hpp>
38 #include <corelib/ncbistre.hpp>
39 #include <corelib/ncbiobj.hpp>
40 
41 #include <sstream>
42 
44 
45 /// This can be used to lay out neat ASCII data.
46 /// Example:<br>
47 /// <pre>
48 /// -------------------- --------
49 /// Name ZIP code
50 /// -------------------- --------
51 /// Pat Doe 22801
52 /// Sammy Smith 20852
53 /// Chris Doe 08361
54 /// -------------------- --------
55 /// </pre>
56 /// Here is example code that would let you lay out such a table
57 /// into cout:
58 /// <pre>
59 /// CTablePrinter::SColInfoVec vecColInfo;
60 /// vecColInfo.AddCol("Name", 20);
61 /// vecColInfo.AddCol("ZIP code", 5);
62 ///
63 /// typedef CTablePrinter::SEndOfCell SEndOfCell;
64 ///
65 /// CTablePrinter table_printer(vecColInfo, cout);
66 ///
67 /// table_printer << "Pat" << ' ' << "Doe" << SEndOfCell();
68 /// table_printer << "22801" << SEndOfCell();
69 ///
70 /// table_printer << "Sammy Smith" << SEndOfCell();
71 /// table_printer << "20852" << SEndOfCell();
72 ///
73 /// table_printer << "Chris Doe" << SEndOfCell();
74 /// table_printer << "08361" << SEndOfCell();
75 ///
76 /// table_printer.FinishTable();
77 /// </pre>
79 public:
80 
81  /// controls how table should behave when a data cell
82  /// is too long to fit into its column.
83  enum EDataTooLong {
84  /// The data will be replaced with some sort of
85  /// error message, or at least question marks if the error
86  /// message wouldn't fit.
88  /// The data is truncated with ellipses (that is, "...").
89  /// This is NOT recommended for numeric
90  /// data because a truncated number can look like a
91  /// different number if the viewer doesn't notice the
92  /// ellipses.
94  /// This recklessly prints the whole table data, regardless of
95  /// formatting corruption and regardless of how long
96  /// the data is.
98  /// Throws an exception when the data won't fit.
100 
101  /// Default behavior.
102  eDataTooLong_Default = eDataTooLong_ShowErrorInColumn
103  };
104  /// controls how the data in each column is justified.
105  /// As a rough rule of thumb, numeric data should be right-justified
106  /// and non-numeric data should be left-justified.
107  enum EJustify {
109  eJustify_Right
110  };
111 
112  /// This structure contains info about a given column
114  SColInfo(const string & sColName,
115  Uint4 iColWidth,
116  EJustify eJustify = eJustify_Left,
117  EDataTooLong eDataTooLong = eDataTooLong_ShowErrorInColumn ) :
118  m_sColName(sColName), m_iColWidth(iColWidth),
119  m_eJustify(eJustify), m_eDataTooLong(eDataTooLong) { }
120 
121  /// The name of the column, which is shown in the header
122  string m_sColName;
123  /// How many characters wide the column is
125  /// Justification of data cells in this column
126  /// (the name of the column is always left-justified, though)
128  /// How data cells should behave in this column behave when
129  /// there is too much data to fit in them.
131  };
132  /// This holds the info about all columns for the table.
133  /// Call AddCol() until all the columns you want are added, then
134  /// use it to create a CTablePrinter.
136  void AddCol(const string & sColName,
137  Uint4 iColWidth = 0,
138  EJustify eJustify = eJustify_Left,
139  EDataTooLong eDataTooLong = eDataTooLong_Default );
140 
141  typedef vector<SColInfo> TColInfoVec;
142  /// The underlying column info vector for which SColInfoVec
143  /// is a wrapper.
145  };
146 
147  /// @param vecColInfo
148  /// This holds information about all the columns that will
149  /// be shown in the table.
150  /// @param ostrm
151  /// This is the output stream to which the table will be written
152  /// @param sColumnSeparator
153  /// Default should be fine for most purposes, but the caller
154  /// can separate columns with something else (for example, " | ").
156  const SColInfoVec & vecColInfo, ostream & ostrm,
157  const string & sColumnSeparator = " ");
158 
159  /// Destructor finishes the table if it's not already finished.
160  /// See FinishTable().
162  FinishTable();
163  }
164 
165  /// Stream an instance of this object into the CTablePrinter
166  /// to have it write out the current table cell and prepare for the
167  /// next one. See the documentation of this class for more details.
168  struct SEndOfCell {
169  int dummy; // in case compiler doesn't like empty classes
170  };
171 
172  /// This is just a helper for the global "operator <<" function
173  /// for writing into the table.
174  template<class TValue>
176  const TValue & value)
177  {
178  m_NextCellContents << value;
179  return *this;
180  }
181 
182  /// This writes the contents of the current cell and
183  /// prepares for the next one. This is really just a helper
184  /// for the "operator <<" that accepts SEndOfCell.
186  {
187  // reset m_NextCellContents early in case
188  // x_AddCellValue throws.
189  const string sNextCellContents( m_NextCellContents.str() );
190  m_NextCellContents.str(kEmptyStr);
191 
192  // might throw
193  x_AddCellValue(sNextCellContents);
194 
195  return *this;
196  }
197 
198  /// If the table is not already finished, this
199  /// finishes it by writing the closing row (which
200  /// is usually a series of dashes).
201  /// If cells are added after this point, a new header will
202  /// be printed and a new table will be written.
203  void FinishTable(void);
204 
205 private:
206  /// This keeps track of the state of the table writer.
207  enum EState {
208  /// This means the header row has NOT been printed yet.
210  /// This means the header row HAS been printed, and data
211  /// rows are being printed.
213  };
214  /// This keeps track of the state of the table writer.
216 
217  /// The info about columns of the table
219  /// The ostream to which the table is written
220  ostream & m_ostrm;
221  /// The 0-based index of the column that the next AddCell will use.
223  /// The text that separates columns (both in the header as well as dat).
224  const string m_sColumnSeparator;
225 
226  /// The contents of the current table cell are accumulated
227  /// in here.
228  stringstream m_NextCellContents;
229 
230  /// forbid copy
232  /// forbid assignment
233  CTablePrinter & operator = (const CTablePrinter &);
234 
235  /// This writes a row of dashes which starts the table,
236  /// separates the header from the data, and ends the table.
237  void x_PrintDashes(void);
238  /// This prints the column names, appropriately spaced and separated.
239  void x_PrintColumnNames(void);
240 
241  /// This is the underlying logic to add another cell to the table data.
242  void x_AddCellValue(const string & sValue);
243 };
244 
245 // inline functions
246 
247  /// Writes object to current table cell.
248  template<typename TValue>
249  inline
251  CTablePrinter & table_printer, const TValue & value)
252  {
253  return table_printer.StreamToCurrentCell(value);
254  }
255 
256  /// Flushes table cell contents and prepares for the next cell.
257  template<>
258  inline
259  CTablePrinter & operator << <CTablePrinter::SEndOfCell>(
260  CTablePrinter & table_printer, const CTablePrinter::SEndOfCell & /*end_of_cell*/)
261  {
262  return table_printer.EndOfCurrentCell();
263  }
264 
265 
267 
268 #endif /* UTIL___TABLE_PRINTER__HPP */
This can be used to lay out neat ASCII data.
CTablePrinter(const CTablePrinter &)
forbid copy
SColInfoVec m_vecColInfo
The info about columns of the table.
const string m_sColumnSeparator
The text that separates columns (both in the header as well as dat).
Uint4 m_iNextCol
The 0-based index of the column that the next AddCell will use.
CTablePrinter & EndOfCurrentCell(void)
This writes the contents of the current cell and prepares for the next one.
EDataTooLong
controls how table should behave when a data cell is too long to fit into its column.
@ eDataTooLong_ShowErrorInColumn
The data will be replaced with some sort of error message, or at least question marks if the error me...
@ eDataTooLong_ShowWholeData
This recklessly prints the whole table data, regardless of formatting corruption and regardless of ho...
@ eDataTooLong_TruncateWithEllipses
The data is truncated with ellipses (that is, "...").
@ eDataTooLong_ThrowException
Throws an exception when the data won't fit.
stringstream m_NextCellContents
The contents of the current table cell are accumulated in here.
ostream & m_ostrm
The ostream to which the table is written.
CTablePrinter & StreamToCurrentCell(const TValue &value)
This is just a helper for the global "operator <<" function for writing into the table.
EState m_eState
This keeps track of the state of the table writer.
~CTablePrinter(void)
Destructor finishes the table if it's not already finished.
@ eState_PrintingRows
This means the header row HAS been printed, and data rows are being printed.
@ eState_Initial
This means the header row has NOT been printed yet.
EJustify
controls how the data in each column is justified.
char value[7]
Definition: config.c:431
Include a standard set of the NCBI C++ Toolkit most basic headers.
uint32_t Uint4
4-byte (32-bit) unsigned integer
Definition: ncbitype.h:103
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define kEmptyStr
Definition: ncbistr.hpp:123
Portable reference counted smart and weak pointers using CWeakRef, CRef, CObject and CObjectEx.
NCBI C++ stream class wrappers for triggering between "new" and "old" C++ stream libraries.
NCBI_XUTIL_EXPORT
Parameter to control printing diagnostic message about conversion of static array data from a differe...
Definition: static_set.hpp:72
This holds the info about all columns for the table.
vector< SColInfo > TColInfoVec
TColInfoVec m_colInfoVec
The underlying column info vector for which SColInfoVec is a wrapper.
This structure contains info about a given column.
EJustify m_eJustify
Justification of data cells in this column (the name of the column is always left-justified,...
EDataTooLong m_eDataTooLong
How data cells should behave in this column behave when there is too much data to fit in them.
string m_sColName
The name of the column, which is shown in the header.
SColInfo(const string &sColName, Uint4 iColWidth, EJustify eJustify=eJustify_Left, EDataTooLong eDataTooLong=eDataTooLong_ShowErrorInColumn)
Uint4 m_iColWidth
How many characters wide the column is.
Stream an instance of this object into the CTablePrinter to have it write out the current table cell ...
CTablePrinter & operator<<(CTablePrinter &table_printer, const TValue &value)
Writes object to current table cell.
Modified on Mon Feb 26 03:59:57 2024 by modify_doxy.py rev. 669887