iterator.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Iterators-related utilities
  2. //
  3. // Platform: ISO C++ 98/11
  4. // $Id$
  5. //
  6. // (c) __vic 2014
  7. #ifndef __VIC_ITERATOR_H
  8. #define __VIC_ITERATOR_H
  9. #include<__vic/defs.h>
  10. #include<iterator>
  11. namespace __vic {
  12. //------------------------------------------------------------------------------
  13. template<class T, size_t N>
  14. __VIC_CONSTEXPR_FUNC T *begin(T (&arr)[N]) { return arr; }
  15. //------------------------------------------------------------------------------
  16. template<class T, size_t N>
  17. __VIC_CONSTEXPR_FUNC T *end(T (&arr)[N]) { return arr + N; }
  18. //------------------------------------------------------------------------------
  19. template<class T, size_t N>
  20. __VIC_CONSTEXPR_FUNC const T *cbegin(T (&arr)[N]) { return arr; }
  21. //------------------------------------------------------------------------------
  22. template<class T, size_t N>
  23. __VIC_CONSTEXPR_FUNC const T *cend(T (&arr)[N]) { return arr + N; }
  24. //------------------------------------------------------------------------------
  25. //------------------------------------------------------------------------------
  26. // Moves only forward as opposed to std::advance() and never steps beyond the end
  27. // advance(it, end, n) effects as while(it != end && n--) ++it;
  28. //------------------------------------------------------------------------------
  29. template<class Iter>
  30. inline void advance_(std::random_access_iterator_tag, Iter &begin, Iter end, size_t n)
  31. {
  32. size_t total = end - begin;
  33. begin += n < total ? n : total;
  34. }
  35. //------------------------------------------------------------------------------
  36. template<class Iter>
  37. inline void advance_(std::input_iterator_tag, Iter &begin, Iter end, size_t n)
  38. {
  39. Iter it = begin;
  40. while(it != end && n--) ++it;
  41. begin = it;
  42. }
  43. //------------------------------------------------------------------------------
  44. template<class Iter>
  45. inline void advance(Iter &begin, Iter end, size_t n)
  46. {
  47. advance_(typename std::iterator_traits<Iter>::iterator_category(),
  48. begin, end, n);
  49. }
  50. //------------------------------------------------------------------------------
  51. //------------------------------------------------------------------------------
  52. template<class Iter>
  53. inline Iter next_(std::forward_iterator_tag, Iter it, size_t n)
  54. {
  55. while(n--) ++it;
  56. return it;
  57. }
  58. //------------------------------------------------------------------------------
  59. template<class Iter>
  60. inline Iter next_(std::random_access_iterator_tag, Iter it, size_t n)
  61. {
  62. return it += n;
  63. }
  64. //------------------------------------------------------------------------------
  65. template<class ForwardIterator>
  66. inline ForwardIterator next(ForwardIterator it, size_t n)
  67. {
  68. return next_(typename std::iterator_traits<ForwardIterator>
  69. ::iterator_category(), it, n);
  70. }
  71. //------------------------------------------------------------------------------
  72. template<class ForwardIterator>
  73. inline ForwardIterator next(ForwardIterator it)
  74. {
  75. return ++it;
  76. }
  77. //------------------------------------------------------------------------------
  78. //------------------------------------------------------------------------------
  79. template<class Iter>
  80. inline Iter prev_(std::bidirectional_iterator_tag, Iter it, size_t n)
  81. {
  82. while(n--) --it;
  83. return it;
  84. }
  85. //------------------------------------------------------------------------------
  86. template<class Iter>
  87. inline Iter prev_(std::random_access_iterator_tag, Iter it, size_t n)
  88. {
  89. return it -= n;
  90. }
  91. //------------------------------------------------------------------------------
  92. template<class BidirectionalIterator>
  93. inline BidirectionalIterator prev(BidirectionalIterator it, size_t n)
  94. {
  95. return prev_(typename std::iterator_traits<BidirectionalIterator>
  96. ::iterator_category(), it, n);
  97. }
  98. //------------------------------------------------------------------------------
  99. template<class BidirectionalIterator>
  100. inline BidirectionalIterator prev(BidirectionalIterator it)
  101. {
  102. return --it;
  103. }
  104. //------------------------------------------------------------------------------
  105. } // namespace
  106. #endif // header guard