|
Sierra Toolkit
Version of the Day
|
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