gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-2191-ga4742ac
a Global And Modular Bsm Inference Tool
table_formatter.hpp
Go to the documentation of this file.
1 // GAMBIT: Global and Modular BSM Inference Tool
2 // *********************************************
18 
19 /**********************************************************************************
20  * The table formatter class will formatt a table for you to fit the *
21  * screen as best as it can. Here is an example of its use: *
22  * *
23  * This will declare a 3 column table with each column title being *
24  * "file", "locate", "status": *
25  * *
26  * table_formatter table("file", "locate", "status"); *
27  * *
28  * If you add another line to the column titles, you can by: *
29  * *
30  * table.new_titles("(name)", "(/home)", "[ok/not ok]"); *
31  * *
32  * Just in case something bad happens, the formatter will make *
33  * the column widths equal to its default values which you can set by: *
34  * *
35  * table.default_widths(10, 20, 5); *
36  * *
37  * And if you want to capitalize the titles, do *
38  * *
39  * table.capitalize_title(); *
40  * *
41  * Or table.capitalize_title(0) for a specific line number in the title *
42  * *
43  * Also, you may want to add a padding space between the columns like this: *
44  * *
45  * table.padding(1); *
46  * *
47  * To fill the table you just do: *
48  * *
49  * table << "cookie" << "/cookie" << "OK"; *
50  * table << "cookie2" << "/cookie2" << "NOT OK"; *
51  * *
52  * If you want to change the "OK" to green, you can either do: *
53  * *
54  * table.green(0, 2); // (row, column) *
55  * *
56  * or you can do: *
57  * *
58  * table << "cookie" << "/cookie"; *
59  * table.green() << "OK"; *
60  * *
61  * The same goes or red(), yellow(), bold(), underline() or reset() *
62  * to reset the values. *
63  * *
64  * if you want to change the column justification, do *
65  * *
66  * table.center_justify(2); // no value will default to the current column *
67  * *
68  * same is true for left_justify (the default) and right_justify. And if you *
69  * don't want the extra newline after a row: *
70  * *
71  * table.no_newline(2); // again defaults to current row *
72  * *
73  * This can be undone with table.newline(2). *
74  * *
75  * To access a specific element, do: *
76  * *
77  * table[1][1] = "/cookie/2"; *
78  * *
79  * And the current row/column to be entered are given by the member functions *
80  * row_pos() and col_pos(). Also, new_row(int N = 1) adds N rows. *
81  * *
82  * Now, if you want to allow lines to be wrapped within each column, set a *
83  * minimum length for each column to be wrapped: *
84  * *
85  * table.min_widths(5, 5, 2); *
86  * *
87  * and each column will be wrapped down to this minimum width. You can undo *
88  * this by either setting the min_widths to be -1 or by *
89  * *
90  * table.wrap_around(false); *
91  * *
92  * After you're finished, you can output the formatted string with: *
93  * *
94  * std::string output = table.str(); *
95  * *
96  **********************************************************************************/
97 
98 #ifndef __TABLE_FORMATTER__
99 #define __TABLE_FORMATTER__
100 
101 #include <cstdlib>
102 #include <sstream>
103 #include <iomanip>
104 #include <map>
105 #include <utility>
106 #include <cctype>
108 
109 namespace Gambit
110 {
111  /*************************************/
112  /****** class to format lists ********/
113  /*************************************/
114 
116  {
117  private:
118  const int col_num;
119  int col;
120  int row;
121  int pad;
122  bool wrap;
123  bool top;
124  bool bottom;
125  std::vector<int> defaultWidths;
126  std::vector<int> minWidths;
127  std::vector<std::vector<std::string>> data;
128  std::vector<std::vector<std::string>> titles;
129  std::map<std::pair<int, int>, unsigned char> flags;
130  std::vector<unsigned char> row_flags;
131  std::vector<unsigned char> col_flags;
132 
133  template <typename U>
134  inline void enter_vec(std::vector<U> &){}
135 
136  template<typename U, typename V, typename... T>
137  void enter_vec (std::vector<U> &vec, const V &str, const T&... params)
138  {
139  vec.push_back(str);
140  enter_vec(vec, params...);
141  }
142 
143  public:
144  static const unsigned char RESET = 0x00;
145  static const unsigned char RED = 0x01;
146  static const unsigned char GREEN = 0x02;
147  static const unsigned char YELLOW = 0x04;
148  static const unsigned char COLOR = 0x07;
149  static const unsigned char BOLD = 0x80;
150  static const unsigned char JUST_RIGHT = 0x10;
151  static const unsigned char JUST_CENTER = 0x20;
152  static const unsigned char JUST = 0x30;
153  static const unsigned char UNDERLINE = 0x40;
154  static const unsigned char WRAP = 0x80;
155 
156  template <typename... T>
157  table_formatter(const T& ...params) : col_num(sizeof...(T)), col(0), row(0), pad(0), wrap(false), top(false), bottom(false), defaultWidths(col_num, 25), minWidths(col_num, -1), titles(1), row_flags(1, 0x00), col_flags(sizeof...(T), 0x00)
158  {
159  enter_vec(titles[0], params...);
160  }
161 
162  template<typename... T>
163  void new_titles(const T&... in)
164  {
165  if (sizeof...(T) == col_num)
166  {
167  std::vector<std::string> temp;
168  enter_vec(temp, in...);
169  titles.push_back(temp);
170  }
171  }
172 
173  template<typename... T>
174  void default_widths(const T&... in)
175  {
176  if (sizeof...(T) == col_num)
177  {
178  std::vector<int> temp;
179  enter_vec(temp, in...);
180  defaultWidths = temp;
181  }
182  }
183 
184  template<typename... T>
185  void min_widths(const T&... in)
186  {
187  if (sizeof...(T) == col_num)
188  {
189  wrap = true;
190  std::vector<int> temp;
191  enter_vec(temp, in...);
192  minWidths = temp;
193  }
194  }
195 
196  inline void padding(int p) {pad = p;}
197  inline void wrap_around(bool b) {wrap = b;}
198  inline void top_line(bool b){top = b;}
199  inline void bottom_line(bool b){bottom = b;}
200 
201  inline void capitalize_title(int i)
202  {
203  for (auto it = titles[i].begin(), end = titles[i].end(); it != end; ++it)
204  {
205  for(auto s_it = it->begin(), s_end = it->end(); s_it != s_end; ++s_it)
206  {
207  *s_it = std::toupper(*s_it);
208  }
209  }
210  }
211 
212  inline void capitalize_title()
213  {
214  for (auto it = titles.begin(), end = titles.end(); it != end; ++it)
215  {
216  for (auto t_it = it->begin(), t_end = it->end(); t_it != t_end; ++t_it)
217  {
218  for(auto s_it = t_it->begin(), s_end = t_it->end(); s_it != s_end; ++s_it)
219  {
220  *s_it = std::toupper(*s_it);
221  }
222  }
223  }
224  }
225 
226  inline int rows() const {return data.size();}
227  inline int cols() const {return col_num;}
228  inline int row_pos() const {return row;}
229  inline int col_pos() const {return col;}
230 
231  inline table_formatter &new_row(int n = 1)
232  {
233  for (int i = 0; i < n; i++)
234  {
235  data.push_back(std::vector<std::string>(col_num));
236  row_flags.push_back(0x00);
237  }
238 
239  col = 0;
240  row += n;
241 
242  return *this;
243  }
244 
245  template<typename T>
246  inline table_formatter &operator << (const T &in)
247  {
248  std::stringstream ss;
249  ss << in;
250  if (col == 0)
251  {
252  data.push_back(std::vector<std::string>(col_num));
253  row_flags.push_back(0x00);
254  }
255  data[row][col] = ss.str();
256  col++;
257  if (col == col_num)
258  {
259  col = 0;
260  row++;
261  }
262 
263  return *this;
264  }
265 
266  inline table_formatter& reset_pt_flag(const unsigned char flag, int i, int j)
267  {
268  std::pair<int, int> key(i, j);
269  flags[key] = flag;
270 
271  return *this;
272  }
273 
274  inline table_formatter& reset_row_flag(const unsigned char flag, int i)
275  {
276  if (i < (int)row_flags.size())
277  row_flags[i] = flag;
278 
279  return *this;
280  }
281 
282  inline table_formatter& reset_col_flag(const unsigned char flag, int i)
283  {
284  if (i < (int)col_flags.size())
285  col_flags[i] = flag;
286 
287  return *this;
288  }
289 
290 
291  inline table_formatter& set_pt_flag(const unsigned char flag, int i, int j)
292  {
293  std::pair<int, int> key(i, j);
294  if (flags.find(key) == flags.end())
295  {
296  flags[key] = flag;
297  }
298  else
299  {
300  if (bool(flags[key] & COLOR) && bool(flag & COLOR))
301  {
302  flags[key] &= ~COLOR;
303  }
304  if (bool(flags[key] & JUST) && bool(flag & JUST))
305  {
306  flags[key] &= ~JUST;
307  }
308  flags[key] |= flag;
309  }
310 
311  return *this;
312  }
313 
314  inline table_formatter& set_row_flag(const unsigned char flag, int i)
315  {
316  if (i < (int)row_flags.size())
317  row_flags[i] |= flag;
318 
319  return *this;
320  }
321 
322  inline table_formatter& set_col_flag(const unsigned char flag, int i)
323  {
324  if (i < (int)col_flags.size())
325  {
326  if (bool(col_flags[i] & JUST) && bool(flag & JUST))
327  {
328  col_flags[i] &= ~JUST;
329  }
330 
331  col_flags[i] |= flag;
332  }
333 
334  return *this;
335  }
336 
337  inline table_formatter& reset(int i=-1, int j=-1)
338  {
339  return reset_pt_flag(RESET, (i == -1 ? row : i) , (j == -1 ? col : j));
340  }
341 
342  inline table_formatter& red(int i=-1, int j=-1)
343  {
344  return set_pt_flag(RED, (i == -1 ? row : i) , (j == -1 ? col : j));
345  }
346 
347  inline table_formatter& green(int i=-1, int j=-1)
348  {
349  return set_pt_flag(GREEN, (i == -1 ? row : i) , (j == -1 ? col : j));
350  }
351 
352  inline table_formatter& yellow(int i=-1, int j=-1)
353  {
354  return set_pt_flag(YELLOW, (i == -1 ? row : i) , (j == -1 ? col : j));
355  }
356 
357  inline table_formatter& bold(int i=-1, int j=-1)
358  {
359  return set_pt_flag(BOLD, (i == -1 ? row : i) , (j == -1 ? col : j));
360  }
361 
362  inline table_formatter& underline(int i=-1, int j=-1)
363  {
364  return set_pt_flag(UNDERLINE, (i == -1 ? row : i) , (j == -1 ? col : j));
365  }
366 
367  inline table_formatter& right_justify(int j=-1)
368  {
369  return set_col_flag(JUST_RIGHT, (j == -1 ? col : j));
370  }
371 
372  inline table_formatter& center_justify(int j=-1)
373  {
374  return set_col_flag(JUST_CENTER, (j == -1 ? col : j));
375  }
376 
377  inline table_formatter& left_justify(int j=-1)
378  {
379  return reset_col_flag(RESET, (j == -1 ? col : j));
380  }
381 
382  inline table_formatter& no_newline(int j=-1)
383  {
384  return set_row_flag(WRAP, (j == -1 ? row : j));
385  }
386 
387  inline table_formatter& newline(int j=-1)
388  {
389  return reset_row_flag(RESET, (j == -1 ? row : j));
390  }
391 
392  inline std::vector<std::string> &operator[](int i)
393  {
394  return data[i];
395  }
396 
397  std::string str();
398  };
399 
400 }
401 
402 #endif
std::map< std::pair< int, int >, unsigned char > flags
table_formatter & green(int i=-1, int j=-1)
table_formatter & red(int i=-1, int j=-1)
table_formatter & reset_row_flag(const unsigned char flag, int i)
table_formatter & right_justify(int j=-1)
void new_titles(const T &... in)
table_formatter & reset_col_flag(const unsigned char flag, int i)
table_formatter & center_justify(int j=-1)
table_formatter & left_justify(int j=-1)
table_formatter & operator<<(const T &in)
static const unsigned char UNDERLINE
START_MODEL b
Definition: demo.hpp:270
static const unsigned char GREEN
table_formatter & newline(int j=-1)
table_formatter & yellow(int i=-1, int j=-1)
static const unsigned char JUST_CENTER
table_formatter & no_newline(int j=-1)
void min_widths(const T &... in)
table_formatter & underline(int i=-1, int j=-1)
table_formatter & set_col_flag(const unsigned char flag, int i)
std::vector< int > defaultWidths
table_formatter & reset(int i=-1, int j=-1)
static const unsigned char BOLD
std::vector< std::string > & operator[](int i)
table_formatter & set_pt_flag(const unsigned char flag, int i, int j)
static const unsigned char JUST_RIGHT
static const unsigned char RED
std::vector< std::vector< std::string > > data
Variadic utilty functions.
void enter_vec(std::vector< U > &vec, const V &str, const T &... params)
std::string str
Shorthand for a standard string.
Definition: Analysis.hpp:35
void default_widths(const T &... in)
table_formatter & reset_pt_flag(const unsigned char flag, int i, int j)
std::vector< int > minWidths
std::vector< unsigned char > col_flags
static const unsigned char WRAP
std::vector< unsigned char > row_flags
table_formatter & new_row(int n=1)
static const unsigned char JUST
void enter_vec(std::vector< U > &)
static const unsigned char COLOR
static const unsigned char YELLOW
std::vector< T > vec(std::vector< T > vector)
Definition: daFunk.hpp:142
std::vector< std::vector< std::string > > titles
table_formatter(const T &...params)
table_formatter & bold(int i=-1, int j=-1)
static const unsigned char RESET
TODO: see if we can use this one:
Definition: Analysis.hpp:33
table_formatter & set_row_flag(const unsigned char flag, int i)