CsString  1.4.0
cs_string_iterator.h
1 /***********************************************************************
2 *
3 * Copyright (c) 2017-2024 Barbara Geller
4 * Copyright (c) 2017-2024 Ansel Sermersheim
5 *
6 * This file is part of CsString.
7 *
8 * CsString is free software, released under the BSD 2-Clause license.
9 * For license details refer to LICENSE provided with this project.
10 *
11 * CsString is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 *
15 * https://opensource.org/licenses/BSD-2-Clause
16 *
17 ***********************************************************************/
18 
19 #ifndef LIB_CS_STRING_ITERATOR_H
20 #define LIB_CS_STRING_ITERATOR_H
21 
22 #include <cstddef>
23 #include <vector>
24 
25 #include <cs_char.h>
26 
27 namespace CsString {
28 
29 class LIB_CS_STRING_EXPORT CsCharArrow
30 {
31  public:
32  CsCharArrow (CsChar c)
33  : m_data(c)
34  { }
35 
36  const CsChar *operator->() const {
37  return &m_data;
38  }
39 
40  private:
41  CsChar m_data;
42 };
43 
44 template <typename E, typename A>
45 class CsStringIterator
46 {
47  using v_iter = typename std::vector<typename E::storage_unit, A>::const_iterator;
48 
49  public:
50  using difference_type = std::ptrdiff_t;
51  using pointer = CsChar *;
52  using reference = CsChar;
53  using size_type = std::ptrdiff_t;
54  using value_type = CsChar;
55  using iterator_category = std::random_access_iterator_tag;
56 
57  CsStringIterator() = default;
58 
59  CsChar operator*() const;
60  CsCharArrow operator->() const;
61 
62  CsChar operator[](size_type n) const;
63 
64  // comparisons
65  bool operator!=(const CsStringIterator &other) const;
66  bool operator==(const CsStringIterator &other) const;
67  bool operator<(const CsStringIterator &other) const;
68  bool operator<=(const CsStringIterator &other) const;
69  bool operator>(const CsStringIterator &other) const;
70  bool operator>=(const CsStringIterator &other) const;
71 
72  // math
73  CsStringIterator &operator+=(size_type n);
74  CsStringIterator &operator-=(size_type n);
75 
76  CsStringIterator operator+(size_type n) const;
77  CsStringIterator &operator++();
78  CsStringIterator operator++(int);
79 
80  CsStringIterator operator-(size_type n) const;
81  size_type operator-(CsStringIterator other) const;
82  CsStringIterator &operator--();
83  CsStringIterator operator--(int);
84 
85  typename std::pair<v_iter, v_iter> codePointRange() const;
86  v_iter codePointBegin() const;
87  v_iter codePointEnd() const;
88 
89  private:
90  explicit CsStringIterator(v_iter data);
91  v_iter m_iter;
92 
93  friend class CsBasicString<E, A>;
94 };
95 
96 template <typename E, typename A>
97 CsChar CsStringIterator<E,A>::operator*() const
98 {
99  return E::getCodePoint(m_iter);
100 }
101 
102 template <typename E, typename A>
103 CsCharArrow CsStringIterator<E,A>::operator->() const
104 {
105  return E::getCodePoint(m_iter);
106 }
107 
108 template <typename E, typename A>
109 CsChar CsStringIterator<E,A>:: operator[](size_type n) const
110 {
111  // calls operator+()
112  return *(*this + n);
113 }
114 
115 // comparisons
116 template <typename E, typename A>
117 bool CsStringIterator <E,A>::operator!=(const CsStringIterator &other) const
118 {
119  return m_iter != other.m_iter;
120 }
121 
122 template <typename E, typename A>
123 bool CsStringIterator <E,A>::operator==(const CsStringIterator &other) const
124 {
125  return m_iter == other.m_iter;
126 }
127 
128 template <typename E, typename A>
129 bool CsStringIterator <E,A>::operator<(const CsStringIterator &other) const
130 {
131  return m_iter < other.m_iter;
132 }
133 
134 template <typename E, typename A>
135 bool CsStringIterator <E,A>::operator<=(const CsStringIterator &other) const
136 {
137  return m_iter <= other.m_iter;
138 }
139 
140 template <typename E, typename A>
141 bool CsStringIterator <E,A>::operator>(const CsStringIterator &other) const
142 {
143  return m_iter > other.m_iter;
144 }
145 
146 template <typename E, typename A>
147 bool CsStringIterator <E,A>::operator>=(const CsStringIterator &other) const
148 {
149  return m_iter >= other.m_iter;
150 }
151 
152 // math
153 template <typename E, typename A>
154 CsStringIterator<E,A> &CsStringIterator<E,A>::operator+=(size_type n)
155 {
156  m_iter += E::walk(n, m_iter);
157  return *this;
158 }
159 
160 template <typename E, typename A>
161 CsStringIterator<E,A> &CsStringIterator<E,A>::operator-=(size_type n)
162 {
163  m_iter += E::walk(-n, m_iter);
164  return *this;
165 }
166 
167 template <typename E, typename A>
168 CsStringIterator<E,A> CsStringIterator<E,A>::operator+(size_type n) const
169 {
170  auto iter = m_iter + E::walk(n, m_iter);
171  return CsStringIterator(iter);
172 }
173 
174 template <typename E, typename A>
175 CsStringIterator<E,A> &CsStringIterator<E,A>::operator++()
176 {
177  m_iter += E::walk(1, m_iter);
178  return *this;
179 }
180 
181 template <typename E, typename A>
182 CsStringIterator<E,A> CsStringIterator<E,A>::operator++(int)
183 {
184  CsStringIterator retval = *this;
185  m_iter += E::walk(1, m_iter);
186 
187  return retval;
188 }
189 
190 template <typename E, typename A>
191 CsStringIterator<E,A> CsStringIterator<E,A>::operator-(size_type n) const
192 {
193  auto iter = m_iter + E::walk(-n, m_iter);
194  return CsStringIterator(iter);
195 }
196 
197 template <typename E, typename A>
198 typename CsStringIterator<E, A>::size_type CsStringIterator <E,A>::operator-(CsStringIterator other) const
199 {
200  CsStringIterator a = *this;
201  CsStringIterator b = other;
202 
203  if (a < b) {
204  return 0 - E::distance(a.m_iter, b.m_iter);
205 
206  } else {
207  return E::distance(b.m_iter, a.m_iter);
208 
209  }
210 }
211 
212 template <typename E, typename A>
213 CsStringIterator<E,A> &CsStringIterator<E,A>::operator--()
214 {
215  m_iter+= E::walk(-1, m_iter);
216  return *this;
217 }
218 
219 template <typename E, typename A>
220 CsStringIterator<E,A> CsStringIterator<E,A>::operator--(int)
221 {
222  CsStringIterator retval = *this;
223  m_iter += E::walk(-1, m_iter);
224 
225  return retval;
226 }
227 
228 // private methods
229 template <typename E, typename A>
230 CsStringIterator<E,A>::CsStringIterator(v_iter data)
231 {
232  m_iter = data;
233 }
234 
235 template <typename E, typename A>
236 auto CsStringIterator<E,A>::codePointRange() const -> typename std::pair<v_iter, v_iter>
237 {
238  return std::make_pair(m_iter, m_iter + E::walk(1, m_iter));
239 }
240 
241 template <typename E, typename A>
242 auto CsStringIterator<E,A>::codePointBegin() const -> v_iter
243 {
244  return m_iter;
245 }
246 
247 template <typename E, typename A>
248 auto CsStringIterator<E,A>::codePointEnd() const -> v_iter
249 {
250  return m_iter + E::walk(1, m_iter);
251 }
252 
253 // reverse iterator dereference needs to return by value
254 template <typename T>
255 class CsStringReverseIterator : public std::reverse_iterator<T>
256 {
257  public:
258  CsStringReverseIterator() = default;
259 
260  CsStringReverseIterator(T iter)
261  : std::reverse_iterator<T>(iter)
262  {
263  }
264 
265  template <typename U>
266  CsStringReverseIterator(CsStringReverseIterator<U> iter)
267  : std::reverse_iterator<T>(iter.base())
268  {
269  }
270 
271  decltype(std::declval<T>().operator*()) operator*() const;
272  decltype(std::declval<T>().operator->()) operator->() const;
273 };
274 
275 template <typename T>
276 decltype(std::declval<T>().operator*()) CsStringReverseIterator<T>::operator*() const
277 {
278  auto tmp = this->base();
279  return (--tmp).operator*();
280 }
281 
282 template <typename T>
283 decltype(std::declval<T>().operator->()) CsStringReverseIterator<T>::operator->() const
284 {
285  auto tmp = this->base();
286  return (--tmp).operator->();
287 }
288 
289 }
290 
291 #endif
#define LIB_CS_STRING_EXPORT
Definition: cs_char.h:34