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_IMPL__
34 : #define __H__TABLE_IMPL__
35 :
36 : #include <iomanip>
37 : #include <cassert>
38 : #include "common/error.h"
39 : #include "common/log.h"
40 : #include "string_util.h"
41 :
42 : namespace ug{
43 :
44 : template <class T>
45 0 : Table<T>::Table() :
46 0 : m_numRows(0),
47 0 : m_numCols(0)
48 : {
49 0 : m_defaultColSeperator = ' ';
50 0 : m_defaultRowSeperator = ' ';
51 0 : m_defaultColAlignment = 'l';
52 : }
53 :
54 : template <class T>
55 0 : Table<T>::Table(size_t numRows, size_t numCols) :
56 0 : m_numRows(0),
57 0 : m_numCols(0)
58 : {
59 0 : m_defaultColSeperator = ' ';
60 0 : m_defaultRowSeperator = ' ';
61 0 : m_defaultColAlignment = 'l';
62 0 : add_rows(numRows);
63 0 : add_cols(numCols);
64 0 : }
65 :
66 : template <class T>
67 0 : Table<T>::~Table()
68 : {
69 0 : clear();
70 0 : }
71 :
72 : template <class T>
73 0 : void Table<T>::clear()
74 : {
75 0 : for(size_t i_row = 0; i_row < m_numRows; ++i_row){
76 0 : for(size_t i_col = 0; i_col < m_numCols; ++i_col){
77 0 : delete m_data[i_row][i_col];
78 : }
79 : }
80 0 : m_numRows = m_numCols = 0;
81 : m_data.clear();
82 0 : }
83 :
84 : template <class T>
85 0 : void Table<T>::add_rows(size_t num)
86 : {
87 0 : if(num > 0){
88 0 : size_t newSize = m_numRows + num;
89 0 : m_data.resize(newSize);
90 :
91 0 : if(m_numCols > 0){
92 0 : for(size_t i_row = m_numRows; i_row < newSize; ++i_row){
93 0 : m_data[i_row].resize(m_numCols);
94 0 : for(size_t i_col = 0; i_col < m_numCols; ++i_col)
95 0 : m_data[i_row][i_col] = new T;
96 : }
97 : }
98 0 : m_numRows = newSize;
99 : }
100 0 : }
101 :
102 : template <class T>
103 0 : void Table<T>::add_cols(size_t num)
104 : {
105 0 : if(num > 0){
106 0 : size_t newSize = m_numCols + num;
107 0 : for(size_t i_row = 0; i_row < m_numRows; ++i_row){
108 0 : m_data[i_row].resize(newSize);
109 0 : for(size_t i_col = m_numCols; i_col < newSize; ++i_col)
110 0 : m_data[i_row][i_col] = new T;
111 : }
112 0 : m_numCols = newSize;
113 : }
114 0 : }
115 :
116 : template <class T>
117 0 : T& Table<T>::operator() (size_t rowInd, size_t colInd)
118 : {
119 0 : if(rowInd >= num_rows())
120 0 : add_rows((rowInd + 1) - num_rows());
121 :
122 0 : if(colInd >= num_cols())
123 0 : add_cols((colInd + 1) - num_cols());
124 :
125 0 : return *m_data[rowInd][colInd];
126 : }
127 :
128 : template <class T>
129 0 : const T& Table<T>::operator() (size_t rowInd, size_t colInd) const
130 : {
131 0 : UG_COND_THROW(rowInd >= num_rows(), "Bad row index: " << rowInd << "! Only " << num_rows() << " rows exist.");
132 0 : UG_COND_THROW(colInd >= num_cols(), "Bad col index: " << colInd << "! Only " << num_cols() << " cols exist.");
133 0 : return *m_data[rowInd][colInd];
134 : }
135 :
136 : template <class T>
137 0 : size_t Table<T>::num_rows() const
138 : {
139 0 : return m_numRows;
140 : }
141 :
142 : template <class T>
143 0 : size_t Table<T>::num_cols() const
144 : {
145 0 : return m_numCols;
146 : }
147 :
148 :
149 :
150 :
151 :
152 : template <class T>
153 0 : std::string Table<T>::to_string() const
154 : {
155 0 : std::stringstream ssOut;
156 : ssOut << *this;
157 0 : return ssOut.str();
158 0 : }
159 :
160 :
161 :
162 : template<typename T>
163 0 : std::string Table<T>::to_latex() const
164 : {
165 0 : Table<std::string> strTable(num_rows(), num_cols());
166 :
167 0 : std::stringstream os;
168 0 : os << "\\begin{table}\n\\centering\n";
169 0 : os << "\\begin{tabular}{";
170 0 : for(size_t i=0; i < num_cols(); i++)
171 0 : os << get_col_sep(i) << get_col_alignment(i);
172 0 : os << get_col_sep(num_cols());
173 0 : os << "}\n";
174 :
175 :
176 0 : for(size_t i_row = 0; i_row < num_rows(); ++i_row)
177 : {
178 0 : if(get_row_sep(i_row) != ' ')
179 0 : os << "\\hline \n";
180 :
181 0 : for(size_t i_col = 0; i_col < num_cols(); ++i_col)
182 : {
183 0 : if(i_col != 0) os << " & ";
184 0 : os << EntryToString(*this, i_row, i_col);
185 : }
186 :
187 0 : os << " \\\\\n";
188 : }
189 0 : if(get_row_sep(num_rows()) != ' ')
190 0 : os << "\\hline \n";
191 0 : os << "\\end{tabular}\n";
192 0 : os << "\\end{table}\n";
193 0 : return os.str();
194 0 : }
195 :
196 :
197 : template<typename T>
198 0 : std::string Table<T>::to_csv(const char *seperator) const
199 : {
200 0 : std::stringstream os;
201 0 : for(size_t i_row = 0; i_row < num_rows(); ++i_row)
202 : {
203 0 : for(size_t i_col = 0; i_col < num_cols(); ++i_col)
204 : {
205 0 : if(i_col != 0) os << " " << seperator << " ";
206 0 : os << EntryToString(*this, i_row, i_col);
207 : }
208 :
209 0 : os << "\n";
210 : }
211 0 : return os.str();
212 0 : }
213 :
214 : template <class T>
215 : std::ostream& operator << (std::ostream& os, const Table<T>& table)
216 : {
217 0 : return table.stream(os);
218 : }
219 :
220 : template <class T>
221 0 : std::ostream& Table<T>::stream(std::ostream& os) const
222 : {
223 : const Table<T> &table = *this;
224 : // we'll fill a fresh table with strings of the given table
225 : // At the same time we'll find the max-width of each column
226 0 : Table<std::string> strTable(num_rows(), num_cols());
227 0 : std::vector<size_t> colSizes(num_cols(), 0);
228 :
229 0 : for(size_t i_row = 0; i_row < num_rows(); ++i_row){
230 0 : for(size_t i_col = 0; i_col < num_cols(); ++i_col){
231 0 : strTable(i_row, i_col) = EntryToString(table, i_row, i_col);
232 0 : colSizes[i_col] = std::max(colSizes[i_col], strTable(i_row, i_col).size());
233 : }
234 : }
235 :
236 : size_t totalRowLength=0;
237 0 : for(size_t i_col = 0; i_col < num_cols(); ++i_col)
238 : {
239 0 : totalRowLength++;
240 0 : totalRowLength += colSizes[i_col] + 2;
241 : }
242 0 : totalRowLength++;
243 :
244 : // now print each row
245 0 : for(size_t i_row = 0; i_row < num_rows(); ++i_row)
246 : {
247 0 : if(get_row_sep(i_row) != 0x00 && get_row_sep(i_row) != ' ')
248 0 : os << repeat(get_row_sep(i_row), totalRowLength) << "\n";
249 0 : for(size_t i_col = 0; i_col < num_cols(); ++i_col)
250 : {
251 0 : os << get_col_sep(i_col);
252 0 : size_t l = colSizes[i_col] + 1;
253 0 : size_t s = strTable(i_row, i_col).size();
254 0 : os << " ";
255 0 : if(get_col_alignment(i_col) == 'r')
256 0 : os << std::setw(l) << std::right << strTable(i_row, i_col);
257 0 : else if(get_col_alignment(i_col) == 'l')
258 0 : os << std::setw(l) << std::left << strTable(i_row, i_col);
259 : else
260 0 : os << repeat(' ', (l-s)/2) << std::setw(l-(l-s)/2) << std::left << strTable(i_row, i_col);
261 : }
262 0 : os << get_col_sep(num_cols()) << std::endl;
263 : }
264 0 : if(get_row_sep(num_cols()) != 0x00 && get_row_sep(num_cols()) != ' ')
265 0 : os << repeat(get_row_sep(num_cols()), totalRowLength) << "\n";
266 0 : return os;
267 0 : }
268 :
269 :
270 :
271 :
272 : template <class T>
273 : inline
274 : std::string EntryToString(const Table<T>& table, size_t rowInd, size_t colInd)
275 : {
276 : std::stringstream ss;
277 : ss << table(rowInd, colInd);
278 : return ss.str();
279 : }
280 :
281 :
282 : inline
283 0 : std::string EntryToString(const Table<std::string>& table,
284 : size_t rowInd, size_t colInd)
285 : {
286 0 : return table(rowInd, colInd);
287 : }
288 :
289 : inline
290 : std::string EntryToString(const Table<std::stringstream>& table,
291 : size_t rowInd, size_t colInd)
292 : {
293 0 : return table(rowInd, colInd).str();
294 : }
295 :
296 : }// end of namespace
297 :
298 : #endif
|