Virtual Testbed
Ship dynamics simulator for extreme conditions
multiple_array_iterator.hh
1 #ifndef VTESTBED_BASE_MULTIPLE_ARRAY_ITERATOR_HH
2 #define VTESTBED_BASE_MULTIPLE_ARRAY_ITERATOR_HH
3 
4 #include <array>
5 #include <cstddef>
6 #include <initializer_list>
7 #include <iterator>
8 #include <utility>
9 
10 namespace vtb {
11 
12  namespace base {
13 
14  template <class Iterator, size_t N>
16 
17  static_assert(N > 0, "bad N");
18 
19  private:
20  typedef Iterator base_iterator;
24 
25  public:
26  typedef typename traits_type::value_type value_type;
27  typedef typename traits_type::difference_type difference_type;
28  typedef typename traits_type::pointer pointer;
29  typedef typename traits_type::reference reference;
30  typedef std::size_t size_type;
32  typedef const pointer const_pointer;
33  typedef const reference const_reference;
34 
35  private:
36  pointer_array _ptrs;
37  Iterator _ptr = nullptr;
38  size_type _index = 0;
39 
40  public:
41 
42  template <class ... Args>
43  inline
44  multiple_array_iterator(const Args& ... ptrs):
45  _ptrs{ptrs...}, _ptr(_ptrs.front().first) { this->advance_empty(); }
46 
47  template <class ... Args>
48  inline
49  multiple_array_iterator(int, const Args& ... ptrs):
50  _ptrs{ptrs...}, _ptr(_ptrs.back().second), _index(N) {}
51 
52  multiple_array_iterator() = default;
56  operator=(const multiple_array_iterator&) = default;
58  operator=(multiple_array_iterator&&) = default;
59 
60  inline bool
61  operator==(const multiple_array_iterator& rhs) const {
62  return this->_ptr == rhs._ptr && this->_index == rhs._index;
63  }
64 
65  inline bool
66  operator!=(const multiple_array_iterator& rhs) const {
67  return !this->operator==(rhs);
68  }
69 
70  inline pointer operator->() { return this->_ptr; }
71  inline const_pointer operator->() const { return this->_ptr; }
72  inline reference operator*() { return *this->_ptr; }
73  inline const_reference operator*() const { return *this->_ptr; }
74 
75  inline reference
76  operator++() {
77  const auto& ptrs = this->_ptrs;
78  auto& i = this->_index;
79  auto& ptr = this->_ptr;
80  if (i != N && ++ptr == ptrs[i].second && ++i != N) {
81  ptr = ptrs[i].first;
82  this->advance_empty();
83  }
84  return *ptr;
85  }
86 
88  operator++(int) {
89  multiple_array_iterator tmp(*this);
90  this->operator++();
91  return *tmp;
92  }
93 
94  private:
95 
96  inline void
97  advance_empty() {
98  const auto& ptrs = this->_ptrs;
99  auto& i = this->_index;
100  auto& ptr = this->_ptr;
101  while (i != N && ptrs[i].first == ptrs[i].second) {
102  ptr = ptrs[++i].first;
103  }
104  }
105 
106  };
107 
108  }
109 
110 }
111 
112 #endif // vim:filetype=cpp
Main namespace.
Definition: convert.hh:9