stride.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // Range v3 library
  2. //
  3. // Copyright Eric Niebler 2014-present
  4. //
  5. // Use, modification and distribution is subject to the
  6. // Boost Software License, Version 1.0. (See accompanying
  7. // file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // Project home: https://github.com/ericniebler/range-v3
  11. #include <list>
  12. #include <vector>
  13. #include <sstream>
  14. #include <range/v3/core.hpp>
  15. #include <range/v3/view/istream.hpp>
  16. #include <range/v3/view/move.hpp>
  17. #include <range/v3/view/partial_sum.hpp>
  18. #include <range/v3/view/reverse.hpp>
  19. #include <range/v3/view/stride.hpp>
  20. #include <range/v3/view/iota.hpp>
  21. #include <range/v3/algorithm/copy.hpp>
  22. #include <range/v3/iterator/operations.hpp>
  23. #include <range/v3/iterator/insert_iterators.hpp>
  24. #include <range/v3/iterator/stream_iterators.hpp>
  25. #include <range/v3/numeric.hpp>
  26. #include "../simple_test.hpp"
  27. #include "../test_utils.hpp"
  28. #include "../test_iterators.hpp"
  29. // https://github.com/ericniebler/range-v3/issues/1291
  30. void bug_1291()
  31. {
  32. std::vector<int> vec;
  33. auto tx = vec | ranges::views::stride( 2 ) | ranges::views::partial_sum;
  34. ranges::accumulate( tx, 0 );
  35. }
  36. int main()
  37. {
  38. using namespace ranges;
  39. auto const v = []
  40. {
  41. std::vector<int> vec(50);
  42. iota(vec, 0);
  43. return vec;
  44. }();
  45. {
  46. auto rng = v | views::stride(3);
  47. using R = decltype(rng);
  48. CPP_assert(random_access_range<R> && view_<R>);
  49. CPP_assert(!contiguous_range<R>);
  50. CPP_assert(common_range<R>);
  51. CPP_assert(sized_range<R>);
  52. CPP_assert(range<R const>);
  53. ::check_equal(rng | views::reverse,
  54. {48, 45, 42, 39, 36, 33, 30, 27, 24, 21, 18, 15, 12, 9, 6, 3, 0});
  55. }
  56. {
  57. std::stringstream str;
  58. copy(v, ostream_iterator<int>{str, " "});
  59. auto rng = istream<int>(str) | views::stride(3);
  60. using R = decltype(rng);
  61. CPP_assert(input_range<R> && view_<R>);
  62. CPP_assert(!forward_range<R>);
  63. CPP_assert(!common_range<R>);
  64. CPP_assert(!sized_range<R>);
  65. CPP_assert(!range<R const>);
  66. check_equal(rng, {0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48});
  67. }
  68. {
  69. std::list<int> li;
  70. copy(v, back_inserter(li));
  71. auto rng = li | views::stride(3);
  72. using R = decltype(rng);
  73. CPP_assert(bidirectional_range<R> && view_<R>);
  74. CPP_assert(!random_access_range<R>);
  75. CPP_assert(common_range<R>);
  76. CPP_assert(sized_range<R>);
  77. CPP_assert(range<R const>);
  78. ::check_equal(rng,
  79. {0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48});
  80. ::check_equal(rng | views::reverse,
  81. {48, 45, 42, 39, 36, 33, 30, 27, 24, 21, 18, 15, 12, 9, 6, 3, 0});
  82. for(int i : rng | views::reverse)
  83. std::cout << i << ' ';
  84. std::cout << '\n';
  85. }
  86. {
  87. auto x2 = v | views::stride(3);
  88. CHECK(ranges::distance(x2) == 17);
  89. auto it0 = x2.begin();
  90. auto it1 = std::next(it0, 10);
  91. CHECK((it1 - it0) == 10);
  92. CHECK((it0 - it1) == -10);
  93. CHECK((it0 - it0) == 0);
  94. CHECK((it1 - it1) == 0);
  95. }
  96. {
  97. const auto n = 4;
  98. auto rng = v | views::move | views::stride(2);
  99. CHECK((next(begin(rng), n) - begin(rng)) == n);
  100. }
  101. {
  102. // Regression test #368
  103. int n = 42;
  104. (void)ranges::views::stride(n);
  105. }
  106. {
  107. int const some_ints[] = {0,1,2,3,4,5,6,7};
  108. auto rng = debug_input_view<int const>{some_ints} | views::stride(2);
  109. using R = decltype(rng);
  110. CPP_assert(input_range<R> && view_<R>);
  111. CPP_assert(!forward_range<R>);
  112. CPP_assert(!common_range<R>);
  113. CPP_assert(sized_range<R>);
  114. CPP_assert(!range<R const>);
  115. ::check_equal(rng, {0,2,4,6});
  116. }
  117. {
  118. std::list<int> li;
  119. copy(v, back_inserter(li));
  120. subrange<std::list<int>::const_iterator> tmp{li.begin(), li.end()};
  121. auto rng = tmp | views::stride(3);
  122. using R = decltype(rng);
  123. CPP_assert(bidirectional_range<R> && view_<R>);
  124. CPP_assert(!random_access_range<R>);
  125. CPP_assert(!common_range<R>);
  126. CPP_assert(!sized_range<R>);
  127. CPP_assert(!range<R const>);
  128. ::check_equal(rng,
  129. {0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48});
  130. ::check_equal(rng | views::reverse,
  131. {48, 45, 42, 39, 36, 33, 30, 27, 24, 21, 18, 15, 12, 9, 6, 3, 0});
  132. }
  133. {
  134. std::list<int> li;
  135. copy(v, back_inserter(li));
  136. using CLI = std::list<int>::const_iterator;
  137. subrange<CLI, CLI, subrange_kind::sized> tmp{li};
  138. auto rng = tmp | views::stride(3);
  139. using R = decltype(rng);
  140. CPP_assert(bidirectional_range<R> && view_<R>);
  141. CPP_assert(!random_access_range<R>);
  142. CPP_assert(common_range<R>);
  143. CPP_assert(sized_range<R>);
  144. CPP_assert(range<R const>);
  145. CHECK((*--rng.end()) == 48);
  146. ::check_equal(rng,
  147. {0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48});
  148. ::check_equal(rng | views::reverse,
  149. {48, 45, 42, 39, 36, 33, 30, 27, 24, 21, 18, 15, 12, 9, 6, 3, 0});
  150. }
  151. // https://github.com/ericniebler/range-v3/issues/901
  152. {
  153. auto r = views::iota( 0, 12 );
  154. // Evenly divisible stride:
  155. auto strided1 = r | views::stride(3);
  156. ::check_equal(strided1, {0, 3, 6, 9});
  157. CHECK(strided1.size() == 4u);
  158. CHECK(strided1.front() == 0);
  159. CHECK(strided1[0] == 0);
  160. CHECK(strided1.back() == 9);
  161. CHECK(strided1[3] == 9);
  162. CHECK(strided1[(int)strided1.size() - 1] == 9);
  163. // Not evenly divisible stride:
  164. auto strided2 = r | views::stride(5);
  165. ::check_equal(strided2, {0, 5, 10});
  166. CHECK(strided2.size() == 3u);
  167. CHECK(strided2.front() == 0);
  168. CHECK(strided2[0] == 0);
  169. CHECK(strided2.back() == 10);
  170. CHECK(strided2[2] == 10);
  171. CHECK(strided2[(int)strided2.size() - 1] == 10);
  172. }
  173. return ::test_result();
  174. }