Sierra Toolkit Version of the Day
PrintTable.hpp
00001 /*------------------------------------------------------------------------*/
00002 /*                 Copyright 2010 Sandia Corporation.                     */
00003 /*  Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive   */
00004 /*  license for use of this work by or on behalf of the U.S. Government.  */
00005 /*  Export of this program may require a license from the                 */
00006 /*  United States Government.                                             */
00007 /*------------------------------------------------------------------------*/
00008 
00009 #ifndef stk_util_util_PrintTable_hpp
00010 #define stk_util_util_PrintTable_hpp
00011 
00012 #include <vector>
00013 #include <string>
00014 #include <sstream>
00015 
00016 namespace stk {
00017 
00018 class PrintTable
00019 {
00020   template<typename T>
00021   friend PrintTable &operator<<(PrintTable &table, const T &t);
00022 
00023 public:
00024   typedef std::string::size_type ColumnWidth;
00025   typedef std::vector<ColumnWidth> ColumnWidthVector;
00026 
00027   struct Cell
00028   {
00029     enum Flags {
00030       SPAN = 0x01
00031     };
00032 
00033     enum Justification {
00034       LEFT    = 1,
00035       RIGHT   = 2,
00036       CENTER    = 3,
00037       JUSTIFY_MASK  = 0x0F,
00038       TRUNC   = 0x10,
00039       ENDS    = 0x20
00040     };
00041 
00042     Cell()
00043       : m_string(),
00044   m_flags(0),
00045   m_justification(RIGHT | TRUNC),
00046   m_indent(0),
00047   m_width(0)
00048     {}
00049 
00050     std::string     m_string;
00051     int       m_flags;
00052     int       m_justification;
00053     ColumnWidth                 m_indent;
00054     ColumnWidth                 m_width;
00055   };
00056 
00057   typedef std::vector<Cell> Row;
00058   typedef std::vector<Row> Table;
00059 
00060   enum Flags {
00061     AUTO_END_COL                = 0x01,
00062     COMMA_SEPARATED_VALUES      = 0x02,
00063     PRINT_TRANSPOSED            = 0x04
00064   };
00065 
00066   PrintTable()
00067     : m_flags(AUTO_END_COL),
00068       m_tableWidth(0)
00069   {
00070     m_table.push_back(Row());
00071   }
00072 
00073   explicit PrintTable(std::ostream &os)
00074     : m_flags(AUTO_END_COL),
00075       m_commentPrefix(),
00076       m_tableWidth(0)
00077   {
00078     m_table.push_back(Row());
00079   }
00080 
00081 private:
00082   PrintTable(const PrintTable &);
00083   PrintTable &operator=(const PrintTable &);
00084 
00085 public:
00086   ~PrintTable()
00087   {}
00088   
00089   Row::size_type headerSize() const {
00090     return m_header.empty() ? 0 : m_header.begin()->size();
00091   }
00092 
00093   Table::size_type size() const {
00094     return m_table.size();
00095   }
00096 
00097   bool autoEndCol() const {
00098     return m_flags & AUTO_END_COL;
00099   }
00100 
00101   PrintTable &setAutoEndCol(bool auto_end_col = true) {
00102     if (auto_end_col)
00103       m_flags |= AUTO_END_COL;
00104     else
00105       m_flags &= ~AUTO_END_COL;
00106     return *this;
00107   }
00108 
00109   bool commaSeparatedValues() const {
00110     return m_flags & COMMA_SEPARATED_VALUES;
00111   }
00112 
00113   PrintTable &setCommaSeparatedValues(bool comma_separated_values = true) {
00114     if (comma_separated_values)
00115       m_flags |= COMMA_SEPARATED_VALUES;
00116     else
00117       m_flags &= ~COMMA_SEPARATED_VALUES;
00118     return *this;
00119   }
00120 
00121   PrintTable &setCommentPrefix(const std::string &comment_prefix) {
00122     m_commentPrefix = comment_prefix;
00123     return *this;
00124   }
00125 
00126   const std::string &getCommentPrefix() const {
00127     return m_commentPrefix;
00128   }
00129 
00134   PrintTable &setTitle(const std::string &title){
00135     m_title = title;
00136     return *this;
00137   }
00138 
00139   const std::string &getTitle() const {
00140     return m_title;
00141   }
00142 
00149   PrintTable& operator<<(PrintTable& (*f)(PrintTable&)) {
00150     f(*this);
00151     return *this;
00152 
00153   }
00154 
00161   PrintTable& operator<<(std::ios_base& (*f)(std::ios_base&)) {
00162     f(m_currentString);
00163     return *this;
00164   }
00165 
00166   PrintTable &push() {
00167     ++m_currentCell.m_indent;
00168     return *this;
00169   }
00170 
00171   PrintTable &span() {
00172     m_currentCell.m_flags |= Cell::SPAN;
00173     return *this;
00174   }
00175 
00176   PrintTable &pop() {
00177     if (m_currentCell.m_indent != 0)
00178       --m_currentCell.m_indent;
00179 
00180     return *this;
00181   }
00182 
00183   PrintTable &cell_width(ColumnWidth width) {
00184     m_currentCell.m_width = width;
00185 
00186     return *this;
00187   }
00188 
00189   PrintTable &indent(ColumnWidth indent) {
00190     m_currentCell.m_indent = indent;
00191 
00192     return *this;
00193   }
00194 
00195   PrintTable &justify(int justification) {
00196     m_currentCell.m_justification = justification;
00197 
00198     return *this;
00199   }
00200 
00201   PrintTable &end_col();
00202 
00203   PrintTable &end_row();
00204 
00205   PrintTable &at(size_t row, size_t col);
00206 
00207   PrintTable &end_header() {
00208     m_header.push_back(m_table.back());
00209     m_table.pop_back();
00210     m_table.push_back(Row());
00211     return *this;
00212   }
00213 
00214   PrintTable &end_format() {
00215     m_format = m_table.back();
00216     m_table.pop_back();
00217     m_table.push_back(Row());
00218     return *this;
00219   }
00220 
00221   void calculate_column_widths() const;
00222 
00223   void transpose_table() const;
00224 
00228   std::ostream &print(std::ostream &os) const;
00229 
00233   std::ostream &printRow(std::ostream &os, const Row &row) const;
00234 
00238   std::ostream &printHeaderBar(std::ostream &os) const;
00239 
00243   std::ostream &csvPrint(std::ostream &os) const;
00244 
00245 private:
00253   void normalize_table(int row, int col);
00254 
00255 private:
00256   std::string     m_title;
00257   Table       m_header;
00258   Row       m_format;
00259   Table       m_table;
00260   Cell        m_currentCell;
00261   std::ostringstream    m_currentString;
00262   int       m_flags;
00263   std::string                   m_commentPrefix;
00264   mutable ColumnWidthVector m_columnWidth;
00265   mutable ColumnWidth         m_tableWidth;
00266 };
00267 
00268 
00269 template<typename T>
00270 PrintTable &operator<<(PrintTable &table, const T &t) {
00271   table.m_currentString << t;
00272   if (table.autoEndCol())
00273     table.end_col();
00274 
00275   return table;
00276 }
00277 
00278 
00279 struct cell_width
00280 {
00281   cell_width(PrintTable::ColumnWidth width)
00282     : m_width(width)
00283   {}
00284 
00285   PrintTable::ColumnWidth m_width;
00286 };
00287 
00288 
00289 struct at
00290 {
00291   at(size_t row, size_t col)
00292     : m_row(row),
00293       m_col(col)
00294   {}
00295 
00296   size_t                        m_row;
00297   size_t                        m_col; 
00298 };
00299 
00300 
00301 struct indent
00302 {
00303   indent(PrintTable::ColumnWidth indent)
00304     : m_indent(indent)
00305   {}
00306 
00307   PrintTable::ColumnWidth m_indent;
00308 };
00309 
00310 
00311 struct justify
00312 {
00313   justify(int justify)
00314     : m_justify(justify)
00315   {}
00316 
00317   int   m_justify;
00318 };
00319 
00320 
00321 inline PrintTable &operator<<(PrintTable &tout, const cell_width &m) {
00322   tout.cell_width(m.m_width);
00323   return tout;
00324 }
00325 
00326 inline PrintTable &operator<<(PrintTable &tout, const at &m) {
00327   tout.at(m.m_row, m.m_col);
00328   return tout;
00329 }
00330 
00331 inline PrintTable &operator<<(PrintTable &tout, const indent &m) {
00332   tout.indent(m.m_indent);
00333   return tout;
00334 }
00335 
00336 inline PrintTable &operator<<(PrintTable &tout, const justify &m) {
00337   tout.justify(m.m_justify);
00338   return tout;
00339 }
00340 
00341 inline PrintTable &end_col(PrintTable &tout) {
00342   return tout.end_col();
00343 }
00344 
00345 inline PrintTable &end_row(PrintTable &tout) {
00346   return tout.end_row();
00347 }
00348 
00349 inline PrintTable &end_header(PrintTable &tout) {
00350   return tout.end_header();
00351 }
00352 
00353 inline PrintTable &end_format(PrintTable &tout) {
00354   return tout.end_format();
00355 }
00356 
00357 inline PrintTable &push(PrintTable &tout) {
00358   return tout.push();
00359 }
00360 
00361 inline PrintTable &pop(PrintTable &tout) {
00362   return tout.pop();
00363 }
00364 
00365 inline PrintTable &span(PrintTable &tout) {
00366   return tout.span();
00367 }
00368 
00369 inline std::ostream &operator<<(std::ostream &os, const PrintTable &table){
00370   return table.print(os);
00371 }
00372 
00373 } // namespace sierra
00374 
00375 #endif // stk_util_util_PrintTable_hpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends