tudocomp
– The TU Dortmund Compression Framework
IntPtr.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <cstring>
7 #include <fstream>
8 #include <iomanip>
9 #include <iostream>
10 #include <iterator>
11 #include <memory>
12 #include <sstream>
13 #include <string>
14 #include <type_traits>
15 #include <utility>
16 #include <climits>
17 
18 #include <tudocomp/ds/IntRepr.hpp>
19 #include <tudocomp/ds/uint_t.hpp>
22 
23 #include <sdsl/bits.hpp>
24 #include <glog/logging.h>
25 
27 
28 namespace tdc {
29  namespace int_vector {
30  template<class T>
31  class IntRef;
32  template<class T>
33  class ConstIntRef;
34  template<class T>
35  class IntPtr;
36  template<class T>
37  class ConstIntPtr;
38  }
39 
40 template<typename T>
41 struct ConstIntegerBaseTrait<int_vector::IntRef<T>> {
42  using Dispatch = typename int_vector::IntRepr<T>::IntOpDispatch;
43 };
44 template<typename T>
45 struct IntegerBaseTrait<int_vector::IntRef<T>> {
46  using Dispatch = typename int_vector::IntRepr<T>::IntOpDispatch;
47 };
48 template<typename T>
49 struct ConstIntegerBaseTrait<int_vector::ConstIntRef<T>> {
50  using Dispatch = typename int_vector::IntRepr<T>::IntOpDispatch;
51 };
52 }
53 
54 namespace std {
55  template<typename T>
56  struct iterator_traits<tdc::int_vector::IntPtr<T>> {
57  typedef ptrdiff_t difference_type;
58  typedef typename tdc::int_vector::IntRepr<T>::value_type value_type;
59  typedef tdc::int_vector::IntPtr<T> pointer;
60  typedef tdc::int_vector::IntRef<T> reference;
61  typedef std::random_access_iterator_tag iterator_category;
62  };
63  template<typename T>
64  struct iterator_traits<tdc::int_vector::ConstIntPtr<T>> {
65  typedef ptrdiff_t difference_type;
66  typedef typename tdc::int_vector::IntRepr<T>::value_type value_type;
67  typedef tdc::int_vector::ConstIntPtr<T> pointer;
68  typedef tdc::int_vector::ConstIntRef<T> reference;
69  typedef std::random_access_iterator_tag iterator_category;
70  };
71 }
72 
73 namespace tdc {
74 namespace int_vector {
75  using sdsl::bits;
76 
77  template<class T>
78  struct IntPtrBase {};
79 
80  template<typename T>
81  class IntPtrBase<ConstIntPtr<T>>:
82  public IntRepr<T>::ConstIntPtrBase {
83  public:
84  using IntRepr<T>::ConstIntPtrBase::ConstIntPtrBase;
85  };
86 
87  template<typename T>
88  class IntPtrBase<IntPtr<T>>:
89  public IntRepr<T>::IntPtrBase {
90  public:
91  using IntRepr<T>::IntPtrBase::IntPtrBase;
92 
93  inline operator IntPtrBase<ConstIntPtr<T>>() const {
94  return IntPtrBase<ConstIntPtr<T>>(this->m_ptr, this->m_bit_offset, this->data_bit_size());
95  }
96  };
97 
98  template<class Self, class Ptr>
99  class GenericIntRef;
100 
101  template<class Self, class T>
102  class GenericIntPtr: IntPtrBase<Self> {
103  protected:
104  friend class GenericIntRef<IntRef<T>, IntPtr<T>>;
105  friend class GenericIntRef<ConstIntRef<T>, ConstIntPtr<T>>;
106  friend class IntRef<T>;
107  friend class ConstIntRef<T>;
108  friend struct IntegerBaseTrait<IntRef<T>>;
109  friend struct ConstIntegerBaseTrait<IntRef<T>>;
110  friend struct ConstIntegerBaseTrait<ConstIntRef<T>>;
111  friend typename IntRepr<T>::IntOpDispatch;
112 
113  public:
114  using tag_type = T;
115 
116  GenericIntPtr():
117  IntPtrBase<Self>(nullptr, 0, 0) {}
118  GenericIntPtr(const IntPtrBase<Self>& other):
119  IntPtrBase<Self>(other) {}
120  GenericIntPtr(const GenericIntPtr& other):
121  IntPtrBase<Self>(other){}
122 
123  Self& operator=(const Self& other) {
124  this->set_data_bit_size(other.data_bit_size());
125  this->m_ptr = other.m_ptr;
126  this->m_bit_offset = other.m_bit_offset;
127  return static_cast<Self&>(*this);
128  }
129 
130  Self& operator++() {
131  DynamicIntValueType const* tmp = this->m_ptr;
132  bits::move_right(tmp, this->m_bit_offset, this->data_bit_size());
133  this->m_ptr = (DynamicIntValueType*) tmp;
134  return static_cast<Self&>(*this);
135  }
136 
137  Self& operator--() {
138  DynamicIntValueType const* tmp = this->m_ptr;
139  bits::move_left(tmp, this->m_bit_offset, this->data_bit_size());
140  this->m_ptr = (DynamicIntValueType*) tmp;
141  return static_cast<Self&>(*this);
142  }
143 
144  friend Self operator+(const Self& lhs, const ptrdiff_t& rhs) {
145  auto tmp = lhs;
146  if (rhs >= 0) {
147  for(size_t i = 0; i < size_t(rhs); i++) {
148  ++tmp;
149  }
150  } else {
151  for(size_t i = 0; i < size_t(-rhs); i++) {
152  --tmp;
153  }
154  }
155  return tmp;
156  }
157 
158  friend Self operator+(const ptrdiff_t& lhs, const Self& rhs) { return rhs + lhs; }
159  friend Self operator-(const Self& lhs, const ptrdiff_t& rhs) { return lhs + (-rhs); }
160 
161  friend ptrdiff_t operator-(const Self& lhs, const Self& rhs) {
162  // TODO: test
163  DCHECK(lhs.data_bit_size() == rhs.data_bit_size());
164  auto ptr_diff = lhs.m_ptr - rhs.m_ptr;
165  auto bit_count = ptr_diff * sizeof(DynamicIntValueType) * CHAR_BIT;
166  bit_count += lhs.m_bit_offset;
167  bit_count -= rhs.m_bit_offset;
168  bit_count /= lhs.data_bit_size();
169  return bit_count;
170  }
171 
172  friend bool operator==(const Self& lhs, const Self& rhs) {
173  DCHECK(lhs.data_bit_size() == rhs.data_bit_size());
174  return (lhs.m_ptr == rhs.m_ptr)
175  && (lhs.m_bit_offset == rhs.m_bit_offset);
176  }
177  friend bool operator<(const Self& lhs, const Self& rhs) {
178  // TODO: test
179  DCHECK(lhs.data_bit_size() == rhs.data_bit_size());
180  if (lhs.m_ptr < rhs.m_ptr) return true;
181  if ((lhs.m_ptr == rhs.m_ptr) && (lhs.m_bit_offset < rhs.m_bit_offset)) return true;
182  return false;
183  }
184  friend bool operator!=(const Self& lhs, const Self& rhs) { return !(lhs == rhs); }
185  friend bool operator>(const Self& lhs, const Self& rhs) { return !(lhs < rhs); }
186  friend bool operator>=(const Self& lhs, const Self& rhs) { return (lhs > rhs) || (lhs == rhs); }
187  friend bool operator<=(const Self& lhs, const Self& rhs) { return (lhs < rhs) || (lhs == rhs); }
188 
189  Self& operator+=(const ptrdiff_t& v) { auto& self = static_cast<Self&>(*this); self = (self + v); return self; }
190  Self& operator-=(const ptrdiff_t& v) { auto& self = static_cast<Self&>(*this); self = (self - v); return self; }
191 
192  Self operator++(int) { auto self = static_cast<Self&>(*this); ++(*this); return self; }
193  Self operator--(int) { auto self = static_cast<Self&>(*this); --(*this); return self; }
194 
195  ConstIntRef<T> operator[](size_t i) const;
196  ConstIntRef<T> operator*() const;
197  };
198 
199  template<class T>
200  class ConstIntPtr: public GenericIntPtr<ConstIntPtr<T>, T> {
201  public:
202  using GenericIntPtr<ConstIntPtr<T>, T>::GenericIntPtr;
203  inline ConstIntPtr(): GenericIntPtr<ConstIntPtr<T>, T>::GenericIntPtr() {}
204  inline ConstIntPtr(const ConstIntPtr& other): GenericIntPtr<ConstIntPtr<T>, T>::GenericIntPtr(other) {}
205 
206  ConstIntPtr& operator=(const ConstIntPtr& other) {
207  return ((GenericIntPtr<ConstIntPtr<T>, T>&) *this) = other;
208  }
209  };
210 
211  template<class T>
212  class IntPtr: public GenericIntPtr<IntPtr<T>, T> {
213  public:
214  using GenericIntPtr<IntPtr<T>, T>::GenericIntPtr;
215  inline IntPtr(): GenericIntPtr<IntPtr<T>, T>::GenericIntPtr() {}
216  inline IntPtr(const IntPtr& other): GenericIntPtr<IntPtr<T>, T>::GenericIntPtr(other) {}
217 
218  IntPtr& operator=(const IntPtr& other) {
219  return ((GenericIntPtr<IntPtr<T>, T>&) *this) = other;
220  }
221 
222  inline IntRef<T> operator*();
223  inline IntRef<T> operator[](size_t i);
224 
225  inline operator ConstIntPtr<T>() const {
226  return ConstIntPtr<T>(IntPtrBase<ConstIntPtr<T>>((const IntPtrBase<IntPtr<T>>&) *this));
227  }
228  };
229 
230  template<class Self, class Ptr>
231  class GenericIntRef {
232  using T = typename Ptr::tag_type;
233  protected:
234  friend class IntPtr<T>;
235  friend class ConstIntPtr<T>;
236  friend struct IntegerBaseTrait<IntRef<T>>;
237  friend struct ConstIntegerBaseTrait<IntRef<T>>;
238  friend struct ConstIntegerBaseTrait<ConstIntRef<T>>;
239  friend typename IntRepr<T>::IntOpDispatch;
240 
241  Ptr m_ptr;
242  public:
243  using value_type = typename IntRepr<T>::value_type;
244 
245  inline GenericIntRef() = delete;
246  explicit GenericIntRef(const Ptr& ptr): m_ptr(ptr) {}
247 
248  operator value_type() const {
249  return IntRepr<T>::mem_rw::read_int(
250  m_ptr.m_ptr, m_ptr.m_bit_offset, this->m_ptr.data_bit_size());
251  }
252 
253  };
254 
255  template<class T>
256  class ConstIntRef:
257  public GenericIntRef<ConstIntRef<T>, ConstIntPtr<T>>,
258  public ConstIntegerBaseCombiner<
259  ConstIntegerBaseWithSelf<ConstIntRef<T>>,
260  ConstIntegerBaseWith32<ConstIntRef<T>, unsigned char>,
261  ConstIntegerBaseWith32<ConstIntRef<T>, char>,
262  ConstIntegerBaseWith32<ConstIntRef<T>, signed char>,
263  ConstIntegerBaseWith32<ConstIntRef<T>, unsigned short int>,
264  ConstIntegerBaseWith32<ConstIntRef<T>, signed short int>,
265  ConstIntegerBaseWith32<ConstIntRef<T>, unsigned int>,
266  ConstIntegerBaseWith32<ConstIntRef<T>, signed int>,
267  ConstIntegerBaseWith64<ConstIntRef<T>, unsigned long int>,
268  ConstIntegerBaseWith64<ConstIntRef<T>, signed long int>,
269  ConstIntegerBaseWith64<ConstIntRef<T>, unsigned long long int>,
270  ConstIntegerBaseWith64<ConstIntRef<T>, signed long long int>,
271  ConstIntegerBaseWith64<ConstIntRef<T>, T>
272  > {
273  public:
274  inline ConstIntRef() = delete;
275  explicit ConstIntRef(const ConstIntPtr<T>& ptr): GenericIntRef<ConstIntRef<T>, ConstIntPtr<T>>::GenericIntRef(ptr) {}
276 
277  inline ConstIntPtr<T> operator&() { return this->m_ptr; }
278  };
279 
280  template<class T>
281  class IntRef:
282  public GenericIntRef<IntRef<T>, IntPtr<T>>,
283  public IntegerBaseCombiner<
284  IntegerBaseWithSelf<IntRef<T>>,
285  IntegerBaseWith32<IntRef<T>, unsigned char>,
286  IntegerBaseWith32<IntRef<T>, char>,
287  IntegerBaseWith32<IntRef<T>, signed char>,
288  IntegerBaseWith32<IntRef<T>, unsigned short int>,
289  IntegerBaseWith32<IntRef<T>, signed short int>,
290  IntegerBaseWith32<IntRef<T>, unsigned int>,
291  IntegerBaseWith32<IntRef<T>, signed int>,
292  IntegerBaseWith64<IntRef<T>, unsigned long int>,
293  IntegerBaseWith64<IntRef<T>, signed long int>,
294  IntegerBaseWith64<IntRef<T>, unsigned long long int>,
295  IntegerBaseWith64<IntRef<T>, signed long long int>,
296  IntegerBaseWith64<IntRef<T>, T>
297  > {
298  public:
299  using typename GenericIntRef<IntRef<T>, IntPtr<T>>::value_type;
300 
301  inline IntRef() = delete;
302  explicit IntRef(const IntPtr<T>& ptr): GenericIntRef<IntRef<T>, IntPtr<T>>::GenericIntRef(ptr) {}
303 
304  inline IntRef& operator=(value_type other) {
305  IntRepr<T>::mem_rw::write_int(
306  this->m_ptr.m_ptr, other,
307  this->m_ptr.m_bit_offset,
308  this->m_ptr.data_bit_size()
309  );
310 
311  return *this;
312  };
313 
314  inline IntRef& operator=(const IntRef& other) {
315  return operator=(other.operator value_type());
316  };
317 
318  inline IntRef& operator=(const ConstIntRef<T>& other);
319 
320  inline IntPtr<T> operator&() { return this->m_ptr; }
321 
322  inline operator ConstIntRef<T>() const {
323  return ConstIntRef<T>(this->m_ptr);
324  }
325  };
326 
327  template<class T>
328  inline IntRef<T>& IntRef<T>::operator=(const ConstIntRef<T>& other) {
329  return operator=(value_type(other));
330  }
331 
332  template<class T>
333  inline IntRef<T> IntPtr<T>::operator*() {
334  return IntRef<T>(*this);
335  }
336 
337  template<class Self, class T>
338  ConstIntRef<T> GenericIntPtr<Self, T>::operator*() const {
339  return ConstIntRef<T>(static_cast<const Self&>(*this));
340  }
341 
342  template<class Self, class T>
343  ConstIntRef<T> GenericIntPtr<Self, T>::operator[](size_t i) const {
344  auto x = *this;
345  x += i;
346  return ConstIntRef<T>(static_cast<const Self&>(x));
347  }
348 
349  template<class T>
350  inline IntRef<T> IntPtr<T>::operator[](size_t i) {
351  auto x = *this;
352  x += i;
353  return IntRef<T>(x);
354  }
355 
356  template<class T>
357  inline void swap(IntRef<T>& lhs, IntRef<T>& rhs) noexcept {
358  T tmp = lhs;
359  lhs = rhs.operator T();
360  rhs = tmp;
361  }
362 
363  template<class T>
364  inline void swap(IntRef<T>& lhs, T& rhs) noexcept {
365  T tmp = lhs;
366  lhs = T(rhs);
367  rhs = tmp;
368  }
369 
370  template<class T>
371  inline void swap(T& lhs, IntRef<T>& rhs) noexcept {
372  T tmp = lhs;
373  lhs = rhs.operator T();
374  rhs = tmp;
375  }
376 
377  static_assert(sizeof(GenericIntPtr<ConstIntPtr<uint_t<40>>, uint_t<40>>) <= (sizeof(void*) * 2),
378  "make sure this is reasonably small");
379 
380 }
381 
382 template<class T>
383 using IntRef = int_vector::IntRef<T>;
384 
385 template<class T>
386 using ConstIntRef = int_vector::ConstIntRef<T>;
387 
388 template<class T>
389 using IntPtr = int_vector::IntPtr<T>;
390 
391 template<class T>
392 using ConstIntPtr = int_vector::ConstIntPtr<T>;
393 
394 }
395 
397 
Contains the text compression and encoding framework.
Definition: namespaces.hpp:11
uint_impl_t & operator=(const uint_impl_t &b)
Definition: uint_t.hpp:43
bool operator>(const IntVector< T > &lhs, const IntVector< T > &rhs)
Definition: IntVector.hpp:522
bool operator<=(const IntVector< T > &lhs, const IntVector< T > &rhs)
Definition: IntVector.hpp:517
bool operator==(const IntVector< T > &lhs, const IntVector< T > &rhs)
Definition: IntVector.hpp:502
void swap(IntVector< T > &lhs, IntVector< T > &rhs)
Definition: IntVector.hpp:532
bool operator<(const IntVector< T > &lhs, const IntVector< T > &rhs)
Definition: IntVector.hpp:512
bool operator>=(const IntVector< T > &lhs, const IntVector< T > &rhs)
Definition: IntVector.hpp:527
bool operator!=(const IntVector< T > &lhs, const IntVector< T > &rhs)
Definition: IntVector.hpp:507