reverse.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // Range v3 library
  2. //
  3. // Copyright Eric Niebler 2015-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 <range/v3/core.hpp>
  14. #include <range/v3/view/take.hpp>
  15. #include <range/v3/view/take_exactly.hpp>
  16. #include <range/v3/view/reverse.hpp>
  17. #include <range/v3/view/counted.hpp>
  18. #include <range/v3/view/delimit.hpp>
  19. #include <range/v3/view/filter.hpp>
  20. #include <range/v3/view/c_str.hpp>
  21. #include <range/v3/view/zip.hpp>
  22. #include <range/v3/utility/copy.hpp>
  23. #include <range/v3/algorithm/find.hpp>
  24. #include "../simple_test.hpp"
  25. #include "../test_utils.hpp"
  26. int main()
  27. {
  28. using namespace ranges;
  29. // Reverse a random-access, common, sized range
  30. std::vector<int> rgv{0,1,2,3,4,5,6,7,8,9};
  31. auto const rng0 = rgv | views::reverse;
  32. CPP_assert(view_<std::remove_const_t<decltype(rng0)>>);
  33. CPP_assert(random_access_range<decltype(rng0)>);
  34. CPP_assert(common_range<decltype(rng0)>);
  35. CPP_assert(sized_range<decltype(rng0)>);
  36. CHECK(rng0.size() == 10u);
  37. ::check_equal(rng0, {9,8,7,6,5,4,3,2,1,0});
  38. ::check_equal(rng0 | views::reverse, {0,1,2,3,4,5,6,7,8,9});
  39. ::check_equal(rng0 | views::reverse | views::reverse, {9,8,7,6,5,4,3,2,1,0});
  40. ::check_equal(rng0 | views::reverse | views::reverse | views::reverse, {0,1,2,3,4,5,6,7,8,9});
  41. {
  42. auto z = views::zip(rgv);
  43. auto rz = z | views::reverse;
  44. CPP_assert(same_as<range_value_t<decltype(z)>, range_value_t<decltype(rz)>>);
  45. }
  46. #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
  47. #if defined(__clang__) && __clang_major__ < 6
  48. // Workaround https://bugs.llvm.org/show_bug.cgi?id=33314
  49. RANGES_DIAGNOSTIC_PUSH
  50. RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_FUNC_TEMPLATE
  51. #endif
  52. {
  53. ranges::reverse_view dg0{rgv};
  54. ::check_equal(dg0, {9, 8, 7, 6, 5, 4, 3, 2, 1, 0});
  55. ranges::reverse_view dg1{dg0};
  56. #ifdef RANGES_WORKAROUND_MSVC_934330
  57. ::check_equal(dg1, {9, 8, 7, 6, 5, 4, 3, 2, 1, 0});
  58. #else // ^^^ "workaround" / no "workaround" vvv
  59. ::check_equal(dg1, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
  60. #endif // RANGES_WORKAROUND_MSVC_934330
  61. }
  62. #if defined(__clang__) && __clang_major__ < 6
  63. RANGES_DIAGNOSTIC_POP
  64. #endif // clang bug workaround
  65. #endif // use deduction guides
  66. // Reverse another random-access, non-common, sized range
  67. auto cnt = counted_view<std::vector<int>::iterator>(rgv.begin(), 10);
  68. CPP_assert(!common_range<decltype(cnt)>);
  69. auto const rng1 = rgv | views::reverse;
  70. CPP_assert(view_<std::remove_const_t<decltype(rng1)>>);
  71. CPP_assert(random_access_range<decltype(rng1)>);
  72. CPP_assert(common_range<decltype(rng1)>);
  73. CPP_assert(sized_range<decltype(rng1)>);
  74. CHECK(rng1.size() == 10u);
  75. ::check_equal(rng1, {9,8,7,6,5,4,3,2,1,0});
  76. ::check_equal(rng1 | views::reverse, {0,1,2,3,4,5,6,7,8,9});
  77. // Reverse a random-access, non-common, non-sized range
  78. auto sz = views::c_str((char const*)"hello");
  79. auto rng2 = sz | views::reverse;
  80. CPP_assert(view_<decltype(rng2)>);
  81. CPP_assert(random_access_range<decltype(rng2)>);
  82. CPP_assert(common_range<decltype(rng2)>);
  83. CPP_assert(!sized_range<decltype(detail::as_const(rng2))>);
  84. CPP_assert(sized_range<decltype(rng2)>);
  85. auto const & crng2 = rng2;
  86. CPP_assert(!range<decltype(crng2)>);
  87. ::check_equal(rng2, {'o','l','l','e','h'});
  88. ::check_equal(rng2 | views::reverse, {'h','e','l','l','o'});
  89. // Reverse a bidirectional, common, sized range
  90. std::list<int> rgl{0,1,2,3,4,5,6,7,8,9};
  91. auto const rng3 = rgl | views::reverse;
  92. CPP_assert(view_<std::remove_const_t<decltype(rng3)>>);
  93. CPP_assert(bidirectional_range<decltype(rng3)>);
  94. CPP_assert(!random_access_range<decltype(rng3)>);
  95. CPP_assert(common_range<decltype(rng3)>);
  96. CPP_assert(sized_range<decltype(rng3)>);
  97. CHECK(rng3.size() == 10u);
  98. ::check_equal(rng3, {9,8,7,6,5,4,3,2,1,0});
  99. ::check_equal(rng3 | views::reverse, {0,1,2,3,4,5,6,7,8,9});
  100. // Reverse a bidirectional, weak, sized range
  101. auto cnt2 = views::counted(rgl.begin(), 10);
  102. auto rng4 = cnt2 | views::reverse;
  103. CPP_assert(view_<decltype(rng4)>);
  104. CPP_assert(bidirectional_range<decltype(rng4)>);
  105. CPP_assert(!random_access_range<decltype(rng4)>);
  106. CPP_assert(common_range<decltype(rng4)>);
  107. CPP_assert(sized_range<decltype(rng4)>);
  108. CHECK(rng4.size() == 10u);
  109. auto const & crng4 = rng4;
  110. CPP_assert(!range<decltype(crng4)>);
  111. ::check_equal(rng4, {9,8,7,6,5,4,3,2,1,0});
  112. ::check_equal(rng4 | views::reverse, {0,1,2,3,4,5,6,7,8,9});
  113. // Reverse a bidirectional, weak, non-sized range
  114. auto dlm = views::delimit(rgl.begin(), 9);
  115. CPP_assert(!common_range<decltype(dlm)>);
  116. auto rng5 = dlm | views::reverse;
  117. CPP_assert(view_<decltype(rng5)>);
  118. CPP_assert(bidirectional_range<decltype(rng5)>);
  119. CPP_assert(!random_access_range<decltype(rng5)>);
  120. CPP_assert(common_range<decltype(rng5)>);
  121. CPP_assert(!sized_range<decltype(rng5)>);
  122. auto const & crng5 = rng5;
  123. CPP_assert(!range<decltype(crng5)>);
  124. ::check_equal(rng5, {8,7,6,5,4,3,2,1,0});
  125. ::check_equal(rng5 | views::reverse, {0,1,2,3,4,5,6,7,8});
  126. // Reverse a bidirectional, weak, non-sized range
  127. auto dlm2 = views::delimit(rgl, 10);
  128. CPP_assert(!common_range<decltype(dlm2)>);
  129. auto rng6 = dlm2 | views::reverse;
  130. CPP_assert(view_<decltype(rng6)>);
  131. CPP_assert(bidirectional_range<decltype(rng6)>);
  132. CPP_assert(!random_access_range<decltype(rng6)>);
  133. CPP_assert(common_range<decltype(rng6)>);
  134. CPP_assert(!sized_range<decltype(rng6)>);
  135. auto const & crng6 = rng6;
  136. CPP_assert(!range<decltype(crng6)>);
  137. ::check_equal(rng6, {9,8,7,6,5,4,3,2,1,0});
  138. ::check_equal(rng6 | views::reverse, {0,1,2,3,4,5,6,7,8,9});
  139. {
  140. std::vector<int> v = {1, 2, 3, 4, 5};
  141. auto b = find(v, 2);
  142. auto e = find(v | views::reverse, 4).base();
  143. ::check_equal(make_subrange(b, e), {2, 3, 4});
  144. auto e2 = find(v | views::filter([](int i){ return i%2 == 0;})
  145. | views::reverse, 4);
  146. CHECK(::is_dangling(e2));
  147. }
  148. return test_result();
  149. }