partition_point.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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 <memory>
  24. #include <utility>
  25. #include <range/v3/core.hpp>
  26. #include <range/v3/algorithm/partition_point.hpp>
  27. #include <range/v3/view/counted.hpp>
  28. #include "../simple_test.hpp"
  29. #include "../test_utils.hpp"
  30. #include "../test_iterators.hpp"
  31. #include "../array.hpp"
  32. struct is_odd
  33. {
  34. constexpr bool operator()(const int & i) const
  35. {
  36. return i & 1;
  37. }
  38. };
  39. template<class Iter, class Sent = Iter>
  40. void
  41. test_iter()
  42. {
  43. {
  44. const int ia[] = {2, 4, 6, 8, 10};
  45. CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
  46. Sent(ranges::end(ia)),
  47. is_odd()) == Iter(ia));
  48. }
  49. {
  50. const int ia[] = {1, 2, 4, 6, 8};
  51. CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
  52. Sent(ranges::end(ia)),
  53. is_odd()) == Iter(ia + 1));
  54. }
  55. {
  56. const int ia[] = {1, 3, 2, 4, 6};
  57. CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
  58. Sent(ranges::end(ia)),
  59. is_odd()) == Iter(ia + 2));
  60. }
  61. {
  62. const int ia[] = {1, 3, 5, 2, 4, 6};
  63. CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
  64. Sent(ranges::end(ia)),
  65. is_odd()) == Iter(ia + 3));
  66. }
  67. {
  68. const int ia[] = {1, 3, 5, 7, 2, 4};
  69. CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
  70. Sent(ranges::end(ia)),
  71. is_odd()) == Iter(ia + 4));
  72. }
  73. {
  74. const int ia[] = {1, 3, 5, 7, 9, 2};
  75. CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
  76. Sent(ranges::end(ia)),
  77. is_odd()) == Iter(ia + 5));
  78. }
  79. {
  80. const int ia[] = {1, 3, 5, 7, 9, 11};
  81. CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
  82. Sent(ranges::end(ia)),
  83. is_odd()) == Iter(ia + 6));
  84. }
  85. {
  86. const int ia[] = {1, 3, 5, 2, 4, 6, 7};
  87. CHECK(ranges::partition_point(Iter(ranges::begin(ia)),
  88. Sent(ranges::begin(ia)),
  89. is_odd()) == Iter(ia));
  90. }
  91. }
  92. template<class Iter, class Sent = Iter>
  93. void
  94. test_range()
  95. {
  96. {
  97. const int ia[] = {2, 4, 6, 8, 10};
  98. CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
  99. Sent(ranges::end(ia)))),
  100. is_odd()) == Iter(ia));
  101. }
  102. {
  103. const int ia[] = {1, 2, 4, 6, 8};
  104. CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
  105. Sent(ranges::end(ia)))),
  106. is_odd()) == Iter(ia + 1));
  107. }
  108. {
  109. const int ia[] = {1, 3, 2, 4, 6};
  110. CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
  111. Sent(ranges::end(ia)))),
  112. is_odd()) == Iter(ia + 2));
  113. }
  114. {
  115. const int ia[] = {1, 3, 5, 2, 4, 6};
  116. CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
  117. Sent(ranges::end(ia)))),
  118. is_odd()) == Iter(ia + 3));
  119. }
  120. {
  121. const int ia[] = {1, 3, 5, 7, 2, 4};
  122. CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
  123. Sent(ranges::end(ia)))),
  124. is_odd()) == Iter(ia + 4));
  125. }
  126. {
  127. const int ia[] = {1, 3, 5, 7, 9, 2};
  128. CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
  129. Sent(ranges::end(ia)))),
  130. is_odd()) == Iter(ia + 5));
  131. }
  132. {
  133. const int ia[] = {1, 3, 5, 7, 9, 11};
  134. CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
  135. Sent(ranges::end(ia)))),
  136. is_odd()) == Iter(ia + 6));
  137. }
  138. {
  139. const int ia[] = {1, 3, 5, 2, 4, 6, 7};
  140. CHECK(ranges::partition_point(::as_lvalue(ranges::make_subrange(Iter(ranges::begin(ia)),
  141. Sent(ranges::begin(ia)))),
  142. is_odd()) == Iter(ia));
  143. }
  144. // An rvalue range
  145. {
  146. const int ia[] = {1, 3, 5, 7, 9, 2};
  147. CHECK(ranges::partition_point(ranges::make_subrange(Iter(ranges::begin(ia)),
  148. Sent(ranges::end(ia))),
  149. is_odd()) == Iter(ia + 5));
  150. }
  151. }
  152. template<class Iter>
  153. void
  154. test_counted()
  155. {
  156. {
  157. const int ia[] = {2, 4, 6, 8, 10};
  158. CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
  159. ranges::size(ia))),
  160. is_odd()) == ranges::counted_iterator<Iter>(Iter(ia), ranges::size(ia)));
  161. }
  162. {
  163. const int ia[] = {1, 2, 4, 6, 8};
  164. CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
  165. ranges::size(ia))),
  166. is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 1), ranges::size(ia) - 1));
  167. }
  168. {
  169. const int ia[] = {1, 3, 2, 4, 6};
  170. CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
  171. ranges::size(ia))),
  172. is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 2), ranges::size(ia) - 2));
  173. }
  174. {
  175. const int ia[] = {1, 3, 5, 2, 4, 6};
  176. CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
  177. ranges::size(ia))),
  178. is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 3), ranges::size(ia) - 3));
  179. }
  180. {
  181. const int ia[] = {1, 3, 5, 7, 2, 4};
  182. CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
  183. ranges::size(ia))),
  184. is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 4), ranges::size(ia) - 4));
  185. }
  186. {
  187. const int ia[] = {1, 3, 5, 7, 9, 2};
  188. CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
  189. ranges::size(ia))),
  190. is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 5), ranges::size(ia) - 5));
  191. }
  192. {
  193. const int ia[] = {1, 3, 5, 7, 9, 11};
  194. CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
  195. ranges::size(ia))),
  196. is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 6), ranges::size(ia) - 6));
  197. }
  198. {
  199. const int ia[] = {1, 3, 5, 2, 4, 6, 7};
  200. CHECK(ranges::partition_point(::as_lvalue(ranges::views::counted(Iter(ranges::begin(ia)),
  201. 0)),
  202. is_odd()) == ranges::counted_iterator<Iter>(Iter(ia), 0));
  203. }
  204. }
  205. struct S
  206. {
  207. int i;
  208. };
  209. int main()
  210. {
  211. test_iter<ForwardIterator<const int*> >();
  212. test_iter<ForwardIterator<const int*>, Sentinel<const int*>>();
  213. test_range<ForwardIterator<const int*> >();
  214. test_range<ForwardIterator<const int*>, Sentinel<const int*>>();
  215. test_counted<ForwardIterator<const int*> >();
  216. // Test projections
  217. const S ia[] = {S{1}, S{3}, S{5}, S{2}, S{4}, S{6}};
  218. CHECK(ranges::partition_point(ia, is_odd(), &S::i) == ia + 3);
  219. {
  220. constexpr test::array<int, 6> a{{1, 3, 5, 2, 4, 6}};
  221. STATIC_CHECK(ranges::partition_point(a, is_odd()) == ranges::begin(a) + 3);
  222. }
  223. return ::test_result();
  224. }