libyui  3.4.2
FSize.h
1 /*
2  Copyright (C) 2000-2012 Novell, Inc
3  Copyright (C) 2018 SUSE LLC
4  This library is free software; you can redistribute it and/or modify
5  it under the terms of the GNU Lesser General Public License as
6  published by the Free Software Foundation; either version 2.1 of the
7  License, or (at your option) version 3.0 of the License. This library
8  is distributed in the hope that it will be useful, but WITHOUT ANY
9  WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
11  License for more details. You should have received a copy of the GNU
12  Lesser General Public License along with this library; if not, write
13  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
14  Floor, Boston, MA 02110-1301 USA
15 */
16 
17 
18 /*-/
19 
20  File: FSize.h
21 
22  Author: Michael Andres <ma@suse.de>
23  Maintainer: Michael Andres <ma@suse.de>
24 
25  Purpose: Store and operate on (file/package/partition) sizes.
26 
27 /-*/
28 #ifndef _FSize_h_
29 #define _FSize_h_
30 
31 #include <iosfwd>
32 #include <string>
33 
34 // arbitrary precision integer
35 #include <boost/multiprecision/cpp_int.hpp>
36 // generate additional operators via the boost templates
37 #include <boost/operators.hpp>
38 
39 //
40 // CLASS NAME : FSize
41 //
42 /**
43  * Store and operate on (file/package/partition) sizes.
44  **/
45 class FSize :
46  // generate > / * + - <= => !== operators
47  boost::ordered_field_operators<FSize>,
48  // generate postfix ++ --
49  boost::unit_steppable<FSize>
50  {
51 
52  public:
53 
54  /**
55  * The Units
56  **/
57  enum class Unit { B, K, M, G, T, P, E, Z, Y };
58 
59  private:
60 
61  /**
62  * The size (in bytes)
63  * @see https://www.boost.org/doc/libs/release/libs/multiprecision/doc/html/index.html
64  **/
65  boost::multiprecision::cpp_int _size;
66 
67  public:
68 
69  static const boost::multiprecision::cpp_int KB;
70  static const boost::multiprecision::cpp_int MB;
71  static const boost::multiprecision::cpp_int GB;
72  static const boost::multiprecision::cpp_int TB;
73  static const boost::multiprecision::cpp_int PB;
74  static const boost::multiprecision::cpp_int EB;
75  // these do not fit long long anymore!
76  static const boost::multiprecision::cpp_int ZB;
77  static const boost::multiprecision::cpp_int YB;
78 
79  /**
80  * Return ammount of bytes in Unit.
81  **/
82  static boost::multiprecision::cpp_int factor( const Unit unit_r ) {
83  switch ( unit_r ) {
84  case Unit::Y: return YB;
85  case Unit::Z: return ZB;
86  case Unit::E: return EB;
87  case Unit::P: return PB;
88  case Unit::T: return TB;
89  case Unit::G: return GB;
90  case Unit::M: return MB;
91  case Unit::K: return KB;
92  case Unit::B: break;
93  }
94  return 1;
95  }
96 
97  /**
98  * String representation of Unit.
99  **/
100  static const char * unit( const Unit unit_r ) {
101  switch ( unit_r ) {
102  case Unit::Y: return "YiB";
103  case Unit::Z: return "ZiB";
104  case Unit::E: return "EiB";
105  case Unit::P: return "PiB";
106  case Unit::T: return "TiB";
107  case Unit::G: return "GiB";
108  case Unit::M: return "MiB";
109  case Unit::K: return "KiB";
110  case Unit::B: break;
111  }
112  return "B";
113  }
114 
115  public:
116 
117  /**
118  * Construct from size in certain unit.
119  * E.g. <code>FSize( 1, FSize::Unit::K )<code> makes 1024 Byte.
120  **/
121  FSize( const boost::multiprecision::cpp_int &size_r = 0, const Unit unit_r = Unit::B)
122  : _size( boost::multiprecision::cpp_int(size_r) * factor( unit_r ) )
123  {}
124 
125  /**
126  * Construct from size in Byte.
127  * @param size_r the initial value
128  **/
129  FSize( double size_r )
130  : _size( size_r )
131  {}
132 
133  /**
134  Construct from string containing a number in given unit.
135  * @param sizeStr input string - must contain *only* numbers
136  * @param unit_r optional unit, bytes by default
137  * @throws std::runtime_error if the string contains any non numeric characters,
138  * even a trailing white space!
139  */
140  FSize( const std::string &sizeStr, const Unit unit_r = Unit::B );
141 
142  /**
143  * Conversions to native data types - only explicit as it might overflow
144  * If the value is out of range then the behavior depends on the boost version
145  * - 1.67 - the min/max values for the corresponding type are returned
146  * - 1.66 - returns just the lower bits
147  **/
148  explicit operator long long() const { return static_cast<long long>(_size); }
149  explicit operator int() const { return static_cast<int>(_size); }
150  explicit operator double() const { return static_cast<double>(_size); }
151 
152  operator boost::multiprecision::cpp_int() const { return _size; }
153  boost::multiprecision::cpp_int in_unit(const Unit unit_r) const { return _size / factor( unit_r ); }
154 
155  // unary minus
156  FSize operator-() const { return FSize(-_size); }
157  FSize & operator+=( const FSize &rhs ) { _size += boost::multiprecision::cpp_int(rhs); return *this; }
158  FSize & operator-=( const FSize &rhs ) { _size -= boost::multiprecision::cpp_int(rhs); return *this; }
159  FSize & operator*=( const FSize &rhs ) { _size *= boost::multiprecision::cpp_int(rhs); return *this; }
160  FSize & operator/=( const FSize &rhs ) { _size /= boost::multiprecision::cpp_int(rhs); return *this; }
161 
162  bool operator<( const FSize &rhs ) const { return _size < boost::multiprecision::cpp_int(rhs); }
163  bool operator==( const FSize &rhs ) const { return _size == boost::multiprecision::cpp_int(rhs); }
164 
165  // ++operator (the prefix variant)
166  FSize & operator++() { _size += 1; return *this; }
167  // --operator (the prefix variant)
168  FSize & operator--() { _size -= 1; return *this; }
169 
170  /**
171  * Adjust size to multiple of <code>blocksize_r</code>
172  **/
173  FSize & fillBlock( FSize blocksize_r = boost::multiprecision::cpp_int(KB) );
174 
175  /**
176  * Return a new size adjusted to multiple of <code>blocksize_r</code>
177  **/
178  FSize fullBlock( FSize blocksize_r = boost::multiprecision::cpp_int(KB) ) const
179  {
180  FSize ret( _size );
181  return ret.fillBlock( blocksize_r );
182  }
183 
184  /**
185  * Return the best unit for string representation.
186  **/
187  Unit bestUnit() const;
188 
189  /**
190  * Used as precision argument to form(), the 'best' precision according to
191  * Unist is chosen.
192  **/
193  static const unsigned bestPrec = (unsigned)-1;
194 
195  /**
196  * Return string representation in given Unit. Parameter <code>fw</code> and
197  * <code>prec</code> denote field width and precision as in a "%*.*f" printf
198  * format string. Avalue of <code>bestPrec</code> automatically picks an
199  * appropriate precision depending on the unit.
200  * If <code>showunit</code> ist true, the string representaion
201  * of Unit is <em>appended<em> separated by a single blank.
202  *
203  * If Unit is <b>B</b>yte, precision is set to zero.
204  **/
205  std::string form( const Unit unit_r, unsigned fw = 0, unsigned prec = bestPrec, const bool showunit = true ) const;
206 
207  /**
208  * Return string representation in bestUnit.
209  **/
210  std::string form( unsigned fw = 0, unsigned prec = bestPrec, const bool showunit = true ) const {
211  return form( bestUnit(), fw, prec, showunit );
212  }
213 
214  /**
215  * Default string representation (precision 1 and unit appended).
216  **/
217  std::string asString() const;
218 };
219 
220 // stream operators
221 std::ostream& operator<<(std::ostream &ostr, const FSize&);
222 std::ostream& operator<<(std::ostream &ostr, const FSize::Unit);
223 
224 #endif // _FSize_h_
static const char * unit(const Unit unit_r)
String representation of Unit.
Definition: FSize.h:100
FSize(double size_r)
Construct from size in Byte.
Definition: FSize.h:129
std::string asString() const
Default string representation (precision 1 and unit appended).
Definition: FSize.cc:156
std::string form(unsigned fw=0, unsigned prec=bestPrec, const bool showunit=true) const
Return string representation in bestUnit.
Definition: FSize.h:210
FSize fullBlock(FSize blocksize_r=boost::multiprecision::cpp_int(KB)) const
Return a new size adjusted to multiple of blocksize_r
Definition: FSize.h:178
Unit
The Units.
Definition: FSize.h:57
FSize(const boost::multiprecision::cpp_int &size_r=0, const Unit unit_r=Unit::B)
Construct from size in certain unit.
Definition: FSize.h:121
Store and operate on (file/package/partition) sizes.
Definition: FSize.h:45
static boost::multiprecision::cpp_int factor(const Unit unit_r)
Return ammount of bytes in Unit.
Definition: FSize.h:82
static const unsigned bestPrec
Used as precision argument to form(), the &#39;best&#39; precision according to Unist is chosen.
Definition: FSize.h:193
FSize & fillBlock(FSize blocksize_r=boost::multiprecision::cpp_int(KB))
Adjust size to multiple of blocksize_r
Definition: FSize.cc:62
std::string form(const Unit unit_r, unsigned fw=0, unsigned prec=bestPrec, const bool showunit=true) const
Return string representation in given Unit.
Definition: FSize.cc:111
Unit bestUnit() const
Return the best unit for string representation.
Definition: FSize.cc:82