fork(1) download
  1. // Experimental sliding window class. (3.00)
  2.  
  3. #include <iostream>
  4.  
  5. template<typename T>
  6. struct window_wrapper {
  7. T m_first, m_last;
  8. T begin() const
  9. { return m_first; }
  10. T end() const
  11. { return m_last; }
  12. };
  13.  
  14. // class sliding_window
  15. // Group a sequence into sequential n-element chunks.
  16. // sliding_window(string("ABCDEF"), 4) -> ABCD, BCDE, CDEF
  17.  
  18. template<typename Iter>
  19. struct sliding_window {
  20. typedef window_wrapper<Iter> value_type;
  21.  
  22. template<typename Iterable>
  23. sliding_window(Iterable&&, size_t n);
  24. sliding_window(Iter, Iter, size_t n);
  25.  
  26. sliding_window begin() const
  27. { return *this; }
  28. sliding_window end() const
  29. { return sliding_window(m_last, m_last, 0); }
  30.  
  31. value_type operator*() const
  32. { return {m_first, std::next(m_next)}; }
  33.  
  34. sliding_window& operator++()
  35. { ++m_first; ++m_next; return *this; }
  36. sliding_window operator++(int)
  37. { sliding_window temp(*this); ++*this; return temp; }
  38.  
  39. bool operator==(const sliding_window& other) const
  40. { return m_next == other.m_next; }
  41. bool operator!=(const sliding_window& other) const
  42. { return !(*this == other); }
  43.  
  44. private:
  45. Iter m_first, m_next, m_last;
  46. };
  47.  
  48. #if __cplusplus >= 201703L
  49. template<typename Iterable>
  50. sliding_window(Iterable&& t, size_t) ->
  51. sliding_window<decltype(std::begin(t))>;
  52. #endif // C++17
  53.  
  54. template<typename Iter>
  55. template<typename Iterable>
  56. sliding_window<Iter>::sliding_window(Iterable&& v, size_t n)
  57. : sliding_window(std::begin(v), std::end(v), n)
  58. {}
  59.  
  60. template<typename Iter>
  61. sliding_window<Iter>::sliding_window(Iter first, Iter last, size_t n)
  62. : m_first(first), m_next(n > 0 ? first : last), m_last(last)
  63. {
  64. for (size_t i = 1; i < n && m_next != m_last; i++)
  65. ++m_next;
  66. }
  67.  
  68. // Ease creation of sliding windows.
  69. // (the C++17 deduction guides make these obsolete)
  70. template<typename Iter>
  71. auto make_sliding_window(Iter first, Iter last, size_t n)
  72. {
  73. return sliding_window<decltype(first)>(first, last, n);
  74. }
  75.  
  76. template<typename Iterable>
  77. auto make_sliding_window(Iterable&& v, size_t n)
  78. {
  79. return make_sliding_window(std::begin(v), std::end(v), n);
  80. }
  81.  
  82. // Testing.
  83.  
  84. int main()
  85. {
  86. auto print = [](auto&& iterable) {
  87. for (auto item : iterable) std::cout << item;
  88. std::cout << ' ';
  89. };
  90.  
  91. std::string s = "ABCDEFGH";
  92. std::cout << s << std::endl;
  93.  
  94. // Ensure all constness and value categories compile.
  95. make_sliding_window(s, 1);
  96. make_sliding_window(const_cast<const std::string&>(s), 1);
  97. make_sliding_window(std::string(), 1);
  98.  
  99. for (size_t i = 0; i <= s.size()+1; i++) {
  100. auto sw = make_sliding_window(s, i);
  101. std::cout << i << "> ";
  102. for (auto window : sw)
  103. print(window);
  104. std::cout << std::endl;
  105. }
  106.  
  107. for (size_t i = 0; i <= s.size()+1; i++) {
  108. auto sw = make_sliding_window(s.begin(), s.end(), i);
  109. std::cout << i << "> ";
  110. for (auto window : sw)
  111. print(window);
  112. std::cout << std::endl;
  113. }
  114.  
  115. // Modify non-const sequence through window.
  116. for (auto window : make_sliding_window(s, 1))
  117. for (auto& x : window)
  118. x = '-';
  119. std::cout << s << std::endl;
  120. }
Success #stdin #stdout 0s 5284KB
stdin
Standard input is empty
stdout
ABCDEFGH
0> 
1> A B C D E F G H 
2> AB BC CD DE EF FG GH 
3> ABC BCD CDE DEF EFG FGH 
4> ABCD BCDE CDEF DEFG EFGH 
5> ABCDE BCDEF CDEFG DEFGH 
6> ABCDEF BCDEFG CDEFGH 
7> ABCDEFG BCDEFGH 
8> ABCDEFGH 
9> 
0> 
1> A B C D E F G H 
2> AB BC CD DE EF FG GH 
3> ABC BCD CDE DEF EFG FGH 
4> ABCD BCDE CDEF DEFG EFGH 
5> ABCDE BCDEF CDEFG DEFGH 
6> ABCDEF BCDEFG CDEFGH 
7> ABCDEFG BCDEFGH 
8> ABCDEFGH 
9> 
--------