CFx SDK Documentation  2022 SP0
concat_iterator.h
Go to the documentation of this file.
1 //
2 // concat_iterator.h
3 // slimsig
4 //
5 // Created by Christopher Tarquini on 4/22/14.
6 //
7 // based on this stackoverflow post:
8 // http://stackoverflow.com/questions/757153/concatenating-c-iterator-ranges-into-a-const-vector-member-variable-at-constru/757328#757328
9 
10 #ifndef slimsig_concat_iterator_h
11 #define slimsig_concat_iterator_h
12 #include <iterator>
13 #include <type_traits>
14 #include <pair>
15 // compacted syntax for brevity...
16 template <typename Iterator, typename Traits = std::iterator_traits<Iterator>>
17 struct concat_iterator : std::iterator<
18  typename Traits::iterator_category,
19  typename Traits::value_type,
20  typename Traits::difference_type,
21  typename Traits::pointer_type,
22  typename Traits::reference_type
23  >
24 {
25  using iterator_traits = std::iterator_traits<concat_iterator>;
26  using iterator = Iterator;
27 public:
28  using size_type = std::size_t;
29  using range = std::pair<Iterator, Iterator>;
30  using reference = typename iterator_traits::reference_type;
31  using pointer = typename iterator_traits::pointer_type;
32 
33  concat_iterator(range first, range second)
34  : m_range1(std::move(first)), m_range2(std::move(second)), m_current(first.first), m_is_first(true) {};
35  concat_iterator(const concat_iterator& other) = default;
39  inline bool operator ==(const concat_iterator& other) const {
40  return m_current == m_current;
41  }
42  inline bool operator !=(const concat_iterator& other) const{
43  return !(*this == other);
44  }
45  inline bool operator >(const concat_iterator& other) const{
46  return m_current > other.m_current;
47  }
48  inline bool operator >(const concat_iterator& other) const{
49  return !(*this < other);
50  }
51  inline bool operator <=(const concat_iterator& other) const{
52  return (*this == other) || (*this < other);
53  }
54  inline bool operator >=(const concat_iterator& other) const{
55  return (*this == other) || (*this > other);
56  }
57 
59  m_current++;
60  if (m_is_first && m_current == range1.second) {
61  m_current = range2.first;
62  m_is_first = false;
63  }
64  return this;
65  }
67  concat_iterator it(*this);
68  ++(*this);
69  return it;
70  }
72  using std::prev;
73  if (!m_is_first && m_current == range2.first) {
74  m_current = prev(range1.second);
75  m_is_first = true;
76  } else {
77  m_current--;
78  }
79  return *this;
80  }
82  concat_iterator it(*this);
83  --(*this);
84  return it;
85  }
86  concat_iterator& operator+=(difference_type offset)
87  {
88  if (offset > 0) {
89  auto delta = m_is_first ? offset - std::distance(m_current, range1.second) : -1;
90  if (delta >= 0) {
91  m_is_first = false;
92  m_current = m_range2.first + delta;
93  } else {
94  m_current += offset;
95  }
96  return *this;
97  } else {
98  return *this -= -offset;
99  }
100  }
102  {
103  if (offset > 0) {
104  auto delta = !m_is_first ? offset - (std::distance(m_current, range2.first)) : -1;
105  if (delta >= 1) {
106  m_is_first = true;
107  m_current = range1.second - delta;
108  } else {
109  m_current -= offset;
110  }
111  return *this;
112  } else {
113  return *this += -offset;
114  }
115  }
116  inline reference operator*() const{
117  return *m_current;
118  }
119  inline pointer operator->() const{
120  return m_current.operator->();
121  }
122  concat_iterator operator+(difference_type offset) const{
123  concat_iterator it(*this);
124  it += offset;
125  return it;
126  }
127  concat_iterator operator-(difference_type offset) const {
128  concat_iterator it(*this);
129  it -= offset;
130  return it;
131  }
133  concat_iterator it(*this);
134  it += offset;
135  return *it;
136  }
137 
138 
139 private:
140  range m_range1;
141  range m_range2;
142  iterator m_current;
143  bool m_is_first;
144 };
145 
146 template <typename T1, typename T2>
147 concat_iterator<T1,T2> concat_begin( T1 b1, T1 e1, T2 b2, T2 e2 )
148 {
149  return concat_iterator<T1,T2>(b1,e1,b2,e2);
150 }
151 template <typename T1, typename T2>
152 concat_iterator<T1,T2> concat_end( T1 b1, T1 e1, T2 b2, T2 e2 )
153 {
154  return concat_iterator<T1,T2>(e1,e1,e2,e2);
155 }
156 
157 #endif
true
Definition: DimVarDefs.h:2046
concat_iterator< T1, T2 > concat_begin(T1 b1, T1 e1, T2 b2, T2 e2)
concat_iterator< T1, T2 > concat_end(T1 b1, T1 e1, T2 b2, T2 e2)
GLenum GLint * range
Definition: gles2_ext.h:563
GLintptr offset
Definition: gles2_ext.h:183
bool operator!=(const concat_iterator &other) const
reference operator[](size_type offset) const
bool operator==(const concat_iterator &other) const
bool operator>=(const concat_iterator &other) const
std::size_t size_type
concat_iterator operator++(int)
concat_iterator(const concat_iterator &other)=default
concat_iterator operator--(int)
concat_iterator & operator++()
typename iterator_traits::pointer_type pointer
typename iterator_traits::reference_type reference
concat_iterator(range first, range second)
concat_iterator operator+(difference_type offset) const
concat_iterator & operator-=(difference_type offset)
concat_iterator(concat_iterator &&)=default
std::iterator_traits< concat_iterator > iterator_traits
concat_iterator & operator--()
concat_iterator & operator+=(difference_type offset)
concat_iterator & operator=(const concat_iterator &)=default
pointer operator->() const
concat_iterator & operator=(concat_iterator &&)=default
concat_iterator operator-(difference_type offset) const
std::pair< Iterator, Iterator > range
bool operator>(const concat_iterator &other) const
reference operator*() const
bool operator<=(const concat_iterator &other) const