fork download
  1. #include <iterator>
  2.  
  3. template<class iterator>
  4. typename std::iterator_traits<iterator>::pointer struct_deref(iterator it)
  5. {return it.operator->();}
  6. template<class T>
  7. T* struct_deref(T* it)
  8. {return it;}
  9.  
  10. template<class underlying_type>
  11. struct back_and_forth_iterator {
  12. typedef back_and_forth_iterator bnfit;
  13. typedef typename std::iterator_traits<underlying_type>::value_type value_type;
  14. typedef typename std::iterator_traits<underlying_type>::difference_type difference_type;
  15. typedef typename std::iterator_traits<underlying_type>::pointer pointer;
  16. typedef typename std::iterator_traits<underlying_type>::reference reference;
  17. typedef typename std::iterator_traits<underlying_type>::reference iterator_category;
  18. typedef size_t size_type;
  19.  
  20. back_and_forth_iterator()
  21. :underlying(), turnaround(), forward(true) {}
  22. back_and_forth_iterator(underlying_type pos, underlying_type turn, bool fwd)
  23. :underlying(pos), turnaround(turn), forward(fwd) {}
  24. back_and_forth_iterator(const bnfit& rhs)
  25. :underlying(rhs.underlying), turnaround(rhs.turnaround), forward(rhs.forward) {}
  26. ~back_and_forth_iterator()
  27. {}
  28. bnfit& operator=(const bnfit& rhs)
  29. {underlying=rhs.underlying; forward=rhs.forward; return *this;}
  30. bnfit& operator++()
  31. {
  32. if (forward) {
  33. if (++underlying == turnaround)
  34. forward = false;
  35. } else
  36. --underlying;
  37. return *this;
  38. }
  39. bnfit operator++(int)
  40. {bnfit p(*this); operator++(); return p;}
  41. bnfit& operator--()
  42. {
  43. if (!forward) {
  44. if (--underlying == turnaround)
  45. forward = true;
  46. } else
  47. ++underlying;
  48. return *this;
  49. }
  50. bnfit operator--(int)
  51. {bnfit p(*this); operator--(); return p;}
  52. bnfit& operator+=(size_type o)
  53. {
  54. if (forward) {
  55. size_type m = std::min(turnaround-underlying, o);
  56. underlying += m;
  57. o -= m;
  58. }
  59. underlying -= o;
  60. return *this;
  61. }
  62. friend bnfit operator+(const bnfit& it, size_type o)
  63. {return bnfit(it)+=o;}
  64. friend bnfit operator+(size_type o, const bnfit& it)
  65. {return bnfit(it)+=o;}
  66. bnfit& operator-=(size_type o)
  67. {
  68. if (!forward) {
  69. size_type m = std::min(turnaround-underlying, o);
  70. underlying += m;
  71. o -= m;
  72. }
  73. underlying -= o;
  74. return *this;
  75. }
  76. friend bnfit operator-(const bnfit& it, size_type o)
  77. {return bnfit(it)-=o;}
  78. friend difference_type operator-(bnfit lhs, bnfit rhs)
  79. {
  80. if(lhs.forward) {
  81. if (rhs.forward)
  82. return lhs.underlying - rhs.underlying;
  83. else
  84. return lhs.underlying-lhs.turnaround + rhs.underlying-rhs.turnaround;
  85. } else {
  86. if (rhs.forward)
  87. return lhs.turnaround-lhs.underlying + rhs.turnaround-rhs.underlying;
  88. else
  89. return rhs.underlying - lhs.underlying;
  90. }
  91. }
  92. reference operator*() const
  93. {
  94. if (forward) return *underlying;
  95. else return *std::prev(underlying);
  96. }
  97. pointer operator->() const
  98. {
  99. if (forward) return struct_deref(underlying);
  100. else return struct_deref(std::prev(underlying));
  101. }
  102. reference operator[](size_type o) const
  103. {return *(iterator(*this)+=o);}
  104. friend bool operator==(const bnfit& lhs, const bnfit& rhs)
  105. {return lhs.underlying==rhs.underlying && lhs.forward==rhs.forward;}
  106. friend bool operator!=(const bnfit& lhs, const bnfit& rhs)
  107. {return lhs.underlying!=rhs.underlying || lhs.forward!=rhs.forward;}
  108. friend bool operator<(const bnfit& lhs, const bnfit& rhs)
  109. {return compare(lhs, rhs)<0;}
  110. friend bool operator>(const bnfit& lhs, const bnfit& rhs)
  111. {return compare(lhs, rhs)>0;}
  112. friend bool operator<=(const bnfit& lhs, const bnfit& rhs)
  113. {return compare(lhs, rhs)<=0;}
  114. friend bool operator>=(const bnfit& lhs, const bnfit& rhs)
  115. {return compare(lhs, rhs)>=0;}
  116. friend void swap(const bnfit& lhs, const bnfit& rhs)
  117. {
  118. using std::swap;
  119. swap(lhs.underlying, rhs.underlying);
  120. swap(lhs.turnaround, rhs.turnaround),
  121. swap(lhs.foward, rhs.forward);
  122. }
  123. private:
  124. static int compare(const bnfit& lhs, const bnfit& rhs)
  125. {
  126. int flip = (lhs.forward ? 1 : -1);
  127. if (lhs.forward != rhs.forward) return -1*flip;
  128. if (lhs.underlying<rhs.underlying) return -1*flip;
  129. if (rhs.underlying<lhs.underlying) return flip;
  130. return 0;
  131. }
  132. underlying_type underlying;
  133. underlying_type turnaround;
  134. bool forward;
  135. };
  136. template<class underlying_type>
  137. back_and_forth_iterator<underlying_type> make_backforth_first(underlying_type first, underlying_type last)
  138. {return back_and_forth_iterator<underlying_type>(first, last, true);}
  139. template<class underlying_type>
  140. back_and_forth_iterator<underlying_type> make_backforth_last(underlying_type first, underlying_type last)
  141. {return back_and_forth_iterator<underlying_type>(first, last, false);}
  142.  
  143.  
  144.  
  145.  
  146. #include <string>
  147. #include <iostream>
  148. #include <list>
  149.  
  150. int main() {
  151. std::string s("qwew");
  152. auto first0 = make_backforth_first(s.begin(), s.end());
  153. auto last0 = make_backforth_last(s.begin(), s.end());
  154. for (auto it=first0; it!=last0; ++it)
  155. std::cout << *it << ' ';
  156. std::cout << std::endl;
  157.  
  158. std::list<std::string> l;
  159. l.push_back(s);
  160. auto first1 = make_backforth_first(l.begin(), l.end());
  161. auto last1 = make_backforth_last(l.begin(), l.end());
  162. for (auto it=first1; it!=last1; ++it)
  163. std::cout << *it << ' ';
  164. std::cout << std::endl;
  165. }
Success #stdin #stdout 0s 3064KB
stdin
Standard input is empty
stdout
q w e w w e w q 
qwew qwew