STXXL  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
uint_types.h
Go to the documentation of this file.
1 /***************************************************************************
2  * include/stxxl/bits/common/uint_types.h
3  *
4  * Class representing a 40-bit or 48-bit unsigned integer encoded in five or
5  * six bytes.
6  *
7  * Part of the STXXL. See http://stxxl.sourceforge.net
8  *
9  * Copyright (C) 2013 Timo Bingmann <[email protected]>
10  *
11  * Distributed under the Boost Software License, Version 1.0.
12  * (See accompanying file LICENSE_1_0.txt or copy at
13  * http://www.boost.org/LICENSE_1_0.txt)
14  **************************************************************************/
15 
16 #ifndef STXXL_COMMON_UINT_TYPES_HEADER
17 #define STXXL_COMMON_UINT_TYPES_HEADER
18 
19 #include <stxxl/bits/config.h>
20 #include <stxxl/bits/namespace.h>
23 
24 #include <limits>
25 #include <ostream>
26 #include <cassert>
27 
29 
30 /*!
31  * \brief Construct an 40-bit or 48-bit unsigned integer stored in five or six
32  * bytes.
33  *
34  * The purpose of this class is to provide integers with smaller data storage
35  * footprints when more than 32-bit, but less than 64-bit indexes are
36  * needed. This is commonly the case for storing file offsets and indexes. Here
37  * smaller types currently suffice for files < 1 TiB or < 16 TiB.
38  *
39  * The class combines a 32-bit integer with a HighType (either 8-bit or 16-bit)
40  * to get a larger type. Only unsigned values are supported, which fits the
41  * general application of file offsets.
42  *
43  * Calculation in uint_pair are generally done by transforming everything to
44  * 64-bit data type, so that 64-bit register arithmetic can be used. The
45  * exception here is \b increment and \b decrement, which is done directly on
46  * the lower/higher part. Not all arithmetic operations are supported, patches
47  * welcome if you really need the operations.
48  */
49 #if STXXL_MSVC
50 #pragma pack(push, 1)
51 #endif
52 template <typename HighType>
53 class uint_pair
54 {
55 public:
56  //! lower part type, always 32-bit
57  typedef uint32 low_type;
58  //! higher part type, currently either 8-bit or 16-bit
59  typedef HighType high_type;
60 
61 private:
62  //! member containing lower significant integer value
64  //! member containing higher significant integer value
66 
67  //! return highest value storable in lower part, also used as a mask.
68  static low_type low_max()
69  {
71  }
72 
73  //! number of bits in the lower integer part, used a bit shift value.
74  static const int low_bits = 8 * sizeof(low_type);
75 
76  //! return highest value storable in higher part, also used as a mask.
78  {
80  }
81 
82  //! number of bits in the higher integer part, used a bit shift value.
83  static const int high_bits = 8 * sizeof(high_type);
84 
85 public:
86  //! number of binary digits (bits) in uint_pair
87  static const int digits = low_bits + high_bits;
88 
89  //! number of bytes in uint_pair
90  static const int bytes = sizeof(low_type) + sizeof(high_type);
91 
92  //! empty constructor, does not even initialize to zero!
93  inline uint_pair()
94  {
95  // compile-time assertions about size of low_type
96  STXXL_STATIC_ASSERT(8 * sizeof(low_type) == 32);
97  // compile-time assertions about size of our data structure, this tests
98  // packing of structures by the compiler
100  STXXL_STATIC_ASSERT(sizeof(uint_pair) == digits / 8);
102  }
103 
104  //! construct unit pair from lower and higher parts.
105  inline uint_pair(const low_type& l, const high_type& h)
106  : low(l), high(h)
107  { }
108 
109  //! copy constructor
110  inline uint_pair(const uint_pair& a)
111  : low(a.low), high(a.high)
112  { }
113 
114  //! const from a simple 32-bit unsigned integer
115  inline uint_pair(const uint32& a)
116  : low(a), high(0)
117  { }
118 
119  //! const from a simple 32-bit signed integer
120  inline uint_pair(const int32& a)
121  : low(a), high(0)
122  {
123  if (a >= 0)
124  low = a;
125  else
126  low = a, high = high_max();
127  }
128 
129  //! construct from an uint64 (unsigned long long)
130  inline uint_pair(const uint64& a)
131  : low(a & low_max()),
132  high((a >> low_bits) & high_max())
133  {
134  // check for overflow
135  assert((a >> (low_bits + high_bits)) == 0);
136  }
137 
138  //! return the number as an uint64 (unsigned long long)
139  inline uint64 ull() const
140  {
141  return ((uint64)high) << low_bits | (uint64)low;
142  }
143 
144  //! implicit cast to an unsigned long long
145  inline operator uint64 () const
146  {
147  return ull();
148  }
149 
150  //! return the number as a uint64
151  inline uint64 u64() const
152  {
153  return ((uint64)high) << low_bits | (uint64)low;
154  }
155 
156  //! prefix increment operator (directly manipulates the integer parts)
158  {
159  if (UNLIKELY(low == low_max()))
160  ++high, low = 0;
161  else
162  ++low;
163  return *this;
164  }
165 
166  //! prefix decrement operator (directly manipulates the integer parts)
168  {
169  if (UNLIKELY(low == 0))
170  --high, low = low_max();
171  else
172  --low;
173  return *this;
174  }
175 
176  //! addition operator (uses 64-bit arithmetic)
177  inline uint_pair& operator += (const uint_pair& b)
178  {
179  uint64 add = low + b.low;
180  low = add & low_max();
181  high += b.high + ((add >> low_bits) & high_max());
182  return *this;
183  }
184 
185  //! equality checking operator
186  inline bool operator == (const uint_pair& b) const
187  {
188  return (low == b.low) && (high == b.high);
189  }
190 
191  //! inequality checking operator
192  inline bool operator != (const uint_pair& b) const
193  {
194  return (low != b.low) || (high != b.high);
195  }
196 
197  //! less-than comparison operator
198  inline bool operator < (const uint_pair& b) const
199  {
200  return (high < b.high) || (high == b.high && low < b.low);
201  }
202 
203  //! less-or-equal comparison operator
204  inline bool operator <= (const uint_pair& b) const
205  {
206  return (high < b.high) || (high == b.high && low <= b.low);
207  }
208 
209  //! greater comparison operator
210  inline bool operator > (const uint_pair& b) const
211  {
212  return (high > b.high) || (high == b.high && low > b.low);
213  }
214 
215  //! greater-or-equal comparison operator
216  inline bool operator >= (const uint_pair& b) const
217  {
218  return (high > b.high) || (high == b.high && low >= b.low);
219  }
220 
221  //! make a uint_pair outputtable via iostreams, using unsigned long long.
222  friend std::ostream& operator << (std::ostream& os, const uint_pair& a)
223  {
224  return os << a.ull();
225  }
226 
227  //! return an uint_pair instance containing the smallest value possible
228  static uint_pair min()
229  {
232  }
233 
234  //! return an uint_pair instance containing the largest value possible
235  static uint_pair max()
236  {
239  }
240 }
241 #if STXXL_MSVC
242 ;
243 #pragma pack(pop)
244 #else
245 __attribute__ ((packed));
246 #endif
247 
248 //! Construct a 40-bit unsigned integer stored in five bytes.
250 
251 //! Construct a 48-bit unsigned integer stored in six bytes.
253 
255 
256 namespace std {
257 
258 //! template class providing some numeric_limits fields for uint_pair types.
259 template <typename HighType>
260 class numeric_limits<stxxl::uint_pair<HighType> >
261 {
262 public:
263  //! yes we have information about uint_pair
264  static const bool is_specialized = true;
265 
266  //! return an uint_pair instance containing the smallest value possible
268  { return stxxl::uint_pair<HighType>::min(); }
269 
270  //! return an uint_pair instance containing the largest value possible
272  { return stxxl::uint_pair<HighType>::max(); }
273 
274  //! return an uint_pair instance containing the smallest value possible
276  { return min(); }
277 
278  //! unit_pair types are unsigned
279  static const bool is_signed = false;
280 
281  //! uint_pair types are integers
282  static const bool is_integer = true;
283 
284  //! unit_pair types contain exact integers
285  static const bool is_exact = true;
286 
287  //! unit_pair radix is binary
288  static const int radix = 2;
289 
290  //! number of binary digits (bits) in uint_pair
292 
293  //! epsilon is zero
295  { return stxxl::uint_pair<HighType>(0, 0); }
296 
297  //! rounding error is zero
299  { return stxxl::uint_pair<HighType>(0, 0); }
300 
301  //! no exponent
302  static const int min_exponent = 0;
303 
304  //! no exponent
305  static const int min_exponent10 = 0;
306 
307  //! no exponent
308  static const int max_exponent = 0;
309 
310  //! no exponent
311  static const int max_exponent10 = 0;
312 
313  //! no infinity
314  static const bool has_infinity = false;
315 };
316 
317 } // namespace std
318 
319 #endif // !STXXL_COMMON_UINT_TYPES_HEADER
uint_pair< uint8 > uint40
Construct a 40-bit unsigned integer stored in five bytes.
Definition: uint_types.h:249
static const int high_bits
number of bits in the higher integer part, used a bit shift value.
Definition: uint_types.h:92
friend std::ostream & operator<<(std::ostream &os, const uint_pair &a)
make a uint_pair outputtable via iostreams, using unsigned long long.
Definition: uint_types.h:231
static const int bytes
number of bytes in uint_pair
Definition: uint_types.h:99
HighType high_type
higher part type, currently either 8-bit or 16-bit
Definition: uint_types.h:68
uint32 low_type
lower part type, always 32-bit
Definition: uint_types.h:66
Construct an 40-bit or 48-bit unsigned integer stored in five or six bytes.
Definition: uint_types.h:53
static uint_pair max()
return an uint_pair instance containing the largest value possible
Definition: uint_types.h:235
unsigned long long int uint64
Definition: types.h:41
static stxxl::uint_pair< HighType > max()
return an uint_pair instance containing the largest value possible
Definition: uint_types.h:271
uint_pair(const uint64 &a)
construct from an uint64 (unsigned long long)
Definition: uint_types.h:130
uint64 u64() const
return the number as a uint64
Definition: uint_types.h:151
uint_pair< uint16 > uint48
Construct a 48-bit unsigned integer stored in six bytes.
Definition: uint_types.h:252
static uint_pair min()
return an uint_pair instance containing the smallest value possible
Definition: uint_types.h:237
int int32
Definition: types.h:38
uint64 ull() const
return the number as an uint64 (unsigned long long)
Definition: uint_types.h:139
low_type low
member containing lower significant integer value
Definition: uint_types.h:63
static const int digits
number of binary digits (bits) in uint_pair
Definition: uint_types.h:96
uint_pair & operator++()
prefix increment operator (directly manipulates the integer parts)
Definition: uint_types.h:166
uint_pair(const low_type &l, const high_type &h)
construct unit pair from lower and higher parts.
Definition: uint_types.h:105
uint64 ull() const
return the number as an uint64 (unsigned long long)
Definition: uint_types.h:148
static stxxl::uint_pair< HighType > min()
return an uint_pair instance containing the smallest value possible
Definition: uint_types.h:267
uint32 low_type
lower part type, always 32-bit
Definition: uint_types.h:57
static low_type low_max()
return highest value storable in lower part, also used as a mask.
Definition: uint_types.h:77
static const stxxl::uint_pair< HighType > epsilon()
epsilon is zero
Definition: uint_types.h:294
uint_pair & operator+=(const uint_pair &b)
addition operator (uses 64-bit arithmetic)
Definition: uint_types.h:186
static uint_pair min()
return an uint_pair instance containing the smallest value possible
Definition: uint_types.h:228
unsigned int uint32
Definition: types.h:39
bool operator!=(const uint_pair &b) const
inequality checking operator
Definition: uint_types.h:201
static const stxxl::uint_pair< HighType > round_error()
rounding error is zero
Definition: uint_types.h:298
bool operator<=(const uint_pair &b) const
less-or-equal comparison operator
Definition: uint_types.h:213
static const int low_bits
number of bits in the lower integer part, used a bit shift value.
Definition: uint_types.h:83
bool operator>(const uint_pair &b) const
greater comparison operator
Definition: uint_types.h:219
low_type low
member containing lower significant integer value
Definition: uint_types.h:72
#define UNLIKELY(c)
Definition: utils.h:226
bool operator>=(const uint_pair &b) const
greater-or-equal comparison operator
Definition: uint_types.h:225
bool operator<(const uint_pair &b) const
less-than comparison operator
Definition: uint_types.h:207
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
static high_type high_max()
return highest value storable in higher part, also used as a mask.
Definition: uint_types.h:86
uint_pair & operator--()
prefix decrement operator (directly manipulates the integer parts)
Definition: uint_types.h:176
high_type high
member containing higher significant integer value
Definition: uint_types.h:74
static uint_pair max()
return an uint_pair instance containing the largest value possible
Definition: uint_types.h:244
#define STXXL_STATIC_ASSERT(x)
Definition: utils.h:49
static stxxl::uint_pair< HighType > lowest()
return an uint_pair instance containing the smallest value possible
Definition: uint_types.h:275
high_type high
member containing higher significant integer value
Definition: uint_types.h:65
uint_pair(const int32 &a)
const from a simple 32-bit signed integer
Definition: uint_types.h:120
uint_pair()
empty constructor, does not even initialize to zero!
Definition: uint_types.h:93
uint_pair()
empty constructor, does not even initialize to zero!
Definition: uint_types.h:102
HighType high_type
higher part type, currently either 8-bit or 16-bit
Definition: uint_types.h:59
bool operator==(const uint_pair &b) const
equality checking operator
Definition: uint_types.h:195
uint_pair(const uint_pair &a)
copy constructor
Definition: uint_types.h:110
#define STXXL_END_NAMESPACE
Definition: namespace.h:17
uint_pair(const uint32 &a)
const from a simple 32-bit unsigned integer
Definition: uint_types.h:115