ezEngine  Milestone 7
StringIterator.h
1 #pragma once
2 
3 #include <Foundation/Strings/StringUtils.h>
4 
5 template <typename Derived>
6 class ezStringBase;
7 
10 template<class STRING>
12 {
13  typedef std::bidirectional_iterator_tag iterator_category;
14  typedef ezUInt32 value_type;
15  typedef ptrdiff_t difference_type;
16  typedef const char* pointer;
17  typedef ezUInt32 reference;
18 
19  EZ_DECLARE_POD_TYPE();
20 
22  EZ_FORCE_INLINE ezStringIterator() : m_String(nullptr), m_pElement(nullptr) { } // [tested]
23 
25  EZ_FORCE_INLINE explicit ezStringIterator(const ezStringBase<STRING>& string, bool bIsEnd) : m_String(&string), m_pElement(nullptr) // [tested]
26  {
27  if (bIsEnd)
28  {
29  m_pElement = m_String->InternalGetDataEnd();
30  }
31  else
32  {
33  m_pElement = m_String->InternalGetData();
34  }
35  }
36 
38  EZ_FORCE_INLINE bool IsValid() const { return m_pElement != nullptr && m_pElement != m_String->InternalGetDataEnd(); } // [tested]
39 
41  EZ_FORCE_INLINE ezUInt32 GetCharacter() const { return IsValid() ? ezUnicodeUtils::ConvertUtf8ToUtf32(m_pElement) : ezUInt32(0); } // [tested]
42 
44  EZ_FORCE_INLINE ezUInt32 Value() const { return GetCharacter(); }
45 
47  EZ_FORCE_INLINE const char* GetData() const { return m_pElement; } // [tested]
48 
50  EZ_FORCE_INLINE bool operator==(const ezStringIterator& it2) const { return (m_pElement == it2.m_pElement); } // [tested]
51 
53  EZ_FORCE_INLINE bool operator!=(const ezStringIterator& it2) const { return (m_pElement != it2.m_pElement); } // [tested]
54 
56  EZ_FORCE_INLINE ezUInt32 operator*() const { return GetCharacter(); } // [tested]
57 
59  EZ_FORCE_INLINE const char* operator->() const { return GetData(); }
60 
62  EZ_FORCE_INLINE ezStringIterator<STRING>& operator++() // [tested]
63  {
64  if (m_pElement < m_String->InternalGetDataEnd())
66  return *this;
67  }
68 
70  EZ_FORCE_INLINE ezStringIterator<STRING>& operator--() // [tested]
71  {
72  if (m_String->InternalGetData() < m_pElement)
74  return *this;
75  }
76 
78  EZ_FORCE_INLINE ezStringIterator<STRING> operator++(int) // [tested]
79  {
80  ezStringIterator<STRING> tmp = *this;
81  ++(*this);
82  return tmp;
83  }
84 
86  EZ_FORCE_INLINE ezStringIterator<STRING> operator--(int) // [tested]
87  {
88  ezStringIterator<STRING> tmp = *this;
89  --(*this);
90  return tmp;
91  }
92 
94  EZ_FORCE_INLINE void operator+=(difference_type d) // [tested]
95  {
96  while (d > 0)
97  {
98  ++(*this);
99  --d;
100  }
101  while (d < 0)
102  {
103  --(*this);
104  ++d;
105  }
106  }
107 
109  EZ_FORCE_INLINE void operator-=(difference_type d) // [tested]
110  {
111  while (d > 0)
112  {
113  --(*this);
114  --d;
115  }
116  while (d < 0)
117  {
118  ++(*this);
119  ++d;
120  }
121  }
122 
124  EZ_FORCE_INLINE ezStringIterator<STRING> operator+(difference_type d) const // [tested]
125  {
126  ezStringIterator<STRING> it = *this;
127  it += d;
128  return it;
129  }
130 
132  EZ_FORCE_INLINE ezStringIterator<STRING> operator-(difference_type d) const // [tested]
133  {
134  ezStringIterator<STRING> it = *this;
135  it -= d;
136  return it;
137  }
138 
142  void SetCurrentPosition(const char* szCurPos)
143  {
144  const char* szEnd = m_String->InternalGetDataEnd();
145  EZ_ASSERT_DEV((szCurPos >= m_String->InternalGetData()) && (szCurPos <= szEnd), "New current position must still be inside the iterator's range.");
146 
147  m_pElement = szCurPos;
148  }
149 
150 protected:
151  const ezStringBase<STRING>* m_String;
152  const char* m_pElement;
153 };
154 
155 
158 template<class STRING>
160 {
161  typedef std::bidirectional_iterator_tag iterator_category;
162  typedef ezUInt32 value_type;
163  typedef ptrdiff_t difference_type;
164  typedef const char* pointer;
165  typedef ezUInt32 reference;
166 
167  EZ_DECLARE_POD_TYPE();
168 
170  EZ_FORCE_INLINE ezStringReverseIterator() : m_String(nullptr), m_pElement(nullptr) { } // [tested]
171 
173  EZ_FORCE_INLINE explicit ezStringReverseIterator(const ezStringBase<STRING>& string, bool bIsEnd) : m_String(&string), m_pElement(nullptr) // [tested]
174  {
175  if (bIsEnd)
176  {
177  m_pElement = nullptr;
178  }
179  else
180  {
181  m_pElement = m_String->InternalGetDataEnd();
183  }
184  }
185 
187  EZ_FORCE_INLINE bool IsValid() const { return (m_pElement != nullptr); } // [tested]
188 
190  EZ_FORCE_INLINE ezUInt32 GetCharacter() const { return IsValid() ? ezUnicodeUtils::ConvertUtf8ToUtf32(m_pElement) : ezUInt32(0); } // [tested]
191 
193  EZ_FORCE_INLINE const char* GetData() const { return m_pElement; } // [tested]
194 
196  EZ_FORCE_INLINE bool operator==(const ezStringReverseIterator& it2) const { return (m_pElement == it2.m_pElement); } // [tested]
197 
199  EZ_FORCE_INLINE bool operator!=(const ezStringReverseIterator& it2) const { return (m_pElement != it2.m_pElement); } // [tested]
200 
202  EZ_FORCE_INLINE ezUInt32 operator*() const { return GetCharacter(); } // [tested]
203 
205  EZ_FORCE_INLINE const char* operator->() const { return GetData(); } // [tested]
206 
208  EZ_FORCE_INLINE ezStringReverseIterator<STRING>& operator++() // [tested]
209  {
210  if (m_pElement != nullptr && m_String->InternalGetData() < m_pElement)
212  else
213  m_pElement = nullptr;
214  return *this;
215  }
216 
218  EZ_FORCE_INLINE ezStringReverseIterator<STRING>& operator--() // [tested]
219  {
220  if (m_pElement != nullptr)
221  {
222  const char* szOldPos = m_pElement;
223  ezUnicodeUtils::MoveToNextUtf8(m_pElement);
224  if (m_pElement == m_String->InternalGetDataEnd())
225  m_pElement = szOldPos;
226  }
227  else
228  {
229  // Set back to the first character.
230  m_pElement = m_String->InternalGetData();
231  }
232  return *this;
233  }
234 
236  EZ_FORCE_INLINE ezStringReverseIterator<STRING> operator++(int) // [tested]
237  {
239  ++(*this);
240  return tmp;
241  }
242 
244  EZ_FORCE_INLINE ezStringReverseIterator<STRING> operator--(int) // [tested]
245  {
247  --(*this);
248  return tmp;
249  }
250 
252  EZ_FORCE_INLINE void operator+=(difference_type d) // [tested]
253  {
254  while (d > 0)
255  {
256  ++(*this);
257  --d;
258  }
259  while (d < 0)
260  {
261  --(*this);
262  ++d;
263  }
264  }
265 
267  EZ_FORCE_INLINE void operator-=(difference_type d) // [tested]
268  {
269  while (d > 0)
270  {
271  --(*this);
272  --d;
273  }
274  while (d < 0)
275  {
276  ++(*this);
277  ++d;
278  }
279  }
280 
282  EZ_FORCE_INLINE ezStringReverseIterator<STRING> operator+(difference_type d) const // [tested]
283  {
285  it += d;
286  return it;
287  }
288 
290  EZ_FORCE_INLINE ezStringReverseIterator<STRING> operator-(difference_type d) const // [tested]
291  {
293  it -= d;
294  return it;
295  }
296 
300  EZ_FORCE_INLINE void SetCurrentPosition(const char* szCurPos)
301  {
302  const char* szBegin = m_String->InternalGetData();
303  const char* szEnd = m_String->InternalGetDataEnd();
304  EZ_ASSERT_DEV(szCurPos == nullptr || (szCurPos >= szBegin) && (szCurPos < szEnd), "New current position must still be inside the iterator's range.");
305 
306  m_pElement = szCurPos;
307  }
308 
309 protected:
310  const ezStringBase<STRING>* m_String;
311  const char* m_pElement;
312 };
313