rvm  1.11
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
strfmt.h
Go to the documentation of this file.
1 #ifndef __strfmt_h__
2 #define __strfmt_h__
3 
4 #include "asserts.h"
5 #include "types.h"
6 #include "estring.h"
7 #include "rmath.h"
8 
9 /** Given an integral number, return a string with the number formatted as a
10  human-readable machine-type size. (Ex: 10240 becomes "10Kb") */
11 template<class T>
12 std::string size_to_string(
13  T a_t,
14  const std::string& a_base_size_unit = "b",
15  uint16 a_width = 8,
16  uint16 a_precision = 1,
17  uint16 a_kilo = 1024
18  )
19 {
20  enum {
21  ones = 0,
22  kilo,
23  mega,
24  giga,
25  tera,
26  peta,
27  exa,
28  zetta,
29  yotta
30  };
31  const char* units[] = {
32  " ",
33  "K",
34  "M",
35  "G",
36  "T",
37  "P",
38  "E",
39  "Z",
40  "Y"
41  };
42  std::string es;
43  int resolution = ones;
44  std::string str;
45  safe_num<T> quotient = a_t;
46  safe_num<T> remainder = 0;
47  safe_num<T> rmul = 10;
48  safe_num<T> tmp;
49 
50  TRY_nomem(es = "Could not generate size-string: \"");
51  TRY_nomem(es += estring(a_t));
52  TRY_nomem(es += "\"");
53 
54  for (tmp = 1; tmp < a_precision; ++tmp) {
55  rmul *= 10;
56  }
57  while ((quotient >= a_kilo) && (resolution < yotta)) {
58  TRY(
59  tmp = quotient;
60  tmp *= rmul;
61  //
62  // *** NOT SURE ABOUT THIS:
63  // This involves a conversion from uint16 to T
64  // for safe_num<T>(a_kilo)
65  //
66  remainder = (tmp / safe_num<T>(a_kilo)) % rmul;
67  quotient /= a_kilo;
68  ,es);
69  resolution++;
70  }
71 
72  if (resolution > ones) {
73  TRY(
74  str += estring(quotient.value()).fmt_str(
75  a_width-(a_precision+1)-2,estring::right,' ','x'),
76  es);
77  TRY_nomem(str += ".");
78  TRY(
79  str += estring(remainder.value()).fmt_str(a_precision,estring::right,'0','x'),
80  es);
81  }
82  else {
83  TRY(
84  str += estring(quotient.value()).fmt_str(a_width-2,estring::right,' ','x'),
85  es);
86  }
87  TRY_nomem(str += units[resolution]);
88  TRY_nomem(str += a_base_size_unit);
89 
90  return(str);
91 }
92 
93 /** Given an integral number, return a string with the number formatted in a
94  generic, human-readable format. (Ex: 10240 becomes "10,240") */
95 template<class T>
96 std::string num_to_string(T a_t, uint16 a_width = 0)
97 {
98  std::string es;
99  std::string tstr;
100  estring str;
101  std::string::size_type n;
102 
103  TRY_nomem(tstr = estring(a_t));
104  TRY_nomem(es = "Could not generate num-string: \"");
105  TRY_nomem(es += tstr);
106  TRY_nomem(es += "\"");
107 
108  if (tstr.size() == 0) {
109  return(tstr);
110  }
111 
112  n = tstr.size();
113  while (n > 0) {
114  if (str.size() > 0) {
115  TRY_nomem(str = "," + str);
116  }
117  str = tstr[(n--)-1] + str; if (n == 0) break;
118  str = tstr[(n--)-1] + str; if (n == 0) break;
119  str = tstr[(n--)-1] + str;
120  }
121 
122  if (a_width == 0) {
123  return(str);
124  }
125  str.width(a_width);
126  str.align(estring::right);
127  TRY_nomem(tstr = str.fmt_str());
128 
129  return(tstr);
130 }
131 
132 /** Given an integral number, return a string with the number formated as a
133  number of machine-type size per second. (Ex: 10240 becomes "10Kb/s") */
134 template<class T>
136  T a_t,
137  const std::string& a_base_size_unit = "b",
138  const std::string& a_base_time_unit = "s",
139  uint16 a_width = 10,
140  uint16 a_precision = 1,
141  uint16 a_kilo = 1024
142  )
143 {
144  std::string str;
145 
146  TRY_nomem(
147  str = size_to_string(a_t, a_base_size_unit, a_width-2, a_precision, a_kilo)
148  );
149  TRY_nomem(str += "/");
150  TRY_nomem(str += a_base_time_unit);
151 
152  return(str);
153 }
154 
155 /** Given a count complete and a count total, calculate a percentage */
156 template<typename T>
157 std::string percent_string(const T& a_complete, const T& a_total)
158 {
159  safe_num<double> percent;
160  estring es;
161  estring estr;
162  std::string str;
163 
164  es = "Could not calculate percentage";
165  if (a_complete == static_cast<T>(0)) {
166  percent = static_cast<T>(0);
167  }
168  else if (a_total == static_cast<T>(0)) {
169  TRY_nomem(str = "??.?%");
170  return(str);
171  }
172  else {
173  TRY (
174  percent = static_cast<double>(a_complete);
175  percent *= 100;
176  percent /= static_cast<double>(a_total);
177  ,es);
178  }
179  estr.width(5);
180  estr.align(estring::right);
181  estr.fillchar(' ');
182  estr.precision(1);
183  estr = percent.value();
184  TRY_nomem(str = estr.fmt_str());
185  TRY_nomem(str += "%");
186 
187  return(str);
188 }
189 
190 #endif
Safely manipulate numbers without worryiung about over/underflow error.
Definition: rmath.h:281
Basic types definitions and templates.
An extended string class.
Definition: estring.h:52
Right-justified.
Definition: estring.h:66
const T value(void) const
Return the value.
Definition: rmath.h:311
std::string percent_string(const T &a_complete, const T &a_total)
Given a count complete and a count total, calculate a percentage.
Definition: strfmt.h:157
std::string num_to_string(T a_t, uint16 a_width=0)
Given an integral number, return a string with the number formatted in a generic, human-readable form...
Definition: strfmt.h:96
std::string throughput_to_string(T a_t, const std::string &a_base_size_unit="b", const std::string &a_base_time_unit="s", uint16 a_width=10, uint16 a_precision=1, uint16 a_kilo=1024)
Given an integral number, return a string with the number formated as a number of machine-type size p...
Definition: strfmt.h:135
#define TRY_nomem(code)
Definition: error.h:144
size_type precision(size_type a_p)
Set the precision used in converting to/from fractional types.
Definition: estring.cc:501
value_type fmt_str(void)
Generate a formatted string.
Definition: estring.cc:688
void fillchar(const char a_char)
Set the fill character used for padding both the left and right side of a formatted string...
Definition: estring.cc:662
#define TRY(code, es)
Definition: error.h:126
size_type width(const size_type a_l)
Set the width of a formatted string.
Definition: estring.cc:446
std::string size_to_string(T a_t, const std::string &a_base_size_unit="b", uint16 a_width=8, uint16 a_precision=1, uint16 a_kilo=1024)
Given an integral number, return a string with the number formatted as a human-readable machine-type ...
Definition: strfmt.h:12
alignment align(const alignment a_alignment)
Set the alignment used for formatted strings.
Definition: estring.cc:471