Line data Source code
1 : /*
2 : * Copyright (c) 2012-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #ifndef __H__TABLE
34 : #define __H__TABLE
35 :
36 : #include <sstream>
37 : #include <string>
38 : #include <vector>
39 : #include <iostream>
40 :
41 : namespace ug{
42 :
43 : /// \addtogroup ugbase_common_types
44 : /// \{
45 :
46 : /// Useful for printing a table to the terminal or into a file.
47 : /** This class is for output purposes only. It automatically adds spacings, so
48 : * that all entries in a column are indeed displayed in the same column.
49 : * Note that the implementation is not optimized in regards to speed and efficiency.
50 : * The class thus shouldn't be used in performance critical sections of your code.
51 : * If it is however used in output related code, the introduced overhead should
52 : * be fine and probably even negligible.
53 : *
54 : * The class is most commonly used as a string table (<tt>Table\<std::string\></tt>) or
55 : * as a stringstream table (<tt>Table\<std::stringstream\></tt>). If you want to use it
56 : * for your own types, you may specialize the template method
57 : * \code
58 : * template <class T> std::string EntryToString(const Table<T>& table, size_t rowInd, size_t colInd);
59 : * \endcode
60 : * The default implementation of EntryToString may already be suited for most cases.
61 : *
62 : * Here's an example on how to use the class:
63 : * \code
64 : * #include "common/util/table.h"
65 : * ...
66 : * ug::Table<std::stringstream> table;
67 : * table(0, 0) << "num rows:"; table(0, 1) << table.num_rows();
68 : * table(1, 0) << "num columns:"; table(1, 1) << table.num_cols();
69 : * std::cout << table;
70 : * \endcode
71 : *
72 : * And this is what the output looks like:
73 : * \verbatim
74 : num rows: 2
75 : num columns: 2
76 : * \endverbatim
77 : *
78 : * Note that several typedefs exist: StringTable, StringStreamTable
79 : * \todo different alignments for different columns / rows / fields
80 : */
81 :
82 : template <class T>
83 : class Table
84 : {
85 : public:
86 : Table();
87 : Table(size_t numRows, size_t numCols);
88 :
89 : ~Table();
90 :
91 : void clear();
92 :
93 : void add_rows(size_t num);
94 : void add_cols(size_t num);
95 :
96 : /// Returns a reference to the given entry.
97 : /** If an entry lies outside of the tables bounds, the table will
98 : * automatically be resized accordingly.*/
99 : T& operator() (size_t rowInd, size_t colInd);
100 :
101 : /// uses operator() to set an entry to a value
102 0 : void set(size_t rowInd, size_t colInd, T value)
103 : {
104 0 : operator()(rowInd, colInd) = value;
105 0 : }
106 :
107 : /// Returns a reference to the given entry.
108 : const T& operator() (size_t rowInd, size_t colInd) const;
109 :
110 : /// uses operator() to get a value
111 0 : const T &get(size_t rowInd, size_t colInd) const
112 : {
113 0 : return operator()(rowInd, colInd);
114 : }
115 :
116 : size_t num_rows() const;
117 : size_t num_cols() const;
118 :
119 :
120 :
121 :
122 0 : void set_default_row_seperator(const char *c)
123 : {
124 0 : m_defaultRowSeperator = *c;
125 0 : }
126 0 : void set_row_seperator(size_t i_row, const char *c)
127 : {
128 0 : if(m_rowSep.size() <= i_row) m_rowSep.resize(i_row+1, 0x00);
129 0 : m_rowSep[i_row] = *c;
130 0 : }
131 0 : void set_row_seperators(std::string s)
132 : {
133 0 : if(m_rowSep.size() < s.size()) m_rowSep.resize(s.size(), 0x00);
134 0 : for(size_t i=0; i<s.size(); i++)
135 0 : m_rowSep[i] = s[i];
136 0 : }
137 0 : void set_default_col_seperator(const char *c)
138 : {
139 :
140 0 : m_defaultColSeperator = *c;
141 0 : }
142 0 : void set_col_seperator(size_t i_col, const char *c)
143 : {
144 0 : if(m_colSep.size() <= i_col) m_colSep.resize(i_col+1, 0x00);
145 0 : m_colSep[i_col] = *c;
146 0 : }
147 0 : void set_col_seperators(std::string s)
148 : {
149 0 : if(m_colSep.size() < s.size()) m_colSep.resize(s.size(), 0x00);
150 0 : for(size_t i=0; i<s.size(); i++)
151 0 : m_colSep[i] = s[i];
152 0 : }
153 :
154 0 : void set_default_col_alignment(const char *c)
155 : {
156 0 : m_defaultColAlignment = *c;
157 0 : }
158 0 : void set_col_alignment(size_t i_col, const char *c)
159 : {
160 0 : if(m_colAlign.size() <= i_col) m_colAlign.resize(i_col+1, 0x00);
161 0 : m_colAlign[i_col] = *c;
162 0 : }
163 0 : void set_col_alignments(std::string s)
164 : {
165 0 : if(m_colAlign.size() < s.size()) m_colAlign.resize(s.size(), 0x00);
166 0 : for(size_t i=0; i<s.size(); i++)
167 0 : m_colAlign[i] = s[i];
168 0 : }
169 :
170 : std::ostream& stream(std::ostream& os) const;
171 : std::string to_latex() const;
172 : std::string to_string() const;
173 : std::string to_csv(const char *seperator) const;
174 :
175 : char get_row_sep(size_t row) const
176 : {
177 0 : if(row >= m_rowSep.size()) return m_defaultRowSeperator;
178 0 : return m_rowSep[row] != 0x00 ? m_rowSep[row] : m_defaultRowSeperator;
179 : }
180 :
181 : char get_col_sep(size_t col) const
182 : {
183 0 : if(col >= m_colSep.size()) return m_defaultColSeperator;
184 0 : return m_colSep[col] != 0x00 ? m_colSep[col] : m_defaultColSeperator;
185 : }
186 :
187 : char get_col_alignment(size_t col) const
188 : {
189 0 : if(col >= m_colAlign.size()) return m_defaultColAlignment;
190 0 : return m_colAlign[col] != 0x00 ? m_colAlign[col] : m_defaultColAlignment;
191 : }
192 :
193 0 : void transpose()
194 : {
195 : DataVec newData;
196 0 : newData.resize(m_numCols);
197 0 : for(size_t irow = 0; irow < m_numRows; ++irow){
198 0 : for(size_t icol = 0; icol < m_numCols; ++icol){
199 0 : newData[icol].push_back(m_data[irow][icol]);
200 : }
201 : }
202 : std::swap(m_numRows, m_numCols);
203 : m_data.swap(newData);
204 0 : }
205 : private:
206 : size_t m_numRows;
207 : size_t m_numCols;
208 :
209 : typedef std::vector<std::vector<T*> > DataVec;
210 : DataVec m_data;
211 :
212 : std::vector<char> m_colAlign;
213 : std::vector<char> m_colSep;
214 : std::vector<char> m_rowSep;
215 : char m_defaultColSeperator, m_defaultRowSeperator, m_defaultColAlignment;
216 :
217 : };
218 :
219 : /// prints a table to the specified ostream.
220 : /** Assumes that output begins at a new line.
221 : * The method uses the template method
222 : * size_t EstimateEntryWidth<T>(const Table<T>& table, size_t rowInd, size_t colInd).
223 : * You may overload this method to adjust it to your datatypes.
224 : * Note that specializations exist for std::string and std::stringstream.
225 : *
226 : * \todo Support for line-breaks ('\n' etc) and multi-line rows.
227 : */
228 : template <class T>
229 : std::ostream& operator << (std::ostream& os, const Table<T>& table);
230 :
231 :
232 : /// Returns a string-representation of the current entry.
233 : /** The default implementation prints the entry to a std::stringstream and returns
234 : * the associated string. Specializations exist for std::string and std::stringstream.
235 : */
236 : template <class T>
237 : std::string EntryToString(const Table<T>& table, size_t rowInd, size_t colInd);
238 :
239 : inline
240 : std::string EntryToString(const Table<std::string>& table,
241 : size_t rowInd, size_t colInd);
242 :
243 : inline
244 : std::string EntryToString(const Table<std::stringstream>& table,
245 : size_t rowInd, size_t colInd);
246 :
247 :
248 : typedef Table<std::string> StringTable;
249 : typedef Table<std::stringstream> StringStreamTable;
250 :
251 : // end group ugbase_common_types
252 : /// \}
253 :
254 : }// end of namespace
255 :
256 : ////////////////////////////////////////
257 : // include implementation
258 : #include "table_impl.hpp"
259 :
260 : #endif
|