tudocomp
– The TU Dortmund Compression Framework
GenericViewBase.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <fstream>
7 #include <iostream>
8 #include <memory>
9 #include <sstream>
10 #include <string>
11 #include <type_traits>
12 #include <utility>
13 #include <iomanip>
14 #include <cstring>
15 #include <glog/logging.h>
16 
17 #include <tudocomp/def.hpp>
18 
19 namespace tdc {
20 
21 template<class T, class P>
23 protected:
24  friend class GenericViewBase<T, const T*>;
25  friend class GenericViewBase<T, T*>;
26 
27  using value_type = T;
28  using const_reference = const T&;
29  using const_pointer = const T*;
31  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
32  using difference_type = ptrdiff_t;
33  using size_type = size_t;
34 
35  static const size_type npos = -1;
36 
37  P m_data;
38  size_t m_size;
39 
40  inline void bound_check(size_t pos) const {
41  if (pos >= m_size) {
42  std::stringstream ss;
43  ss << "accessing view with bounds [0, ";
44  ss << m_size;
45  ss << ") at out-of-bounds index ";
46  ss << pos;
47  throw std::out_of_range(ss.str());
48  }
49  }
50 
51  inline void bound_check_not_empty() const {
52  if (empty()) {
53  std::stringstream ss;
54  ss << "accessing element in empty view with bounds [0, ";
55  ss << m_size;
56  ss << ")";
57  throw std::out_of_range(ss.str());
58  }
59  }
60 
61  inline void debug_bound_check(size_t IF_DEBUG(pos)) const {
63  }
64 
65  inline void debug_bound_check_not_empty() const {
67  }
68 
69  inline GenericViewBase(P data, size_t size): m_data(data), m_size(size) {}
70  inline GenericViewBase(): GenericViewBase(P(""), 0) {} // Need a valid static pointer...
71  inline GenericViewBase(const GenericViewBase& other):
72  GenericViewBase(other.m_data, other.m_size) {}
73  inline GenericViewBase(const std::vector<T>& other):
74  GenericViewBase(other.data(), other.size()) {}
75  template<size_t N>
76  inline GenericViewBase(const std::array<T, N>& other):
77  GenericViewBase(other.data(), other.size()) {}
78 
79  inline operator std::vector<T>() const {
80  return std::vector<T>(cbegin(), cend());
81  }
82 
83  inline GenericViewBase& operator=(const GenericViewBase& other) {
84  m_data = other.m_data;
85  m_size = other.m_size;
86  return *this;
87  }
88 
89  inline const_iterator begin() const {
90  return m_data;
91  }
92 
93  inline const_iterator end() const {
94  return m_data + m_size;
95  }
96 
97  inline const_reverse_iterator rbegin() const {
98  return std::reverse_iterator<const_iterator>(end());
99  }
100 
101  inline const_reverse_iterator rend() const {
102  return std::reverse_iterator<const_iterator>(begin());
103  }
104 
105  inline const_iterator cbegin() const {
106  return m_data;
107  }
108 
109  inline const_iterator cend() const {
110  return m_data + m_size;
111  }
112 
114  return std::reverse_iterator<const_iterator>(cend());
115  }
116 
117  inline const_reverse_iterator crend() const {
118  return std::reverse_iterator<const_iterator>(cbegin());
119  }
120 
121  inline size_type size() const {
122  return m_size;
123  }
124 
125  inline size_type max_size() const {
126  return size();
127  }
128 
129  inline bool empty() const {
130  return size() == 0;
131  }
132 
135  return m_data[n];
136  }
137 
138  inline const_reference at(size_type n) const {
139  bound_check(n);
140  return m_data[n];
141  }
142 
143  inline const_reference front() const {
145  return m_data[0];
146  }
147 
148  inline const_reference back() const {
150  return m_data[size() - 1];
151  }
152 
153  inline const value_type* data() const noexcept {
154  return m_data;
155  }
156 
157  inline void pop_back() {
159  m_size--;
160  }
161 
162  inline void pop_front() {
164  m_data++;
165  m_size--;
166  }
167 
168  inline void swap(GenericViewBase& other) {
169  using std::swap;
170  swap(m_data, other.m_data);
171  swap(m_size, other.m_size);
172  }
173 
174  inline void clear() {
175  m_size = 0;
176  }
177 
178  inline GenericViewBase slice(size_type from, size_type to = npos) const {
179  if (to == npos) {
180  to = m_size;
181  }
182 
183  DCHECK_LE(from, to);
184  DCHECK_LE(from, size());
185  DCHECK_LE(to, size());
186 
187  return GenericViewBase(m_data + from, to - from);
188  }
189 
191  if (len == npos) {
192  len = m_size - pos;
193  }
194 
195  return slice(pos, pos + len);
196  }
197 
198  inline void remove_prefix(size_type n) {
199  *this = slice(n);
200  }
201 
202  inline void remove_suffix(size_type n) {
203  *this = slice(0, m_size - n);
204  }
205 
206  inline bool starts_with(const T& c) const {
207  return !empty() && (front() == c);
208  }
209 
210  inline bool starts_with(const GenericViewBase<T, const T*>& x) const {
211  GenericViewBase<T, const T*> y(m_data, m_size);
212  return (x.size() <= y.size()) && op_eq(y.slice(0, x.size()), x);
213  }
214 
215  inline bool ends_with(const T& c) const {
216  return !empty() && (back() == c);
217  }
218 
219  inline bool ends_with(const GenericViewBase<T, const T*>& x) const {
220  GenericViewBase<T, const T*> y(m_data, m_size);
221  return (x.size() <= y.size()) && op_eq(y.slice(size() - x.size()), x);
222  }
223 
224  template<class U, class Q>
225  friend void swap(GenericViewBase<U, Q>& lhs, GenericViewBase<U, Q>& rhs);
226 
227  inline static bool op_eq(const GenericViewBase<T, const T*>& lhs, const GenericViewBase<T, const T*>& rhs) {
228  if (lhs.size() != rhs.size()) return false;
229  return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin());
230  }
231 
232  inline static bool op_not_eq(const GenericViewBase<T, const T*>& lhs, const GenericViewBase<T, const T*>& rhs) {
233  return !(op_eq(lhs, rhs));
234  }
235 
236  inline static bool op_less(const GenericViewBase<T, const T*>& lhs, const GenericViewBase<T, const T*>& rhs) {
237  return std::lexicographical_compare(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
238  }
239 
240  inline static bool op_less_eq(const GenericViewBase<T, const T*>& lhs, const GenericViewBase<T, const T*>& rhs) {
241  return !(op_greater(lhs, rhs));
242  }
243 
244  inline static bool op_greater(const GenericViewBase<T, const T*>& lhs, const GenericViewBase<T, const T*>& rhs) {
245  return std::lexicographical_compare(rhs.cbegin(), rhs.cend(), lhs.cbegin(), lhs.cend());
246  }
247 
248  inline static bool op_greater_eq(const GenericViewBase<T, const T*>& lhs, const GenericViewBase<T, const T*>& rhs) {
249  return !(op_less(lhs, rhs));
250  }
251 };
252 
253 template<class T, class Q>
255  lhs.swap(rhs);
256 }
257 
258 }
void bound_check_not_empty() const
static bool op_less_eq(const GenericViewBase< T, const T *> &lhs, const GenericViewBase< T, const T *> &rhs)
Contains the text compression and encoding framework.
Definition: namespaces.hpp:11
static bool op_eq(const GenericViewBase< T, const T *> &lhs, const GenericViewBase< T, const T *> &rhs)
void bound_check(size_t pos) const
void debug_bound_check_not_empty() const
bool starts_with(const GenericViewBase< T, const T *> &x) const
const_reference back() const
void remove_suffix(size_type n)
const_iterator cend() const
void remove_prefix(size_type n)
len_compact_t len
Definition: LZSSFactors.hpp:38
const_reverse_iterator rbegin() const
static bool op_less(const GenericViewBase< T, const T *> &lhs, const GenericViewBase< T, const T *> &rhs)
const_iterator begin() const
void swap(GenericViewBase &other)
const_reference front() const
static bool op_not_eq(const GenericViewBase< T, const T *> &lhs, const GenericViewBase< T, const T *> &rhs)
GenericViewBase(const std::array< T, N > &other)
GenericViewBase & operator=(const GenericViewBase &other)
const_reference at(size_type n) const
size_type max_size() const
static bool op_greater_eq(const GenericViewBase< T, const T *> &lhs, const GenericViewBase< T, const T *> &rhs)
const_reference operator[](size_type n) const
std::reverse_iterator< const_iterator > const_reverse_iterator
void swap(GenericViewBase< T, Q > &lhs, GenericViewBase< T, Q > &rhs)
len_compact_t pos
Definition: LZSSFactors.hpp:38
const_iterator end() const
static const size_type npos
size_type size() const
GenericViewBase(P data, size_t size)
const_reverse_iterator crbegin() const
bool ends_with(const T &c) const
const_iterator cbegin() const
GenericViewBase slice(size_type from, size_type to=npos) const
const_reverse_iterator crend() const
GenericViewBase(const std::vector< T > &other)
void debug_bound_check(size_t IF_DEBUG(pos)) const
bool starts_with(const T &c) const
bool ends_with(const GenericViewBase< T, const T *> &x) const
const value_type * data() const noexcept
GenericViewBase(const GenericViewBase &other)
static bool op_greater(const GenericViewBase< T, const T *> &lhs, const GenericViewBase< T, const T *> &rhs)
GenericViewBase substr(size_type pos, size_type len=npos) const
const_reverse_iterator rend() const
#define IF_DEBUG(x)
x is compiled only in debug builds.
Definition: def.hpp:32