set_intersection.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // Range v3 library
  2. //
  3. // Copyright Eric Niebler 2014-present
  4. // Copyright Tomislav Ivek 2015-2016
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. #include <vector>
  13. #include <sstream>
  14. #include <range/v3/core.hpp>
  15. #include <range/v3/range_for.hpp>
  16. #include <range/v3/algorithm/set_algorithm.hpp>
  17. #include <range/v3/algorithm/move.hpp>
  18. #include <range/v3/iterator/operations.hpp>
  19. #include <range/v3/iterator/insert_iterators.hpp>
  20. #include <range/v3/functional/identity.hpp>
  21. #include <range/v3/utility/copy.hpp>
  22. #include <range/v3/view/all.hpp>
  23. #include <range/v3/view/const.hpp>
  24. #include <range/v3/view/drop_while.hpp>
  25. #include <range/v3/view/iota.hpp>
  26. #include <range/v3/view/reverse.hpp>
  27. #include <range/v3/view/set_algorithm.hpp>
  28. #include <range/v3/view/stride.hpp>
  29. #include <range/v3/view/take.hpp>
  30. #include <range/v3/view/transform.hpp>
  31. #include "../simple_test.hpp"
  32. #include "../test_utils.hpp"
  33. int main()
  34. {
  35. using namespace ranges;
  36. int i1_finite[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
  37. int i2_finite[] = { -3, 2, 4, 4, 6, 9};
  38. auto i1_infinite = views::ints | views::stride(3);
  39. auto i2_infinite = views::ints | views::transform([](int x)
  40. {
  41. return x * x;
  42. });
  43. // intersection of two finite ranges
  44. {
  45. auto res = views::set_intersection(i1_finite, i2_finite);
  46. CPP_assert(view_<decltype(res)>);
  47. CPP_assert(forward_range<decltype(res)>);
  48. CPP_assert(!random_access_range<decltype(res)>);
  49. CPP_assert(!common_range<decltype(res)>);
  50. using R = decltype(res);
  51. CPP_assert(same_as<range_value_t<R>, int>);
  52. CPP_assert(same_as<range_reference_t<R>, int&>);
  53. CPP_assert(same_as<decltype(iter_move(begin(res))), int &&>);
  54. static_assert(range_cardinality<R>::value == ranges::finite, "Cardinality of intersection with a finite range should be finite!");
  55. ::check_equal(res, {2, 4, 4});
  56. CHECK(&*begin(res) == &*(begin(i1_finite) + 1));
  57. }
  58. // intersection of two infinite ranges
  59. {
  60. auto res = views::set_intersection(i1_infinite, i2_infinite);
  61. CPP_assert(view_<decltype(res)>);
  62. CPP_assert(forward_range<decltype(res)>);
  63. CPP_assert(!random_access_range<decltype(res)>);
  64. CPP_assert(!common_range<decltype(res)>);
  65. using R = decltype(res);
  66. CPP_assert(same_as<range_value_t<R>, int>);
  67. CPP_assert(same_as<range_reference_t<R>, range_reference_t<decltype(i1_infinite)>>);
  68. CPP_assert(same_as<decltype(iter_move(begin(res))), range_rvalue_reference_t<decltype(i1_infinite)>>);
  69. static_assert(range_cardinality<R>::value == ranges::unknown, "Cardinality of intersection of infinite ranges should be unknown!");
  70. ::check_equal(res | views::take(5), {0, 9, 36, 81, 144});
  71. }
  72. // intersection of a finite and infinite range
  73. {
  74. auto res = views::set_intersection(i1_finite, i2_infinite);
  75. CPP_assert(view_<decltype(res)>);
  76. CPP_assert(forward_range<decltype(res)>);
  77. CPP_assert(!random_access_range<decltype(res)>);
  78. CPP_assert(!common_range<decltype(res)>);
  79. using R = decltype(res);
  80. CPP_assert(same_as<range_value_t<R>, int>);
  81. CPP_assert(same_as<range_reference_t<R>, range_reference_t<decltype(i1_finite)>>);
  82. CPP_assert(same_as<decltype(iter_move(begin(res))), range_rvalue_reference_t<decltype(i1_finite)>>);
  83. static_assert(range_cardinality<R>::value == ranges::finite, "Cardinality of intersection with a finite range should be finite!");
  84. ::check_equal(res | views::take(500), {1, 4});
  85. auto res2 = views::set_intersection(i1_infinite, i2_finite);
  86. CPP_assert(view_<decltype(res2)>);
  87. CPP_assert(forward_range<decltype(res2)>);
  88. CPP_assert(!random_access_range<decltype(res2)>);
  89. CPP_assert(!common_range<decltype(res2)>);
  90. using R2 = decltype(res2);
  91. CPP_assert(same_as<range_value_t<R2>, int>);
  92. CPP_assert(same_as<range_reference_t<R2>, range_reference_t<decltype(i1_infinite)>>);
  93. CPP_assert(same_as<range_rvalue_reference_t<R2>, range_rvalue_reference_t<decltype(i1_infinite)>>);
  94. static_assert(range_cardinality<decltype(res2)>::value == ranges::finite, "Cardinality of intersection with a finite range should be finite!");
  95. ::check_equal(res2 | views::take(500), {6, 9});
  96. }
  97. // intersection of a set of unknown cardinality
  98. {
  99. auto rng0 = views::iota(10) | views::drop_while([](int i)
  100. {
  101. return i < 25;
  102. });
  103. static_assert(range_cardinality<decltype(rng0)>::value == ranges::unknown, "");
  104. auto res = views::set_intersection(i1_finite, rng0);
  105. static_assert(range_cardinality<decltype(res)>::value == ranges::unknown, "Intersection with a set of unknown cardinality should have unknown cardinality!");
  106. }
  107. // test const ranges
  108. {
  109. auto res1 = views::set_intersection(views::const_(i1_finite), views::const_(i2_finite));
  110. using R1 = decltype(res1);
  111. CPP_assert(same_as<range_value_t<R1>, int>);
  112. CPP_assert(same_as<range_reference_t<R1>, const int&>);
  113. CPP_assert(same_as<range_rvalue_reference_t<R1>, const int&&>);
  114. auto res2 = views::set_intersection(views::const_(i1_finite), i2_finite);
  115. using R2 = decltype(res2);
  116. CPP_assert(same_as<range_value_t<R2>, int>);
  117. CPP_assert(same_as<range_reference_t<R2>, const int&>);
  118. CPP_assert(same_as<range_rvalue_reference_t<R2>, const int&&>);
  119. }
  120. // test different orderings
  121. {
  122. auto res = views::set_intersection(views::reverse(i1_finite), views::reverse(i2_finite), [](int a, int b)
  123. {
  124. return a > b;
  125. });
  126. ::check_equal(res, {4, 4, 2});
  127. }
  128. // test projections and sets with different element types
  129. struct S
  130. {
  131. int val;
  132. bool operator==(const S& other) const
  133. {
  134. return val == other.val;
  135. }
  136. };
  137. S s_finite[] = {S{-20}, S{-10}, S{1}, S{3}, S{3}, S{6}, S{8}, S{20}};
  138. {
  139. auto res1 = views::set_intersection(s_finite, views::ints(-2, 10),
  140. less(),
  141. &S::val,
  142. identity()
  143. );
  144. using R1 = decltype(res1);
  145. CPP_assert(same_as<range_value_t<R1>, S>);
  146. CPP_assert(same_as<range_reference_t<R1>, S&>);
  147. CPP_assert(same_as<range_rvalue_reference_t<R1>, S&&>);
  148. ::check_equal(res1, {S{1}, S{3}, S{6}, S{8}});
  149. auto res2 = views::set_intersection(views::ints(-2, 10), s_finite,
  150. less(),
  151. identity(),
  152. [](const S& x){ return x.val; }
  153. );
  154. using R2 = decltype(res2);
  155. CPP_assert(same_as<range_value_t<R2>, int>);
  156. CPP_assert(same_as<range_reference_t<R2>, int>);
  157. CPP_assert(same_as<range_rvalue_reference_t<R2>, int>);
  158. ::check_equal(res2, {1, 3, 6, 8});
  159. }
  160. // move
  161. {
  162. auto v0 = to<std::vector<MoveOnlyString>>({"a","b","b","c","x","x"});
  163. auto v1 = to<std::vector<MoveOnlyString>>({"b","x","y","z"});
  164. auto res = views::set_intersection(v0, v1, [](const MoveOnlyString& a, const MoveOnlyString& b){return a<b;});
  165. std::vector<MoveOnlyString> expected;
  166. move(res, back_inserter(expected));
  167. ::check_equal(expected, {"b","x"});
  168. ::check_equal(v0, {"a","","b","c","","x"});
  169. ::check_equal(v1, {"b","x","y","z"});
  170. using R = decltype(res);
  171. CPP_assert(same_as<range_value_t<R>, MoveOnlyString>);
  172. CPP_assert(same_as<range_reference_t<R>, MoveOnlyString &>);
  173. CPP_assert(same_as<range_rvalue_reference_t<R>, MoveOnlyString &&>);
  174. }
  175. {
  176. auto rng = views::set_intersection(
  177. debug_input_view<int const>{i1_finite},
  178. debug_input_view<int const>{i2_finite}
  179. );
  180. ::check_equal(rng, {2, 4, 4});
  181. }
  182. return test_result();
  183. }