partition_copy.cpp 5.3 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. //
  12. // Copyright 2005 - 2007 Adobe Systems Incorporated
  13. // Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt
  14. // or a copy at http://stlab.adobe.com/licenses.html)
  15. //===----------------------------------------------------------------------===//
  16. //
  17. // The LLVM Compiler Infrastructure
  18. //
  19. // This file is dual licensed under the MIT and the University of Illinois Open
  20. // Source Licenses. See LICENSE.TXT for details.
  21. //
  22. //===----------------------------------------------------------------------===//
  23. #include <tuple>
  24. #include <vector>
  25. #include <range/v3/core.hpp>
  26. #include <range/v3/algorithm/partition_copy.hpp>
  27. #include <range/v3/view/counted.hpp>
  28. #include "../simple_test.hpp"
  29. #include "../test_utils.hpp"
  30. #include "../test_iterators.hpp"
  31. struct is_odd
  32. {
  33. constexpr bool operator()(const int & i) const
  34. {
  35. return i & 1;
  36. }
  37. };
  38. template<class Iter, class Sent = Iter>
  39. void
  40. test_iter()
  41. {
  42. const int ia[] = {1, 2, 3, 4, 6, 8, 5, 7};
  43. int r1[10] = {0};
  44. int r2[10] = {0};
  45. typedef ranges::partition_copy_result<Iter, OutputIterator<int*>, int*> P;
  46. P p = ranges::partition_copy(Iter(std::begin(ia)),
  47. Sent(std::end(ia)),
  48. OutputIterator<int*>(r1), r2, is_odd());
  49. CHECK(p.in == Iter(std::end(ia)));
  50. CHECK(p.out1.base() == r1 + 4);
  51. CHECK(r1[0] == 1);
  52. CHECK(r1[1] == 3);
  53. CHECK(r1[2] == 5);
  54. CHECK(r1[3] == 7);
  55. CHECK(p.out2 == r2 + 4);
  56. CHECK(r2[0] == 2);
  57. CHECK(r2[1] == 4);
  58. CHECK(r2[2] == 6);
  59. CHECK(r2[3] == 8);
  60. }
  61. template<class Iter, class Sent = Iter>
  62. void
  63. test_range()
  64. {
  65. const int ia[] = {1, 2, 3, 4, 6, 8, 5, 7};
  66. int r1[10] = {0};
  67. int r2[10] = {0};
  68. typedef ranges::partition_copy_result<Iter, OutputIterator<int*>, int*> P;
  69. P p = ranges::partition_copy(::as_lvalue(ranges::make_subrange(Iter(std::begin(ia)),
  70. Sent(std::end(ia)))),
  71. OutputIterator<int*>(r1), r2, is_odd());
  72. CHECK(p.in == Iter(std::end(ia)));
  73. CHECK(p.out1.base() == r1 + 4);
  74. CHECK(r1[0] == 1);
  75. CHECK(r1[1] == 3);
  76. CHECK(r1[2] == 5);
  77. CHECK(r1[3] == 7);
  78. CHECK(p.out2 == r2 + 4);
  79. CHECK(r2[0] == 2);
  80. CHECK(r2[1] == 4);
  81. CHECK(r2[2] == 6);
  82. CHECK(r2[3] == 8);
  83. }
  84. struct S
  85. {
  86. int i;
  87. };
  88. void test_proj()
  89. {
  90. // Test projections
  91. const S ia[] = {S{1}, S{2}, S{3}, S{4}, S{6}, S{8}, S{5}, S{7}};
  92. S r1[10] = {S{0}};
  93. S r2[10] = {S{0}};
  94. typedef ranges::partition_copy_result<S const *, S*, S*> P;
  95. P p = ranges::partition_copy(ia, r1, r2, is_odd(), &S::i);
  96. CHECK(p.in == std::end(ia));
  97. CHECK(p.out1 == r1 + 4);
  98. CHECK(r1[0].i == 1);
  99. CHECK(r1[1].i == 3);
  100. CHECK(r1[2].i == 5);
  101. CHECK(r1[3].i == 7);
  102. CHECK(p.out2 == r2 + 4);
  103. CHECK(r2[0].i == 2);
  104. CHECK(r2[1].i == 4);
  105. CHECK(r2[2].i == 6);
  106. CHECK(r2[3].i == 8);
  107. }
  108. void test_rvalue()
  109. {
  110. // Test rvalue ranges
  111. const S ia[] = {S{1}, S{2}, S{3}, S{4}, S{6}, S{8}, S{5}, S{7}};
  112. S r1[10] = {};
  113. S r2[10] = {};
  114. auto p = ranges::partition_copy(std::move(ia), r1, r2, is_odd(), &S::i);
  115. #ifndef RANGES_WORKAROUND_MSVC_573728
  116. CHECK(::is_dangling(p.in));
  117. #endif
  118. CHECK(p.out1 == r1 + 4);
  119. CHECK(r1[0].i == 1);
  120. CHECK(r1[1].i == 3);
  121. CHECK(r1[2].i == 5);
  122. CHECK(r1[3].i == 7);
  123. CHECK(p.out2 == r2 + 4);
  124. CHECK(r2[0].i == 2);
  125. CHECK(r2[1].i == 4);
  126. CHECK(r2[2].i == 6);
  127. CHECK(r2[3].i == 8);
  128. std::fill(r1 + 0, r1 + 10, S{});
  129. std::fill(r2 + 0, r2 + 10, S{});
  130. std::vector<S> vec(ranges::begin(ia), ranges::end(ia));
  131. auto q = ranges::partition_copy(std::move(vec), r1, r2, is_odd(), &S::i);
  132. #ifndef RANGES_WORKAROUND_MSVC_573728
  133. CHECK(::is_dangling(q.in));
  134. #endif
  135. CHECK(q.out1 == r1 + 4);
  136. CHECK(r1[0].i == 1);
  137. CHECK(r1[1].i == 3);
  138. CHECK(r1[2].i == 5);
  139. CHECK(r1[3].i == 7);
  140. CHECK(q.out2 == r2 + 4);
  141. CHECK(r2[0].i == 2);
  142. CHECK(r2[1].i == 4);
  143. CHECK(r2[2].i == 6);
  144. CHECK(r2[3].i == 8);
  145. }
  146. constexpr bool test_constexpr()
  147. {
  148. using namespace ranges;
  149. const int ia[] = {1, 2, 3, 4, 6, 8, 5, 7};
  150. int r1[10] = {0};
  151. int r2[10] = {0};
  152. const auto p = partition_copy(ia, r1, r2, is_odd());
  153. STATIC_CHECK_RETURN(p.in == std::end(ia));
  154. STATIC_CHECK_RETURN(p.out1 == r1 + 4);
  155. STATIC_CHECK_RETURN(r1[0] == 1);
  156. STATIC_CHECK_RETURN(r1[1] == 3);
  157. STATIC_CHECK_RETURN(r1[2] == 5);
  158. STATIC_CHECK_RETURN(r1[3] == 7);
  159. STATIC_CHECK_RETURN(p.out2 == r2 + 4);
  160. STATIC_CHECK_RETURN(r2[0] == 2);
  161. STATIC_CHECK_RETURN(r2[1] == 4);
  162. STATIC_CHECK_RETURN(r2[2] == 6);
  163. STATIC_CHECK_RETURN(r2[3] == 8);
  164. return true;
  165. }
  166. int main()
  167. {
  168. test_iter<InputIterator<const int*> >();
  169. test_iter<InputIterator<const int*>, Sentinel<const int*>>();
  170. test_range<InputIterator<const int*> >();
  171. test_range<InputIterator<const int*>, Sentinel<const int*>>();
  172. test_proj();
  173. test_rvalue();
  174. {
  175. STATIC_CHECK(test_constexpr());
  176. }
  177. return ::test_result();
  178. }