Realistic 3D camera system
3D camera system components
buffers_iterator.hpp
Go to the documentation of this file.
1 //
2 // buffers_iterator.hpp
3 // ~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef ASIO_BUFFERS_ITERATOR_HPP
12 #define ASIO_BUFFERS_ITERATOR_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include "asio/detail/config.hpp"
19 #include <cstddef>
20 #include <iterator>
21 #include "asio/buffer.hpp"
22 #include "asio/detail/assert.hpp"
24 
26 
27 namespace asio {
28 
29 namespace detail
30 {
31  template <bool IsMutable>
33 
34  template <>
36  {
38  template <typename ByteType>
39  struct byte_type
40  {
41  typedef typename add_const<ByteType>::type type;
42  };
43  };
44 
45  template <>
47  {
49  template <typename ByteType>
50  struct byte_type
51  {
52  typedef ByteType type;
53  };
54  };
55 
56  template <typename BufferSequence, typename ByteType>
58  {
59  enum
60  {
61  is_mutable = is_convertible<
62  typename BufferSequence::value_type,
63  mutable_buffer>::value
64  };
66  typedef typename helper::buffer_type buffer_type;
67  typedef typename helper::template byte_type<ByteType>::type byte_type;
68  };
69 }
70 
72 template <typename BufferSequence, typename ByteType = char>
74 {
75 private:
76  typedef typename detail::buffers_iterator_types<
77  BufferSequence, ByteType>::buffer_type buffer_type;
78 
79 public:
81  typedef std::ptrdiff_t difference_type;
82 
84  typedef ByteType value_type;
85 
86 #if defined(GENERATING_DOCUMENTATION)
87 
93  typedef const_or_non_const_ByteType* pointer;
94 #else // defined(GENERATING_DOCUMENTATION)
95  typedef typename detail::buffers_iterator_types<
96  BufferSequence, ByteType>::byte_type* pointer;
97 #endif // defined(GENERATING_DOCUMENTATION)
98 
99 #if defined(GENERATING_DOCUMENTATION)
100 
106  typedef const_or_non_const_ByteType& reference;
107 #else // defined(GENERATING_DOCUMENTATION)
108  typedef typename detail::buffers_iterator_types<
109  BufferSequence, ByteType>::byte_type& reference;
110 #endif // defined(GENERATING_DOCUMENTATION)
111 
113  typedef std::random_access_iterator_tag iterator_category;
114 
117  : current_buffer_(),
118  current_buffer_position_(0),
119  begin_(),
120  current_(),
121  end_(),
122  position_(0)
123  {
124  }
125 
127  static buffers_iterator begin(const BufferSequence& buffers)
128 #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
129  __attribute__ ((__noinline__))
130 #endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
131  {
132  buffers_iterator new_iter;
133  new_iter.begin_ = buffers.begin();
134  new_iter.current_ = buffers.begin();
135  new_iter.end_ = buffers.end();
136  while (new_iter.current_ != new_iter.end_)
137  {
138  new_iter.current_buffer_ = *new_iter.current_;
139  if (asio::buffer_size(new_iter.current_buffer_) > 0)
140  break;
141  ++new_iter.current_;
142  }
143  return new_iter;
144  }
145 
147  static buffers_iterator end(const BufferSequence& buffers)
148 #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
149  __attribute__ ((__noinline__))
150 #endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
151  {
152  buffers_iterator new_iter;
153  new_iter.begin_ = buffers.begin();
154  new_iter.current_ = buffers.begin();
155  new_iter.end_ = buffers.end();
156  while (new_iter.current_ != new_iter.end_)
157  {
158  buffer_type buffer = *new_iter.current_;
159  new_iter.position_ += asio::buffer_size(buffer);
160  ++new_iter.current_;
161  }
162  return new_iter;
163  }
164 
166  reference operator*() const
167  {
168  return dereference();
169  }
170 
172  pointer operator->() const
173  {
174  return &dereference();
175  }
176 
178  reference operator[](std::ptrdiff_t difference) const
179  {
180  buffers_iterator tmp(*this);
181  tmp.advance(difference);
182  return *tmp;
183  }
184 
187  {
188  increment();
189  return *this;
190  }
191 
194  {
195  buffers_iterator tmp(*this);
196  ++*this;
197  return tmp;
198  }
199 
202  {
203  decrement();
204  return *this;
205  }
206 
209  {
210  buffers_iterator tmp(*this);
211  --*this;
212  return tmp;
213  }
214 
216  buffers_iterator& operator+=(std::ptrdiff_t difference)
217  {
218  advance(difference);
219  return *this;
220  }
221 
223  buffers_iterator& operator-=(std::ptrdiff_t difference)
224  {
225  advance(-difference);
226  return *this;
227  }
228 
231  std::ptrdiff_t difference)
232  {
233  buffers_iterator tmp(iter);
234  tmp.advance(difference);
235  return tmp;
236  }
237 
239  friend buffers_iterator operator+(std::ptrdiff_t difference,
240  const buffers_iterator& iter)
241  {
242  buffers_iterator tmp(iter);
243  tmp.advance(difference);
244  return tmp;
245  }
246 
249  std::ptrdiff_t difference)
250  {
251  buffers_iterator tmp(iter);
252  tmp.advance(-difference);
253  return tmp;
254  }
255 
257  friend std::ptrdiff_t operator-(const buffers_iterator& a,
258  const buffers_iterator& b)
259  {
260  return b.distance_to(a);
261  }
262 
264  friend bool operator==(const buffers_iterator& a, const buffers_iterator& b)
265  {
266  return a.equal(b);
267  }
268 
270  friend bool operator!=(const buffers_iterator& a, const buffers_iterator& b)
271  {
272  return !a.equal(b);
273  }
274 
276  friend bool operator<(const buffers_iterator& a, const buffers_iterator& b)
277  {
278  return a.distance_to(b) > 0;
279  }
280 
282  friend bool operator<=(const buffers_iterator& a, const buffers_iterator& b)
283  {
284  return !(b < a);
285  }
286 
288  friend bool operator>(const buffers_iterator& a, const buffers_iterator& b)
289  {
290  return b < a;
291  }
292 
294  friend bool operator>=(const buffers_iterator& a, const buffers_iterator& b)
295  {
296  return !(a < b);
297  }
298 
299 private:
300  // Dereference the iterator.
301  reference dereference() const
302  {
303  return buffer_cast<pointer>(current_buffer_)[current_buffer_position_];
304  }
305 
306  // Compare two iterators for equality.
307  bool equal(const buffers_iterator& other) const
308  {
309  return position_ == other.position_;
310  }
311 
312  // Increment the iterator.
313  void increment()
314  {
315  ASIO_ASSERT(current_ != end_ && "iterator out of bounds");
316  ++position_;
317 
318  // Check if the increment can be satisfied by the current buffer.
319  ++current_buffer_position_;
320  if (current_buffer_position_ != asio::buffer_size(current_buffer_))
321  return;
322 
323  // Find the next non-empty buffer.
324  ++current_;
325  current_buffer_position_ = 0;
326  while (current_ != end_)
327  {
328  current_buffer_ = *current_;
329  if (asio::buffer_size(current_buffer_) > 0)
330  return;
331  ++current_;
332  }
333  }
334 
335  // Decrement the iterator.
336  void decrement()
337  {
338  ASIO_ASSERT(position_ > 0 && "iterator out of bounds");
339  --position_;
340 
341  // Check if the decrement can be satisfied by the current buffer.
342  if (current_buffer_position_ != 0)
343  {
344  --current_buffer_position_;
345  return;
346  }
347 
348  // Find the previous non-empty buffer.
349  typename BufferSequence::const_iterator iter = current_;
350  while (iter != begin_)
351  {
352  --iter;
353  buffer_type buffer = *iter;
354  std::size_t buffer_size = asio::buffer_size(buffer);
355  if (buffer_size > 0)
356  {
357  current_ = iter;
358  current_buffer_ = buffer;
359  current_buffer_position_ = buffer_size - 1;
360  return;
361  }
362  }
363  }
364 
365  // Advance the iterator by the specified distance.
366  void advance(std::ptrdiff_t n)
367  {
368  if (n > 0)
369  {
370  ASIO_ASSERT(current_ != end_ && "iterator out of bounds");
371  for (;;)
372  {
373  std::ptrdiff_t current_buffer_balance
374  = asio::buffer_size(current_buffer_)
375  - current_buffer_position_;
376 
377  // Check if the advance can be satisfied by the current buffer.
378  if (current_buffer_balance > n)
379  {
380  position_ += n;
381  current_buffer_position_ += n;
382  return;
383  }
384 
385  // Update position.
386  n -= current_buffer_balance;
387  position_ += current_buffer_balance;
388 
389  // Move to next buffer. If it is empty then it will be skipped on the
390  // next iteration of this loop.
391  if (++current_ == end_)
392  {
393  ASIO_ASSERT(n == 0 && "iterator out of bounds");
394  current_buffer_ = buffer_type();
395  current_buffer_position_ = 0;
396  return;
397  }
398  current_buffer_ = *current_;
399  current_buffer_position_ = 0;
400  }
401  }
402  else if (n < 0)
403  {
404  std::size_t abs_n = -n;
405  ASIO_ASSERT(position_ >= abs_n && "iterator out of bounds");
406  for (;;)
407  {
408  // Check if the advance can be satisfied by the current buffer.
409  if (current_buffer_position_ >= abs_n)
410  {
411  position_ -= abs_n;
412  current_buffer_position_ -= abs_n;
413  return;
414  }
415 
416  // Update position.
417  abs_n -= current_buffer_position_;
418  position_ -= current_buffer_position_;
419 
420  // Check if we've reached the beginning of the buffers.
421  if (current_ == begin_)
422  {
423  ASIO_ASSERT(abs_n == 0 && "iterator out of bounds");
424  current_buffer_position_ = 0;
425  return;
426  }
427 
428  // Find the previous non-empty buffer.
429  typename BufferSequence::const_iterator iter = current_;
430  while (iter != begin_)
431  {
432  --iter;
433  buffer_type buffer = *iter;
434  std::size_t buffer_size = asio::buffer_size(buffer);
435  if (buffer_size > 0)
436  {
437  current_ = iter;
438  current_buffer_ = buffer;
439  current_buffer_position_ = buffer_size;
440  break;
441  }
442  }
443  }
444  }
445  }
446 
447  // Determine the distance between two iterators.
448  std::ptrdiff_t distance_to(const buffers_iterator& other) const
449  {
450  return other.position_ - position_;
451  }
452 
453  buffer_type current_buffer_;
454  std::size_t current_buffer_position_;
455  typename BufferSequence::const_iterator begin_;
456  typename BufferSequence::const_iterator current_;
457  typename BufferSequence::const_iterator end_;
458  std::size_t position_;
459 };
460 
462 template <typename BufferSequence>
464  const BufferSequence& buffers)
465 {
467 }
468 
470 template <typename BufferSequence>
472  const BufferSequence& buffers)
473 {
475 }
476 
477 } // namespace asio
478 
480 
481 #endif // ASIO_BUFFERS_ITERATOR_HPP
#define ASIO_ASSERT(expr)
Definition: assert.hpp:29
buffers_iterator & operator+=(std::ptrdiff_t difference)
Addition operator.
buffers_iterator & operator-=(std::ptrdiff_t difference)
Subtraction operator.
Holds a buffer that cannot be modified.
Definition: buffer.hpp:211
helper::template byte_type< ByteType >::type byte_type
buffers_iterator< BufferSequence > buffers_end(const BufferSequence &buffers)
Construct an iterator representing the end of the buffers&#39; data.
friend bool operator>=(const buffers_iterator &a, const buffers_iterator &b)
Compare two iterators.
reference operator*() const
Dereference an iterator.
A random access iterator over the bytes in a buffer sequence.
mutable_buffers_1 buffer(const mutable_buffer &b)
Create a new modifiable buffer from an existing buffer.
Definition: buffer.hpp:706
friend bool operator!=(const buffers_iterator &a, const buffers_iterator &b)
Test two iterators for inequality.
detail::buffers_iterator_types< BufferSequence, ByteType >::byte_type & reference
buffers_iterator operator--(int)
Decrement operator (postfix).
friend std::ptrdiff_t operator-(const buffers_iterator &a, const buffers_iterator &b)
Subtraction operator.
friend bool operator>(const buffers_iterator &a, const buffers_iterator &b)
Compare two iterators.
friend buffers_iterator operator-(const buffers_iterator &iter, std::ptrdiff_t difference)
Subtraction operator.
asio::basic_streambuf< Allocator > & b
Definition: read.hpp:702
buffers_iterator & operator++()
Increment operator (prefix).
std::size_t buffer_size(const mutable_buffer &b)
Get the number of bytes in a modifiable buffer.
Definition: buffer.hpp:357
PointerToPodType buffer_cast(const mutable_buffer &b)
Cast a non-modifiable buffer to a specified pointer to POD type.
Definition: buffer.hpp:424
detail::buffers_iterator_types< BufferSequence, ByteType >::byte_type * pointer
const MutableBufferSequence & buffers
Definition: read.hpp:521
static buffers_iterator end(const BufferSequence &buffers)
Construct an iterator representing the end of the buffers&#39; data.
friend bool operator==(const buffers_iterator &a, const buffers_iterator &b)
Test two iterators for equality.
friend bool operator<=(const buffers_iterator &a, const buffers_iterator &b)
Compare two iterators.
buffers_iterator< BufferSequence > buffers_begin(const BufferSequence &buffers)
Construct an iterator representing the beginning of the buffers&#39; data.
buffers_iterator operator++(int)
Increment operator (postfix).
Holds a buffer that can be modified.
Definition: buffer.hpp:91
void increment(atomic_count &a, long b)
buffers_iterator_types_helper< is_mutable > helper
buffers_iterator()
Default constructor. Creates an iterator in an undefined state.
std::ptrdiff_t difference_type
The type used for the distance between two iterators.
ByteType value_type
The type of the value pointed to by the iterator.
friend buffers_iterator operator+(std::ptrdiff_t difference, const buffers_iterator &iter)
Addition operator.
pointer operator->() const
Dereference an iterator.
std::random_access_iterator_tag iterator_category
The iterator category.
friend bool operator<(const buffers_iterator &a, const buffers_iterator &b)
Compare two iterators.
static buffers_iterator begin(const BufferSequence &buffers)
Construct an iterator representing the beginning of the buffers&#39; data.
friend buffers_iterator operator+(const buffers_iterator &iter, std::ptrdiff_t difference)
Addition operator.
reference operator[](std::ptrdiff_t difference) const
Access an individual element.
buffers_iterator & operator--()
Decrement operator (prefix).