Skip to content

Commit e7b3e83

Browse files
Merge pull request #4 from Oradle/dev
Added possibility to add new column, row, or assign a table. Optimized some algorithm
2 parents f38880f + 6563cee commit e7b3e83

1 file changed

Lines changed: 131 additions & 65 deletions

File tree

CppConsoleTable.hpp

Lines changed: 131 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
2-
========================= Cpp Console Table
3-
| Cpp | Console | Table | version 1.0.0
4-
========================= https://github.com/Oradle/CppConsoleTable
2+
========================= Cpp Console Table
3+
| Cpp | Console | Table | version 1.2.0
4+
========================= https://github.com/Oradle/CppConsoleTable
55
66
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
77
Copyright (c) 2017 Oradle
@@ -35,13 +35,19 @@ SOFTWARE.
3535
#include <iomanip>
3636
#include <algorithm>
3737
#include <vector>
38+
#include <type_traits>
3839

3940
namespace samilton {
4041
// force declaration
4142
class ConsoleTable;
43+
class ConsoleRow;
4244

4345
class ConsoleString {
4446
public:
47+
ConsoleString(ConsoleRow *parent) {
48+
_parent = parent;
49+
}
50+
4551
ConsoleString &operator=(const std::string &val) {
4652
_str = val;
4753
return *this;
@@ -52,22 +58,8 @@ namespace samilton {
5258
return *this;
5359
}
5460

55-
ConsoleString &operator=(const long &val) {
56-
_str = std::to_string(val);
57-
return *this;
58-
}
59-
60-
ConsoleString &operator=(const int &val) {
61-
_str = std::to_string(val);
62-
return *this;
63-
}
64-
65-
ConsoleString &operator=(const double &val) {
66-
_str = std::to_string(val);
67-
return *this;
68-
}
69-
70-
ConsoleString &operator=(const float &val) {
61+
template<class T, class = typename std::enable_if<std::is_arithmetic<T>::value>::type>
62+
ConsoleString &operator=(const T &val) {
7163
_str = std::to_string(val);
7264
return *this;
7365
}
@@ -83,29 +75,28 @@ namespace samilton {
8375
private:
8476
friend std::ostream &operator<<(std::ostream &stream, ConsoleTable &table);
8577

78+
ConsoleRow *_parent;
8679
std::string _str;
8780
};
8881

8982
class ConsoleRow {
9083
public:
84+
ConsoleRow(ConsoleTable *parent) {
85+
_parent = parent;
86+
}
87+
9188
~ConsoleRow() {
9289
for (auto &element : _rowData) {
9390
delete element.second;
9491
}
92+
_rowData.clear();
9593
}
9694

97-
ConsoleString &operator[](const size_t &column) {
98-
try {
99-
return *_rowData.at(column);
100-
}
101-
catch (...) {
102-
_rowData[column] = new ConsoleString;
103-
return *_rowData[column];
104-
}
105-
}
95+
ConsoleString &operator[](const size_t column);
10696
private:
10797
friend std::ostream &operator<<(std::ostream &stream, ConsoleTable &table);
10898

99+
ConsoleTable *_parent;
109100
std::map<size_t, ConsoleString*> _rowData;
110101
};
111102

@@ -126,34 +117,92 @@ namespace samilton {
126117

127118
ConsoleTable() {
128119
_alignment = Alignment::left;
129-
_leftIndent = 0;
130-
_rightIndent = 0;
120+
_leftIndent = _rightIndent = _rowSize = _columnSize = 0;
131121
}
132122

133123
ConsoleTable(const Alignment &alignment) {
134124
_alignment = alignment;
135-
_leftIndent = 0;
136-
_rightIndent = 0;
125+
_leftIndent = _rightIndent = _rowSize = _columnSize = 0;
137126
}
138127

139128
ConsoleTable(const size_t &leftIndent, const size_t &rightIndent, const Alignment &alignment = Alignment::left) {
140129
_leftIndent = leftIndent;
141130
_rightIndent = rightIndent;
142131
_alignment = alignment;
132+
_rowSize = _columnSize = 0;
143133
}
144134

145135
~ConsoleTable() {
136+
clear();
137+
}
138+
139+
template<class T,
140+
class = typename std::enable_if<std::is_arithmetic<T>::value ||
141+
std::is_same<std::string, T>::value ||
142+
std::is_same<char*, T>::value>::type>
143+
void addRow(const std::vector<T> &row) {
144+
const size_t tmp = _rowSize;
145+
for (size_t i = 0; i < row.size(); i++) {
146+
(*this)[tmp][i] = row[i];
147+
}
148+
}
149+
150+
template<class T,
151+
class = typename std::enable_if<std::is_arithmetic<T>::value ||
152+
std::is_same<std::string, T>::value>::type>
153+
void addRow(const T *row, const size_t &size) {
154+
const size_t tmp = _rowSize;
155+
for (size_t i = 0; i < size; i++) {
156+
(*this)[tmp][i] = row[i];
157+
}
158+
}
159+
160+
template<class T,
161+
class = typename std::enable_if<std::is_arithmetic<T>::value ||
162+
std::is_same<std::string, T>::value ||
163+
std::is_same<char*, T>::value>::type>
164+
void addColumn(const std::vector<T> &column) {
165+
const size_t tmp = _columnSize;
166+
for (size_t i = 0; i < column.size(); i++) {
167+
(*this)[i][tmp] = column[i];
168+
}
169+
}
170+
171+
template<class T,
172+
class = typename std::enable_if<std::is_arithmetic<T>::value ||
173+
std::is_same<std::string, T>::value>::type>
174+
void addColumn(const T *column, const size_t &size) {
175+
const size_t tmp = _columnSize;
176+
for (size_t i = 0; i < size; i++) {
177+
(*this)[i][tmp] = column[i];
178+
}
179+
}
180+
181+
template<class T,
182+
class = typename std::enable_if<std::is_arithmetic<T>::value ||
183+
std::is_same<std::string, T>::value ||
184+
std::is_same<char*, T>::value>::type>
185+
void assign(const std::vector<std::vector<T>> &table) {
186+
clear();
187+
for (size_t i = 0; i < table.size(); i++)
188+
for (size_t j = 0; j < table[i].size(); j++)
189+
(*this)[i][j] = table[i][j];
190+
}
191+
192+
void clear() {
146193
for (auto &element : _tableData) {
147194
delete element.second;
148195
}
196+
197+
_tableData.clear();
198+
_columnSize = _rowSize = 0;
149199
}
150200

151201
void setAlignment(const Alignment &alignment) {
152202
_alignment = alignment;
153203
}
154204

155-
void setIndent(const size_t &leftIndent, const size_t &rightIndent)
156-
{
205+
void setIndent(const size_t &leftIndent, const size_t &rightIndent) {
157206
_leftIndent = leftIndent;
158207
_rightIndent = rightIndent;
159208
}
@@ -162,18 +211,21 @@ namespace samilton {
162211
_chars = chars;
163212
}
164213

165-
ConsoleRow &operator[](const size_t &row) {
166-
try {
167-
return *_tableData.at(row);
168-
}
169-
catch (...) {
170-
_tableData[row] = new ConsoleRow;
171-
return *_tableData[row];
172-
}
214+
template<class T,
215+
class = typename std::enable_if<std::is_arithmetic<T>::value ||
216+
std::is_same<std::string, T>::value ||
217+
std::is_same<char*, T>::value>::type>
218+
ConsoleTable &operator=(const std::vector<std::vector<T>> &table) {
219+
assign(table);
220+
return *this;
173221
}
174222

223+
ConsoleRow &operator[](const size_t row);
224+
175225
friend std::ostream &operator<<(std::ostream &stream, ConsoleTable &table);
176226
private:
227+
friend ConsoleString &ConsoleRow::operator[](const size_t column);
228+
177229
void _fillStreamByChar(std::ostream &stream, const char &fillChar, const size_t &lenght) {
178230
if (lenght > 0)
179231
stream << std::setfill(fillChar) << std::setw(lenght);
@@ -188,29 +240,43 @@ namespace samilton {
188240
std::map<size_t, ConsoleRow*> _tableData;
189241
Alignment _alignment;
190242
size_t _leftIndent, _rightIndent;
243+
size_t _rowSize, _columnSize;
191244
};
192245

246+
inline ConsoleRow &ConsoleTable::operator[](const size_t row){
247+
try {
248+
return *_tableData.at(row);
249+
}
250+
catch (...) {
251+
_rowSize = std::max(_rowSize, row + 1);
252+
253+
_tableData[row] = new ConsoleRow(this);
254+
return *_tableData[row];
255+
}
256+
}
257+
258+
inline ConsoleString &ConsoleRow::operator[](const size_t column) {
259+
try {
260+
return *_rowData.at(column);
261+
}
262+
catch (...) {
263+
_parent->_columnSize = std::max(_parent->_columnSize, column + 1);
264+
265+
_rowData[column] = new ConsoleString(this);
266+
return *_rowData[column];
267+
}
268+
}
269+
193270
inline std::ostream &operator<<(std::ostream &stream, ConsoleTable &table) {
194271
// Return if table is empty
195272
if (table._tableData.size() == 0)
196273
return stream;
197-
198-
// Calculation row and column
199-
size_t row = 0;
200-
size_t column = 0;
201-
for (auto &i : table._tableData) {
202-
row = std::max(row, i.first);
203-
for (auto &j : i.second->_rowData)
204-
column = std::max(column, j.first);
205-
}
206-
row++;
207-
column++;
208-
274+
209275
// Calculation width of every column
210276
std::vector<size_t> columnWidth;
211-
for (size_t i = 0; i < column; i++) {
277+
for (size_t i = 0; i < table._columnSize; i++) {
212278
size_t tmp = 1;
213-
for (size_t j = 0; j < row; j++) {
279+
for (size_t j = 0; j < table._rowSize; j++) {
214280
if (table._tableData[j] != nullptr && table._tableData[j]->_rowData[i] != nullptr) {
215281
tmp = std::max(tmp, table._tableData[j]->_rowData[i]->_str.size());
216282
}
@@ -222,16 +288,16 @@ namespace samilton {
222288
stream << std::right << table._chars.topLeft;
223289
table._fillStreamByChar(stream, table._chars.topDownSimple, columnWidth[0] + 1 + table._leftIndent + table._rightIndent);
224290

225-
if (column != 1) {
226-
for (size_t i = 1; i < column; i++) {
291+
if (table._columnSize != 1) {
292+
for (size_t i = 1; i < table._columnSize; i++) {
227293
stream << table._chars.topSeparation << std::setw(columnWidth[i] + 1 + table._leftIndent + table._rightIndent);
228294
}
229295
}
230296
stream << table._chars.topRight << std::endl;
231297

232298
// Elements and middle borders
233-
for (size_t i = 0; i < row; i++) {
234-
for (size_t j = 0; j < column; j++) {
299+
for (size_t i = 0; i < table._rowSize; i++) {
300+
for (size_t j = 0; j < table._columnSize; j++) {
235301
if (table._tableData[i] != nullptr && table._tableData[i]->_rowData[j] != nullptr) {
236302
if (table._alignment == ConsoleTable::Alignment::centre) {
237303
const size_t tmp = columnWidth[j] - table._tableData[i]->_rowData[j]->_str.size();
@@ -279,12 +345,12 @@ namespace samilton {
279345
stream << std::right << table._chars.leftRightSimple << std::endl;
280346

281347
// Down border
282-
if (i == row - 1) {
348+
if (i == table._rowSize - 1) {
283349
stream << table._chars.downLeft;
284350
table._fillStreamByChar(stream, table._chars.topDownSimple, columnWidth[0] + 1 + table._leftIndent + table._rightIndent);
285351

286-
if (column != 1) {
287-
for (size_t j = 1; j < column; j++) {
352+
if (table._columnSize != 1) {
353+
for (size_t j = 1; j < table._columnSize; j++) {
288354
stream << table._chars.downSeparation << std::setw(columnWidth[j] + 1 + table._leftIndent + table._rightIndent);
289355
}
290356
}
@@ -294,8 +360,8 @@ namespace samilton {
294360
stream << table._chars.leftSeparation;
295361
table._fillStreamByChar(stream, table._chars.topDownSimple, columnWidth[0] + 1 + table._leftIndent + table._rightIndent);
296362

297-
if (column != 1) {
298-
for (size_t j = 1; j < column; j++) {
363+
if (table._columnSize != 1) {
364+
for (size_t j = 1; j < table._columnSize; j++) {
299365
stream << table._chars.centreSeparation << std::setw(columnWidth[j] + 1 + table._leftIndent + table._rightIndent);
300366
}
301367
}

0 commit comments

Comments
 (0)