ezEngine  Milestone 9
StringIterator.h
1 #pragma once
2 
3 #include <Foundation/Strings/StringUtils.h>
4 
5 template <typename Derived>
6 struct 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_ALWAYS_INLINE ezStringIterator()
23  : m_String(nullptr)
24  , m_pElement(nullptr)
25  {
26  } // [tested]
27 
29  EZ_FORCE_INLINE explicit ezStringIterator(const ezStringBase<STRING>& string, bool bIsEnd)
30  : m_String(&string)
31  , m_pElement(nullptr) // [tested]
32  {
33  if (bIsEnd)
34  {
35  m_pElement = m_String->InternalGetDataEnd();
36  }
37  else
38  {
39  m_pElement = m_String->InternalGetData();
40  }
41  }
42 
45  EZ_ALWAYS_INLINE bool IsValid() const { return m_pElement != nullptr && m_pElement != m_String->InternalGetDataEnd(); } // [tested]
46 
48  EZ_ALWAYS_INLINE ezUInt32 GetCharacter() const
49  {
50  return IsValid() ? ezUnicodeUtils::ConvertUtf8ToUtf32(m_pElement) : ezUInt32(0);
51  } // [tested]
52 
54  EZ_ALWAYS_INLINE ezUInt32 Value() const { return GetCharacter(); }
55 
57  EZ_ALWAYS_INLINE const char* GetData() const { return m_pElement; } // [tested]
58 
60  EZ_ALWAYS_INLINE bool operator==(const ezStringIterator& it2) const { return (m_pElement == it2.m_pElement); } // [tested]
61 
63  EZ_ALWAYS_INLINE bool operator!=(const ezStringIterator& it2) const { return (m_pElement != it2.m_pElement); } // [tested]
64 
66  EZ_ALWAYS_INLINE ezUInt32 operator*() const { return GetCharacter(); } // [tested]
67 
69  EZ_ALWAYS_INLINE const char* operator->() const { return GetData(); }
70 
72  EZ_ALWAYS_INLINE ezStringIterator<STRING>& operator++() // [tested]
73  {
74  if (m_pElement < m_String->InternalGetDataEnd())
76  return *this;
77  }
78 
80  EZ_ALWAYS_INLINE ezStringIterator<STRING>& operator--() // [tested]
81  {
82  if (m_String->InternalGetData() < m_pElement)
84  return *this;
85  }
86 
88  EZ_ALWAYS_INLINE ezStringIterator<STRING> operator++(int) // [tested]
89  {
90  ezStringIterator<STRING> tmp = *this;
91  ++(*this);
92  return tmp;
93  }
94 
96  EZ_ALWAYS_INLINE ezStringIterator<STRING> operator--(int) // [tested]
97  {
98  ezStringIterator<STRING> tmp = *this;
99  --(*this);
100  return tmp;
101  }
102 
104  EZ_FORCE_INLINE void operator+=(difference_type d) // [tested]
105  {
106  while (d > 0)
107  {
108  ++(*this);
109  --d;
110  }
111  while (d < 0)
112  {
113  --(*this);
114  ++d;
115  }
116  }
117 
119  EZ_FORCE_INLINE void operator-=(difference_type d) // [tested]
120  {
121  while (d > 0)
122  {
123  --(*this);
124  --d;
125  }
126  while (d < 0)
127  {
128  ++(*this);
129  ++d;
130  }
131  }
132 
134  EZ_ALWAYS_INLINE ezStringIterator<STRING> operator+(difference_type d) const // [tested]
135  {
136  ezStringIterator<STRING> it = *this;
137  it += d;
138  return it;
139  }
140 
142  EZ_ALWAYS_INLINE ezStringIterator<STRING> operator-(difference_type d) const // [tested]
143  {
144  ezStringIterator<STRING> it = *this;
145  it -= d;
146  return it;
147  }
148 
152  void SetCurrentPosition(const char* szCurPos)
153  {
154  const char* szEnd = m_String->InternalGetDataEnd();
155  EZ_ASSERT_DEV((szCurPos >= m_String->InternalGetData()) && (szCurPos <= szEnd),
156  "New current position must still be inside the iterator's range.");
157 
158  m_pElement = szCurPos;
159  }
160 
161 protected:
162  const ezStringBase<STRING>* m_String;
163  const char* m_pElement;
164 };
165 
166 
169 template <class STRING>
171 {
172  typedef std::bidirectional_iterator_tag iterator_category;
173  typedef ezUInt32 value_type;
174  typedef ptrdiff_t difference_type;
175  typedef const char* pointer;
176  typedef ezUInt32 reference;
177 
178  EZ_DECLARE_POD_TYPE();
179 
181  EZ_ALWAYS_INLINE ezStringReverseIterator()
182  : m_String(nullptr)
183  , m_pElement(nullptr)
184  {
185  } // [tested]
186 
188  EZ_FORCE_INLINE explicit ezStringReverseIterator(const ezStringBase<STRING>& string, bool bIsEnd)
189  : m_String(&string)
190  , m_pElement(nullptr) // [tested]
191  {
192  if (bIsEnd)
193  {
194  m_pElement = nullptr;
195  }
196  else
197  {
198  m_pElement = m_String->InternalGetDataEnd();
200  }
201  }
202 
204  EZ_ALWAYS_INLINE bool IsValid() const { return (m_pElement != nullptr); } // [tested]
205 
207  EZ_ALWAYS_INLINE ezUInt32 GetCharacter() const
208  {
209  return IsValid() ? ezUnicodeUtils::ConvertUtf8ToUtf32(m_pElement) : ezUInt32(0);
210  } // [tested]
211 
213  EZ_ALWAYS_INLINE const char* GetData() const { return m_pElement; } // [tested]
214 
216  EZ_ALWAYS_INLINE bool operator==(const ezStringReverseIterator& it2) const { return (m_pElement == it2.m_pElement); } // [tested]
217 
219  EZ_ALWAYS_INLINE bool operator!=(const ezStringReverseIterator& it2) const { return (m_pElement != it2.m_pElement); } // [tested]
220 
222  EZ_ALWAYS_INLINE ezUInt32 operator*() const { return GetCharacter(); } // [tested]
223 
225  EZ_ALWAYS_INLINE const char* operator->() const { return GetData(); } // [tested]
226 
228  EZ_FORCE_INLINE ezStringReverseIterator<STRING>& operator++() // [tested]
229  {
230  if (m_pElement != nullptr && m_String->InternalGetData() < m_pElement)
232  else
233  m_pElement = nullptr;
234  return *this;
235  }
236 
238  EZ_FORCE_INLINE ezStringReverseIterator<STRING>& operator--() // [tested]
239  {
240  if (m_pElement != nullptr)
241  {
242  const char* szOldPos = m_pElement;
243  ezUnicodeUtils::MoveToNextUtf8(m_pElement);
244  if (m_pElement == m_String->InternalGetDataEnd())
245  m_pElement = szOldPos;
246  }
247  else
248  {
249  // Set back to the first character.
250  m_pElement = m_String->InternalGetData();
251  }
252  return *this;
253  }
254 
256  EZ_ALWAYS_INLINE ezStringReverseIterator<STRING> operator++(int) // [tested]
257  {
259  ++(*this);
260  return tmp;
261  }
262 
264  EZ_ALWAYS_INLINE ezStringReverseIterator<STRING> operator--(int) // [tested]
265  {
267  --(*this);
268  return tmp;
269  }
270 
272  EZ_FORCE_INLINE void operator+=(difference_type d) // [tested]
273  {
274  while (d > 0)
275  {
276  ++(*this);
277  --d;
278  }
279  while (d < 0)
280  {
281  --(*this);
282  ++d;
283  }
284  }
285 
287  EZ_FORCE_INLINE void operator-=(difference_type d) // [tested]
288  {
289  while (d > 0)
290  {
291  --(*this);
292  --d;
293  }
294  while (d < 0)
295  {
296  ++(*this);
297  ++d;
298  }
299  }
300 
302  EZ_ALWAYS_INLINE ezStringReverseIterator<STRING> operator+(difference_type d) const // [tested]
303  {
305  it += d;
306  return it;
307  }
308 
310  EZ_ALWAYS_INLINE ezStringReverseIterator<STRING> operator-(difference_type d) const // [tested]
311  {
313  it -= d;
314  return it;
315  }
316 
320  EZ_FORCE_INLINE void SetCurrentPosition(const char* szCurPos)
321  {
322  const char* szBegin = m_String->InternalGetData();
323  const char* szEnd = m_String->InternalGetDataEnd();
324  EZ_ASSERT_DEV(szCurPos == nullptr || ((szCurPos >= szBegin) && (szCurPos < szEnd)),
325  "New current position must still be inside the iterator's range.");
326 
327  m_pElement = szCurPos;
328  }
329 
330 protected:
331  const ezStringBase<STRING>* m_String;
332  const char* m_pElement;
333 };
334 
void SetCurrentPosition(const char *szCurPos)
Allows to set the &#39;current&#39; iteration position to a different value.
Definition: StringIterator.h:152
EZ_ALWAYS_INLINE bool operator!=(const ezStringIterator &it2) const
Checks whether the two iterators point to the same element.
Definition: StringIterator.h:63
EZ_ALWAYS_INLINE ezStringReverseIterator< STRING > operator++(int)
Move to the next Utf8 character.
Definition: StringIterator.h:256
EZ_FORCE_INLINE ezStringReverseIterator< STRING > & operator--()
Move to the previous Utf8 character.
Definition: StringIterator.h:238
EZ_ALWAYS_INLINE const char * GetData() const
Returns the address the iterator currently points to.
Definition: StringIterator.h:213
EZ_ALWAYS_INLINE bool operator!=(const ezStringReverseIterator &it2) const
Checks whether the two iterators point to the same element.
Definition: StringIterator.h:219
EZ_ALWAYS_INLINE ezStringIterator()
Constructs an invalid iterator.
Definition: StringIterator.h:22
EZ_ALWAYS_INLINE const char * operator->() const
Returns the address the iterator currently points to.
Definition: StringIterator.h:225
static void MoveToNextUtf8(const char *&szUtf8, ezUInt32 uiNumCharacters=1)
Moves the given string pointer ahead to the next Utf8 character sequence.
Definition: UnicodeUtils_inl.h:178
EZ_ALWAYS_INLINE ezStringIterator< STRING > operator++(int)
Move to the next Utf8 character.
Definition: StringIterator.h:88
EZ_ALWAYS_INLINE bool IsValid() const
Checks whether this iterator points to a valid element. Invalid iterators either point to end(m_Strin...
Definition: StringIterator.h:45
EZ_ALWAYS_INLINE ezStringIterator< STRING > operator-(difference_type d) const
Returns an iterator that is advanced backwards by d characters.
Definition: StringIterator.h:142
EZ_FORCE_INLINE void operator+=(difference_type d)
Advances the iterator forwards by d characters. Does not move it beyond the range&#39;s end...
Definition: StringIterator.h:272
EZ_ALWAYS_INLINE const char * GetData() const
Returns the address the iterator currently points to.
Definition: StringIterator.h:57
EZ_FORCE_INLINE ezStringReverseIterator(const ezStringBase< STRING > &string, bool bIsEnd)
Constructs either a rbegin or rend iterator for the given string.
Definition: StringIterator.h:188
EZ_FORCE_INLINE ezStringIterator(const ezStringBase< STRING > &string, bool bIsEnd)
Constructs either a begin or end iterator for the given string.
Definition: StringIterator.h:29
EZ_ALWAYS_INLINE ezUInt32 operator*() const
Returns the currently pointed to character in Utf32 encoding.
Definition: StringIterator.h:66
#define EZ_ASSERT_DEV(bCondition, szErrorMsg,...)
Macro to raise an error, if a condition is not met.
Definition: Assert.h:116
EZ_ALWAYS_INLINE bool IsValid() const
Checks whether this iterator points to a valid element.
Definition: StringIterator.h:204
EZ_FORCE_INLINE ezStringReverseIterator< STRING > & operator++()
Move to the next Utf8 character.
Definition: StringIterator.h:228
EZ_FORCE_INLINE void operator+=(difference_type d)
Advances the iterator forwards by d characters. Does not move it beyond the range&#39;s end...
Definition: StringIterator.h:104
EZ_FORCE_INLINE void operator-=(difference_type d)
Moves the iterator backwards by d characters. Does not move it beyond the range&#39;s start...
Definition: StringIterator.h:119
EZ_ALWAYS_INLINE const char * operator->() const
Returns the address the iterator currently points to.
Definition: StringIterator.h:69
EZ_ALWAYS_INLINE bool operator==(const ezStringReverseIterator &it2) const
Checks whether the two iterators point to the same element.
Definition: StringIterator.h:216
EZ_ALWAYS_INLINE ezStringIterator< STRING > operator--(int)
Move to the previous Utf8 character.
Definition: StringIterator.h:96
EZ_ALWAYS_INLINE ezUInt32 GetCharacter() const
Returns the currently pointed to character in Utf32 encoding.
Definition: StringIterator.h:48
EZ_ALWAYS_INLINE ezStringIterator< STRING > & operator++()
Move to the next Utf8 character.
Definition: StringIterator.h:72
EZ_ALWAYS_INLINE ezStringReverseIterator< STRING > operator-(difference_type d) const
Returns an iterator that is advanced backwards by d characters.
Definition: StringIterator.h:310
EZ_ALWAYS_INLINE ezStringReverseIterator()
Constructs an invalid iterator.
Definition: StringIterator.h:181
EZ_ALWAYS_INLINE ezStringIterator< STRING > operator+(difference_type d) const
Returns an iterator that is advanced forwards by d characters.
Definition: StringIterator.h:134
EZ_ALWAYS_INLINE bool operator==(const ezStringIterator &it2) const
Checks whether the two iterators point to the same element.
Definition: StringIterator.h:60
EZ_FORCE_INLINE void operator-=(difference_type d)
Moves the iterator backwards by d characters. Does not move it beyond the range&#39;s start...
Definition: StringIterator.h:287
Base class for strings, which implements all read-only string functions.
Definition: StringBase.h:18
STL reverse iterator used by all string classes. Iterates over unicode characters. The iterator starts at the last character of the string and ends at the address before the first character of the string.
Definition: StringIterator.h:170
EZ_ALWAYS_INLINE ezUInt32 GetCharacter() const
Returns the currently pointed to character in Utf32 encoding.
Definition: StringIterator.h:207
STL forward iterator used by all string classes. Iterates over unicode characters. The iterator starts at the first character of the string and ends at the address beyond the last character of the string.
Definition: StringIterator.h:11
EZ_ALWAYS_INLINE ezStringIterator< STRING > & operator--()
Move to the previous Utf8 character.
Definition: StringIterator.h:80
static void MoveToPriorUtf8(const char *&szUtf8, ezUInt32 uiNumCharacters=1)
Moves the given string pointer backwards to the previous Utf8 character sequence. ...
Definition: UnicodeUtils_inl.h:195
EZ_FORCE_INLINE void SetCurrentPosition(const char *szCurPos)
Allows to set the &#39;current&#39; iteration position to a different value.
Definition: StringIterator.h:320
EZ_ALWAYS_INLINE ezUInt32 Value() const
Returns the currently pointed to character in Utf32 encoding.
Definition: StringIterator.h:54
EZ_ALWAYS_INLINE ezUInt32 operator*() const
Returns the currently pointed to character in Utf32 encoding.
Definition: StringIterator.h:222
static ezUInt32 ConvertUtf8ToUtf32(const char *pFirstChar)
Converts the UTF-8 character that starts at pFirstChar into a UTF-32 character.
Definition: UnicodeUtils_inl.h:105
EZ_ALWAYS_INLINE ezStringReverseIterator< STRING > operator--(int)
Move to the previous Utf8 character.
Definition: StringIterator.h:264
EZ_ALWAYS_INLINE ezStringReverseIterator< STRING > operator+(difference_type d) const
Returns an iterator that is advanced forwards by d characters.
Definition: StringIterator.h:302