protozero
Minimalistic protocol buffer decoder and encoder in C++.
iterators.hpp
Go to the documentation of this file.
1 #ifndef PROTOZERO_ITERATORS_HPP
2 #define PROTOZERO_ITERATORS_HPP
3 
4 /*****************************************************************************
5 
6 protozero - Minimalistic protocol buffer decoder and encoder in C++.
7 
8 This file is from https://github.com/mapbox/protozero where you can find more
9 documentation.
10 
11 *****************************************************************************/
12 
19 #include <cstring>
20 #include <iterator>
21 #include <utility>
22 
23 #include <protozero/config.hpp>
24 #include <protozero/varint.hpp>
25 
26 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
27 # include <protozero/byteswap.hpp>
28 #endif
29 
30 namespace protozero {
31 
37 template <typename T, typename P = std::pair<T, T>>
39 #ifdef PROTOZERO_STRICT_API
40  protected
41 #else
42  public
43 #endif
44  P {
45 
46 public:
47 
49  using iterator = T;
50 
52  using value_type = typename std::iterator_traits<T>::value_type;
53 
57  constexpr iterator_range() :
58  P(iterator{}, iterator{}) {
59  }
60 
67  constexpr iterator_range(iterator&& first_iterator, iterator&& last_iterator) :
68  P(std::forward<iterator>(first_iterator),
69  std::forward<iterator>(last_iterator)) {
70  }
71 
73  constexpr iterator begin() const noexcept {
74  return this->first;
75  }
76 
78  constexpr iterator end() const noexcept {
79  return this->second;
80  }
81 
83  constexpr iterator cbegin() const noexcept {
84  return this->first;
85  }
86 
88  constexpr iterator cend() const noexcept {
89  return this->second;
90  }
91 
93  constexpr std::size_t empty() const noexcept {
94  return begin() == end();
95  }
96 
102  value_type front() const {
103  protozero_assert(!empty());
104  return *(this->first);
105  }
106 
112  void drop_front() {
113  protozero_assert(!empty());
114  ++this->first;
115  }
116 
122  void swap(iterator_range& other) noexcept {
123  using std::swap;
124  swap(this->first, other.first);
125  swap(this->second, other.second);
126  }
127 
128 }; // struct iterator_range
129 
136 template <typename T>
137 inline void swap(iterator_range<T>& lhs, iterator_range<T>& rhs) noexcept {
138  lhs.swap(rhs);
139 }
140 
145 template <typename T>
147 
149  const char* m_data;
150 
152  const char* m_end;
153 
154 public:
155 
156  using iterator_category = std::forward_iterator_tag;
157  using value_type = T;
158  using difference_type = std::ptrdiff_t;
159  using pointer = value_type*;
160  using reference = value_type&;
161 
162  const_fixed_iterator() noexcept :
163  m_data(nullptr),
164  m_end(nullptr) {
165  }
166 
167  const_fixed_iterator(const char* data, const char* end) noexcept :
168  m_data(data),
169  m_end(end) {
170  }
171 
172  const_fixed_iterator(const const_fixed_iterator&) noexcept = default;
173  const_fixed_iterator(const_fixed_iterator&&) noexcept = default;
174 
175  const_fixed_iterator& operator=(const const_fixed_iterator&) noexcept = default;
176  const_fixed_iterator& operator=(const_fixed_iterator&&) noexcept = default;
177 
178  ~const_fixed_iterator() noexcept = default;
179 
180  value_type operator*() const {
181  value_type result;
182  std::memcpy(&result, m_data, sizeof(value_type));
183 #if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
184  detail::byteswap_inplace(&result);
185 #endif
186  return result;
187  }
188 
189  const_fixed_iterator& operator++() {
190  m_data += sizeof(value_type);
191  return *this;
192  }
193 
194  const_fixed_iterator operator++(int) {
195  const const_fixed_iterator tmp(*this);
196  ++(*this);
197  return tmp;
198  }
199 
200  bool operator==(const const_fixed_iterator& rhs) const noexcept {
201  return m_data == rhs.m_data && m_end == rhs.m_end;
202  }
203 
204  bool operator!=(const const_fixed_iterator& rhs) const noexcept {
205  return !(*this == rhs);
206  }
207 
208 }; // class const_fixed_iterator
209 
214 template <typename T>
216 
217 protected:
218 
220  const char* m_data;
221 
223  const char* m_end;
224 
225 public:
226 
227  using iterator_category = std::forward_iterator_tag;
228  using value_type = T;
229  using difference_type = std::ptrdiff_t;
230  using pointer = value_type*;
231  using reference = value_type&;
232 
233  const_varint_iterator() noexcept :
234  m_data(nullptr),
235  m_end(nullptr) {
236  }
237 
238  const_varint_iterator(const char* data, const char* end) noexcept :
239  m_data(data),
240  m_end(end) {
241  }
242 
243  const_varint_iterator(const const_varint_iterator&) noexcept = default;
244  const_varint_iterator(const_varint_iterator&&) noexcept = default;
245 
246  const_varint_iterator& operator=(const const_varint_iterator&) noexcept = default;
247  const_varint_iterator& operator=(const_varint_iterator&&) noexcept = default;
248 
249  ~const_varint_iterator() noexcept = default;
250 
251  value_type operator*() const {
252  const char* d = m_data; // will be thrown away
253  return static_cast<value_type>(decode_varint(&d, m_end));
254  }
255 
256  const_varint_iterator& operator++() {
257  skip_varint(&m_data, m_end);
258  return *this;
259  }
260 
261  const_varint_iterator operator++(int) {
262  const const_varint_iterator tmp(*this);
263  ++(*this);
264  return tmp;
265  }
266 
267  bool operator==(const const_varint_iterator& rhs) const noexcept {
268  return m_data == rhs.m_data && m_end == rhs.m_end;
269  }
270 
271  bool operator!=(const const_varint_iterator& rhs) const noexcept {
272  return !(*this == rhs);
273  }
274 
275 }; // class const_varint_iterator
276 
281 template <typename T>
283 
284 public:
285 
286  using iterator_category = std::forward_iterator_tag;
287  using value_type = T;
288  using difference_type = std::ptrdiff_t;
289  using pointer = value_type*;
290  using reference = value_type&;
291 
292  const_svarint_iterator() noexcept :
294  }
295 
296  const_svarint_iterator(const char* data, const char* end) noexcept :
298  }
299 
302 
303  const_svarint_iterator& operator=(const const_svarint_iterator&) = default;
304  const_svarint_iterator& operator=(const_svarint_iterator&&) = default;
305 
306  ~const_svarint_iterator() = default;
307 
308  value_type operator*() const {
309  const char* d = this->m_data; // will be thrown away
310  return static_cast<value_type>(decode_zigzag64(decode_varint(&d, this->m_end)));
311  }
312 
313  const_svarint_iterator& operator++() {
314  skip_varint(&this->m_data, this->m_end);
315  return *this;
316  }
317 
318  const_svarint_iterator operator++(int) {
319  const const_svarint_iterator tmp(*this);
320  ++(*this);
321  return tmp;
322  }
323 
324 }; // class const_svarint_iterator
325 
326 } // end namespace protozero
327 
328 #endif // PROTOZERO_ITERATORS_HPP
constexpr iterator cbegin() const noexcept
Return iterator to beginning of range.
Definition: iterators.hpp:83
typename std::iterator_traits< T >::value_type value_type
The value type of the underlying iterator.
Definition: iterators.hpp:52
constexpr int64_t decode_zigzag64(uint64_t value) noexcept
Definition: varint.hpp:181
Definition: iterators.hpp:146
void swap(iterator_range &other) noexcept
Definition: iterators.hpp:122
constexpr iterator begin() const noexcept
Return iterator to beginning of range.
Definition: iterators.hpp:73
T iterator
The type of the iterators in this range.
Definition: iterators.hpp:49
constexpr iterator end() const noexcept
Return iterator to end of range.
Definition: iterators.hpp:78
Contains macro checks for different configurations.
constexpr std::size_t empty() const noexcept
Return true if this range is empty.
Definition: iterators.hpp:93
constexpr iterator_range(iterator &&first_iterator, iterator &&last_iterator)
Definition: iterators.hpp:67
void swap(iterator_range< T > &lhs, iterator_range< T > &rhs) noexcept
Definition: iterators.hpp:137
void skip_varint(const char **data, const char *end)
Definition: varint.hpp:112
void drop_front()
Definition: iterators.hpp:112
const char * m_end
Pointer to end iterator position.
Definition: iterators.hpp:223
const char * m_data
Pointer to current iterator position.
Definition: iterators.hpp:220
Contains functions to swap bytes in values (for different endianness).
constexpr iterator_range()
Definition: iterators.hpp:57
Definition: iterators.hpp:282
bool operator==(const data_view &lhs, const data_view &rhs) noexcept
Definition: types.hpp:186
Definition: iterators.hpp:215
bool operator!=(const data_view &lhs, const data_view &rhs) noexcept
Definition: types.hpp:197
Definition: iterators.hpp:38
Contains low-level varint and zigzag encoding and decoding functions.
value_type front() const
Definition: iterators.hpp:102
uint64_t decode_varint(const char **data, const char *end)
Definition: varint.hpp:89
constexpr iterator cend() const noexcept
Return iterator to end of range.
Definition: iterators.hpp:88
All parts of the protozero header-only library are in this namespace.
Definition: byteswap.hpp:24