Embedded Template Library  1.0
iterator.h
Go to the documentation of this file.
1 
3 /******************************************************************************
4 The MIT License(MIT)
5 
6 Embedded Template Library.
7 https://github.com/ETLCPP/etl
8 https://www.etlcpp.com
9 
10 Copyright(c) 2017 jwellbelove
11 
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files(the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions :
18 
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21 
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29 ******************************************************************************/
30 
31 #ifndef ETL_ITERATOR_INCLUDED
32 #define ETL_ITERATOR_INCLUDED
33 
34 #include "platform.h"
35 #include "type_traits.h"
36 #include "utility.h"
37 
38 #if ETL_USING_STL || defined(ETL_IN_UNIT_TEST)
39  #include <iterator>
40 #endif
41 
44 
45 namespace etl
46 {
47  //***************************************************************************
48  // iterator tags
49  struct input_iterator_tag {};
54 
55  //***************************************************************************
56  // iterator_traits
57  template <typename TIterator>
59  {
60  typedef typename TIterator::iterator_category iterator_category;
61  typedef typename TIterator::value_type value_type;
62  typedef typename TIterator::difference_type difference_type;
63  typedef typename TIterator::pointer pointer;
64  typedef typename TIterator::reference reference;
65  };
66 
67  template <typename T>
68  struct iterator_traits<T*>
69  {
70  typedef ETL_OR_STD::random_access_iterator_tag iterator_category;
71  typedef T value_type;
72  typedef ptrdiff_t difference_type;
73  typedef T* pointer;
74  typedef T& reference;
75  };
76 
77  template <typename T>
78  struct iterator_traits<const T*>
79  {
80  typedef ETL_OR_STD::random_access_iterator_tag iterator_category;
81  typedef T value_type;
82  typedef ptrdiff_t difference_type;
83  typedef const T* pointer;
84  typedef const T& reference;
85  };
86 
87  //***************************************************************************
88  // advance
89 #if ETL_NOT_USING_STL
90 
91  template <typename TIterator, typename TDistance>
92  ETL_CONSTEXPR17 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::output_iterator_tag)
93  {
94  while (n--)
95  {
96  ++itr;
97  }
98  }
99 
100  template <typename TIterator, typename TDistance>
101  ETL_CONSTEXPR17 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::forward_iterator_tag)
102  {
103  while (n--)
104  {
105  ++itr;
106  }
107  }
108 
109  template <typename TIterator, typename TDistance>
110  ETL_CONSTEXPR17 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::bidirectional_iterator_tag)
111  {
112  if (n > 0)
113  {
114  while (n--)
115  {
116  ++itr;
117  }
118  }
119  else
120  {
121  while (n++)
122  {
123  --itr;
124  }
125  }
126  }
127 
128  template <typename TIterator, typename TDistance>
129  ETL_CONSTEXPR17 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::random_access_iterator_tag)
130  {
131  itr += n;
132  }
133 
134  template <typename TIterator, typename TDistance>
135  ETL_CONSTEXPR17 void advance(TIterator& itr, TDistance n)
136  {
137  typedef typename etl::iterator_traits<TIterator>::iterator_category tag;
138 
139  advance_helper(itr, n, tag());
140  }
141 
142 #else
143 
144  template <typename TIterator, typename TDistance>
145  ETL_CONSTEXPR17 void advance(TIterator& itr, TDistance n)
146  {
147  std::advance(itr, n);
148  }
149 
150 #endif
151 
152  //***************************************************************************
153  // distance
154 #if ETL_NOT_USING_STL
155  template<typename TIterator>
156  ETL_CONSTEXPR17 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::input_iterator_tag)
157  {
158  typename etl::iterator_traits<TIterator>::difference_type d = 0;
159 
160  while (first != last)
161  {
162  ++d;
163  ++first;
164  }
165 
166  return d;
167  }
168 
169  template<typename TIterator>
170  ETL_CONSTEXPR17 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::forward_iterator_tag)
171  {
172  typename etl::iterator_traits<TIterator>::difference_type d = 0;
173 
174  while (first != last)
175  {
176  ++d;
177  ++first;
178  }
179 
180  return d;
181  }
182 
183  template<typename TIterator>
184  ETL_CONSTEXPR17 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::bidirectional_iterator_tag)
185  {
186  typename etl::iterator_traits<TIterator>::difference_type d = 0;
187 
188  while (first != last)
189  {
190  ++d;
191  ++first;
192  }
193 
194  return d;
195  }
196 
197  template<typename TIterator>
198  ETL_CONSTEXPR17 typename etl::iterator_traits<TIterator>::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::random_access_iterator_tag)
199  {
200  return last - first;
201  }
202 
203  template<typename TIterator>
204  ETL_CONSTEXPR17 typename etl::iterator_traits<TIterator>::difference_type distance(TIterator first, TIterator last)
205  {
206  typedef typename etl::iterator_traits<TIterator>::iterator_category tag;
207 
208  return distance_helper(first, last, tag());
209  }
210 
211 #else
212 
213  template<typename TIterator>
214  ETL_CONSTEXPR17 typename std::iterator_traits<TIterator>::difference_type distance(TIterator first, TIterator last)
215  {
216  return std::distance(first, last);
217  }
218 
219 #endif
220 
221  //***************************************************************************
222  // Previous
223  template<typename TIterator>
224  ETL_CONSTEXPR17 TIterator prev(TIterator itr, typename etl::iterator_traits<TIterator>::difference_type n = 1)
225  {
226 #if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED
227  etl::advance(itr, -n);
228 #else
229  std::advance(itr, -n);
230 #endif
231  return itr;
232  }
233 
234  //***************************************************************************
235  // Next
236  template<typename TIterator>
237  ETL_CONSTEXPR17 TIterator next(TIterator itr, typename etl::iterator_traits<TIterator>::difference_type n = 1)
238  {
239 #if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED
240  etl::advance(itr, n);
241 #else
242  std::advance(itr, n);
243 #endif
244  return itr;
245  }
246 
247  //***************************************************************************
248  // reverse_iterator
249  template <typename TIterator>
251  {
252  public:
253 
254  typedef typename iterator_traits<TIterator>::iterator_category iterator_category;
255  typedef typename iterator_traits<TIterator>::value_type value_type;
256  typedef typename iterator_traits<TIterator>::difference_type difference_type;
257  typedef typename iterator_traits<TIterator>::pointer pointer;
258  typedef typename iterator_traits<TIterator>::reference reference;
259 
260  typedef TIterator iterator_type;
261 
262  ETL_CONSTEXPR17 reverse_iterator()
263  : current()
264  {
265  }
266 
267  ETL_CONSTEXPR17 explicit reverse_iterator(TIterator itr)
268  : current(itr)
269  {
270  }
271 
272  template <typename TOther>
273  ETL_CONSTEXPR17 reverse_iterator(const reverse_iterator<TOther>& other)
274  : current(other.base())
275  {
276  }
277 
278  template<class TOther>
279  ETL_CONSTEXPR17 reverse_iterator& operator=(const reverse_iterator<TOther>& other)
280  {
281  current = other.base();
282 
283  return (*this);
284  }
285 
286  ETL_CONSTEXPR17 TIterator base() const
287  {
288  return current;
289  }
290 
291  ETL_NODISCARD ETL_CONSTEXPR17 reference operator*() const
292  {
293  TIterator temp = current;
294 
295  return *(--temp);
296  }
297 
298  ETL_NODISCARD ETL_CONSTEXPR17 pointer operator->() const
299  {
300  TIterator temp = current;
301 
302  return &(*--temp);
303  }
304 
305  ETL_CONSTEXPR17 reverse_iterator& operator++()
306  {
307  --current;
308 
309  return *this;
310  }
311 
312  ETL_CONSTEXPR17 reverse_iterator operator++(int)
313  {
314  reverse_iterator temp = *this;
315  --current;
316 
317  return temp;
318  }
319 
320  ETL_CONSTEXPR17 reverse_iterator& operator--()
321  {
322  ++current;
323 
324  return (*this);
325  }
326 
327  ETL_CONSTEXPR17 reverse_iterator operator--(int)
328  {
329  reverse_iterator temp = *this;
330  ++current;
331 
332  return temp;
333  }
334 
335  ETL_CONSTEXPR17 reverse_iterator& operator+=(const difference_type offset)
336  {
337  current -= offset;
338 
339  return (*this);
340  }
341 
342  ETL_CONSTEXPR17 reverse_iterator& operator-=(const difference_type offset)
343  {
344  current += offset;
345 
346  return (*this);
347  }
348 
349  ETL_NODISCARD ETL_CONSTEXPR17 reverse_iterator operator+(const difference_type offset) const
350  {
351  return reverse_iterator(current - offset);
352  }
353 
354  ETL_NODISCARD ETL_CONSTEXPR17 reverse_iterator operator-(const difference_type offset) const
355  {
356  return (reverse_iterator(current + offset));
357  }
358 
359  ETL_NODISCARD ETL_CONSTEXPR17 reference operator[](const difference_type offset) const
360  {
361  return (*(*this + offset));
362  }
363 
364  protected:
365 
366  TIterator current;
367  };
368 
369  template <class TIterator>
370  inline ETL_CONSTEXPR17 bool operator ==(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
371  {
372  return lhs.base() == rhs.base();
373  }
374 
375  template <class TIterator>
376  inline ETL_CONSTEXPR17 bool operator !=(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
377  {
378  return !(lhs == rhs);
379  }
380 
381  template <class TIterator>
382  inline ETL_CONSTEXPR17 bool operator <(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
383  {
384  return rhs.base() < lhs.base();
385  }
386 
387  template <class TIterator>
388  inline ETL_CONSTEXPR17 bool operator >(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
389  {
390  return rhs < lhs;
391  }
392 
393  template <class TIterator>
394  inline ETL_CONSTEXPR17 bool operator <=(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
395  {
396  return !(rhs < lhs);
397  }
398 
399  template <class TIterator>
400  inline ETL_CONSTEXPR17 bool operator >=(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
401  {
402  return !(lhs < rhs);
403  }
404 
405  template <class TIterator>
406  inline ETL_CONSTEXPR17 typename reverse_iterator<TIterator>::difference_type operator -(const reverse_iterator<TIterator>& lhs, const reverse_iterator<TIterator>& rhs)
407  {
408  return rhs.base() - lhs.base();
409  }
410 
411  template <class TIterator, class TDifference>
412  inline ETL_CONSTEXPR17 reverse_iterator<TIterator> operator +(TDifference n, const reverse_iterator<TIterator>& itr)
413  {
414  return itr.operator +(n);
415  }
416 
417  //***************************************************************************
419  //***************************************************************************
420  template <typename TCategory, typename T, typename TDistance = ptrdiff_t, typename TPointer = T* , typename TReference = T& >
421  struct iterator
422  {
423  typedef T value_type;
424  typedef TDistance difference_type;
425  typedef TPointer pointer;
426  typedef TReference reference;
427  typedef TCategory iterator_category;
428  };
429 
430 #if ETL_CPP11_SUPPORTED
431  //***************************************************************************
432  // move_iterator
433  template <typename TIterator>
434  class move_iterator
435  {
436  public:
437 
438  typedef typename iterator_traits<TIterator>::iterator_category iterator_category;
439  typedef typename iterator_traits<TIterator>::value_type value_type;
440  typedef typename iterator_traits<TIterator>::difference_type difference_type;
441  typedef TIterator iterator_type;
442  typedef TIterator pointer;
443  typedef value_type&& reference;
444 
445  move_iterator()
446  {
447  }
448 
449  explicit move_iterator(TIterator itr)
450  : current(itr)
451  {
452  }
453 
454  template <typename U>
455  move_iterator(const move_iterator<U>& itr)
456  : current(itr.base())
457  {
458  }
459 
460  template <typename U>
461  move_iterator& operator =(const move_iterator<U>& itr)
462  {
463  current = itr.current;
464  return *this;
465  }
466 
467  iterator_type base() const
468  {
469  return current;
470  }
471 
472  pointer operator ->() const
473  {
474  return current;
475  }
476 
477  reference operator *() const
478  {
479  return etl::move(*current);
480  }
481 
482  move_iterator& operator++()
483  {
484  ++current;
485  return *this;
486  }
487 
488  move_iterator& operator--()
489  {
490  --current;
491  return *this;
492  }
493 
494  move_iterator operator++(int)
495  {
496  move_iterator temp = *this;
497  ++current;
498  return temp;
499  }
500 
501  move_iterator operator--(int)
502  {
503  move_iterator temp = *this;
504  --current;
505  return temp;
506  }
507 
508  move_iterator operator +(difference_type n) const
509  {
510  return move_iterator(current + n);
511  }
512 
513  move_iterator operator -(difference_type n) const
514  {
515  return move_iterator(current - n);
516  }
517 
518  move_iterator operator +=(difference_type n)
519  {
520  current += n;
521  return *this;
522  }
523 
524  move_iterator operator -=(difference_type n)
525  {
526  current -= n;
527  return *this;
528  }
529 
530  reference operator [](difference_type n) const
531  {
532  return etl::move(current[n]);
533  }
534 
535  private:
536 
537  TIterator current;
538  };
539 
540  template <typename TIterator>
541  bool operator ==(const etl::move_iterator<TIterator>& lhs,
542  const etl::move_iterator<TIterator>& rhs)
543  {
544  return lhs.base() == rhs.base();
545  }
546 
547  template <typename TIterator>
548  bool operator !=(const etl::move_iterator<TIterator>& lhs,
549  const etl::move_iterator<TIterator>& rhs)
550  {
551  return !(lhs == rhs);
552  }
553 
554  template <typename TIterator>
555  bool operator <(const etl::move_iterator<TIterator>& lhs,
556  const etl::move_iterator<TIterator>& rhs)
557  {
558  return lhs.base() < rhs.base();
559  }
560 
561  template <typename TIterator>
562  bool operator <=(const etl::move_iterator<TIterator>& lhs,
563  const etl::move_iterator<TIterator>& rhs)
564  {
565  return !(rhs < lhs);
566  }
567 
568  template <typename TIterator>
569  bool operator >(const etl::move_iterator<TIterator>& lhs,
570  const etl::move_iterator<TIterator>& rhs)
571  {
572  return (rhs < lhs);
573  }
574 
575  template <typename TIterator>
576  bool operator >=(const etl::move_iterator<TIterator>& lhs,
577  const etl::move_iterator<TIterator>& rhs)
578  {
579  return !(lhs < rhs);
580  }
581 
582  template <typename TIterator>
583  move_iterator<TIterator> operator +(typename move_iterator<TIterator>::difference_type n,
584  const move_iterator<TIterator>& rhs)
585  {
586  return rhs + n;
587  }
588 
589  template <typename TIterator1, typename TIterator2 >
590  auto operator -(const move_iterator<TIterator1>& lhs,
591  const move_iterator<TIterator2>& rhs) -> decltype(lhs.base() - rhs.base())
592  {
593  return lhs.base() - rhs.base();
594  }
595 
596  template <typename TIterator>
597  etl::move_iterator<TIterator> make_move_iterator(TIterator itr)
598  {
599  return etl::move_iterator<TIterator>(itr);
600  }
601 
602 #endif
603 
604  //***************************************************************************
605  // Helper templates.
606  //***************************************************************************
607  template <typename T>
609  {
610  static ETL_CONSTANT bool value = etl::is_same<typename etl::iterator_traits<T>::iterator_category, ETL_OR_STD::input_iterator_tag>::value;
611  };
612 
613  template <typename T>
615  {
616  static ETL_CONSTANT bool value = etl::is_same<typename etl::iterator_traits<T>::iterator_category, ETL_OR_STD::output_iterator_tag>::value;
617  };
618 
619  template <typename T>
621  {
622  static ETL_CONSTANT bool value = etl::is_same<typename etl::iterator_traits<T>::iterator_category, ETL_OR_STD::forward_iterator_tag>::value;
623  };
624 
625  template <typename T>
627  {
628  static ETL_CONSTANT bool value = etl::is_same<typename etl::iterator_traits<T>::iterator_category, ETL_OR_STD::bidirectional_iterator_tag>::value;
629  };
630 
631  template <typename T>
633  {
634  static ETL_CONSTANT bool value = etl::is_same<typename etl::iterator_traits<T>::iterator_category, ETL_OR_STD::random_access_iterator_tag>::value;
635  };
636 
637  template <typename T>
639  {
640  static ETL_CONSTANT bool value = etl::is_input_iterator<T>::value ||
644  };
645 
646  template <typename T>
648  {
649  static ETL_CONSTANT bool value = etl::is_output_iterator<T>::value ||
653  };
654 
655  template <typename T>
657  {
658  static ETL_CONSTANT bool value = etl::is_forward_iterator<T>::value ||
661  };
662 
663  template <typename T>
665  {
666  static ETL_CONSTANT bool value = etl::is_bidirectional_iterator<T>::value ||
668  };
669 
670  template <typename T>
672  {
673  static ETL_CONSTANT bool value = etl::is_random_iterator<T>::value;
674  };
675 }
676 
677 #endif
678 
Definition: iterator.h:251
is_same
Definition: type_traits_generator.h:981
Definition: absolute.h:37
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:633
etl::fixed_iterator< TIterator > & operator-(etl::fixed_iterator< TIterator > &lhs, typename etl::iterator_traits< TIterator >::difference_type)
Definition: fixed_iterator.h:193
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:645
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:594
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:582
etl::fixed_iterator< TIterator > & operator+(etl::fixed_iterator< TIterator > &lhs, typename etl::iterator_traits< TIterator >::difference_type)
Definition: fixed_iterator.h:183
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:606
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition: array.h:621
Definition: iterator.h:52
Definition: iterator.h:51
Definition: iterator.h:49
Definition: iterator.h:665
Definition: iterator.h:627
Definition: iterator.h:657
Definition: iterator.h:621
Definition: iterator.h:639
Definition: iterator.h:609
Definition: iterator.h:648
Definition: iterator.h:615
Definition: iterator.h:672
Definition: iterator.h:633
Definition: iterator.h:59
iterator
Definition: iterator.h:422
Definition: iterator.h:50
Definition: iterator.h:53