]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/TextTable.h
import ceph quincy 17.2.4
[ceph.git] / ceph / src / common / TextTable.h
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2012 Inktank Storage, Inc.
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15#ifndef TEXT_TABLE_H_
16#define TEXT_TABLE_H_
17
18#include <vector>
19#include <sstream>
11fdf7f2 20#include "include/ceph_assert.h"
7c673cae
FG
21
22/**
23 * TextTable:
24 * Manage tabular output of data. Caller defines heading of each column
25 * and alignment of heading and column data,
26 * then inserts rows of data including tuples of
27 * length (ncolumns) terminated by TextTable::endrow. When all rows
28 * are inserted, caller asks for output with ostream <<
29 * which sizes/pads/dumps the table to ostream.
30 *
31 * Columns autosize to largest heading or datum. One space is printed
32 * between columns.
33 */
34
35class TextTable {
36
37public:
38 enum Align {LEFT = 1, CENTER, RIGHT};
39
40private:
41 struct TextTableColumn {
42 std::string heading;
43 int width;
44 Align hd_align;
45 Align col_align;
46
47 TextTableColumn() {}
11fdf7f2 48 TextTableColumn(const std::string &h, int w, Align ha, Align ca) :
7c673cae
FG
49 heading(h), width(w), hd_align(ha), col_align(ca) { }
50 ~TextTableColumn() {}
51 };
52
53 std::vector<TextTableColumn> col; // column definitions
54 unsigned int curcol, currow; // col, row being inserted into
55 unsigned int indent; // indent width when rendering
9f95a23c 56 std::string column_separation = {" "};
7c673cae
FG
57
58protected:
59 std::vector<std::vector<std::string> > row; // row data array
60
61public:
62 TextTable(): curcol(0), currow(0), indent(0) {}
63 ~TextTable() {}
64
65 /**
66 * Define a column in the table.
67 *
68 * @param heading Column heading string (or "")
69 * @param hd_align Alignment for heading in column
70 * @param col_align Data alignment
71 *
72 * @note alignment is of type TextTable::Align; values are
73 * TextTable::LEFT, TextTable::CENTER, or TextTable::RIGHT
74 *
75 */
76 void define_column(const std::string& heading, Align hd_align,
77 Align col_align);
78
79 /**
80 * Set indent for table. Only affects table output.
81 *
82 * @param i Number of spaces to indent
83 */
84 void set_indent(int i) { indent = i; }
85
9f95a23c
TL
86 /**
87 * Set column separation
88 *
89 * @param s String to separate columns
90 */
91 void set_column_separation(const std::string& s) {
92 column_separation = s;
93 }
94
7c673cae
FG
95 /**
96 * Add item to table, perhaps on new row.
97 * table << val1 << val2 << TextTable::endrow;
98 *
99 * @param: value to output.
100 *
101 * @note: Numerics are output in decimal; strings are not truncated.
102 * Output formatting choice is limited to alignment in define_column().
103 *
104 * @return TextTable& for chaining.
105 */
106
107 template<typename T> TextTable& operator<<(const T& item)
108 {
109 if (row.size() < currow + 1)
110 row.resize(currow + 1);
111
112 /**
113 * col.size() is a good guess for how big row[currow] needs to be,
114 * so just expand it out now
115 */
116 if (row[currow].size() < col.size()) {
117 row[currow].resize(col.size());
118 }
119
120 // inserting more items than defined columns is a coding error
11fdf7f2 121 ceph_assert(curcol + 1 <= col.size());
7c673cae
FG
122
123 // get rendered width of item alone
124 std::ostringstream oss;
125 oss << item;
126 int width = oss.str().length();
127 oss.seekp(0);
128
129 // expand column width if necessary
130 if (width > col[curcol].width) {
131 col[curcol].width = width;
132 }
133
134 // now store the rendered item with its proper width
135 row[currow][curcol] = oss.str();
136
137 curcol++;
138 return *this;
139 }
140
141 /**
142 * Degenerate type/variable here is just to allow selection of the
143 * following operator<< for "<< TextTable::endrow"
144 */
145
146 struct endrow_t {};
11fdf7f2 147 static constexpr endrow_t endrow{};
7c673cae
FG
148
149 /**
150 * Implements TextTable::endrow
151 */
152
153 TextTable &operator<<(endrow_t)
154 {
155 curcol = 0;
156 currow++;
157 return *this;
158 }
159
160 /**
161 * Render table to ostream (i.e. cout << table)
162 */
163
164 friend std::ostream &operator<<(std::ostream &out, const TextTable &t);
165
166 /**
167 * clear: Reset everything in a TextTable except column defs
168 * resize cols to heading widths, clear indent
169 */
170
171 void clear();
172};
173
174#endif
175