sample.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. // Range v3 lbrary
  2. //
  3. // Copyright Eric Niebler 2014-present
  4. // Copyright Casey Carter 2016
  5. //
  6. // Use, modification and distrbution 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. //
  13. // Copyright 2005 - 2007 Adobe Systems Incorporated
  14. // Distrbuted under the MIT License(see accompanying file LICENSE_1_0_0.txt
  15. // or a copy at http://stlab.adobe.com/licenses.html)
  16. //===----------------------------------------------------------------------===//
  17. //
  18. // The LLVM Compiler Infrastructure
  19. //
  20. // This file is dual licensed under the MIT and the University of Illinois Open
  21. // Source Licenses. See LICENSE.TXT for details.
  22. //
  23. //===----------------------------------------------------------------------===//
  24. #include <array>
  25. #include <range/v3/core.hpp>
  26. #include <range/v3/algorithm/equal.hpp>
  27. #include <range/v3/algorithm/sample.hpp>
  28. #include <range/v3/numeric/iota.hpp>
  29. #include <range/v3/iterator/move_iterators.hpp>
  30. #include "../simple_test.hpp"
  31. #include "../test_utils.hpp"
  32. #include "../test_iterators.hpp"
  33. namespace
  34. {
  35. template<typename I, typename S>
  36. auto in_sequence(I first, I mid, S last) ->
  37. CPP_ret(bool)(
  38. requires ranges::sentinel_for<S, I>)
  39. {
  40. for (; first != mid; ++first)
  41. RANGES_ENSURE(first != last);
  42. for (; first != last; ++first)
  43. ;
  44. return true;
  45. }
  46. }
  47. int main()
  48. {
  49. constexpr unsigned N = 100;
  50. constexpr unsigned K = 10;
  51. {
  52. std::array<int, N> i;
  53. ranges::iota(i, 0);
  54. std::array<int, K> a{}, b{}, c{};
  55. std::minstd_rand g1, g2 = g1;
  56. {
  57. auto result = ranges::sample(RandomAccessIterator<int*>(i.data()),
  58. Sentinel<int*>(i.data()+N), a.begin(), K, g1);
  59. CHECK(in_sequence(i.data(), result.in.base(), i.data() + N));
  60. CHECK(result.out == a.end());
  61. CHECK(!ranges::equal(a, c));
  62. }
  63. {
  64. auto result = ranges::sample(i.begin(), i.end(), b.begin(), K, g1);
  65. CHECK(in_sequence(i.begin(), result.in, i.end()));
  66. CHECK(result.out == b.end());
  67. CHECK(!ranges::equal(a, b));
  68. CHECK(!ranges::equal(b, c));
  69. }
  70. {
  71. auto result = ranges::sample(i.begin(), i.end(), c.begin(), K, g2);
  72. CHECK(in_sequence(i.begin(), result.in, i.end()));
  73. CHECK(result.out == c.end());
  74. CHECK(ranges::equal(a, c));
  75. }
  76. }
  77. {
  78. std::array<int, N> i;
  79. ranges::iota(i, 0);
  80. std::array<int, K> a{}, b{}, c{};
  81. std::minstd_rand g1, g2 = g1;
  82. auto rng = ranges::make_subrange(RandomAccessIterator<int*>(i.data()), Sentinel<int*>(i.data() + N));
  83. {
  84. auto result = ranges::sample(rng, a.begin(), K, g1);
  85. CHECK(in_sequence(ranges::begin(rng), result.in, ranges::end(rng)));
  86. CHECK(result.out == a.end());
  87. CHECK(!ranges::equal(a, b));
  88. }
  89. {
  90. auto result = ranges::sample(i, b.begin(), K, g2);
  91. CHECK(in_sequence(i.begin(), result.in, i.end()));
  92. CHECK(result.out == b.end());
  93. CHECK(ranges::equal(a, b));
  94. }
  95. {
  96. auto result = ranges::sample(i, b.begin(), K, g1);
  97. CHECK(in_sequence(i.begin(), result.in, i.end()));
  98. CHECK(result.out == b.end());
  99. CHECK(!ranges::equal(a, b));
  100. CHECK(!ranges::equal(b, c));
  101. }
  102. {
  103. a.fill(0);
  104. auto result = ranges::sample(std::move(rng), a.begin(), K, g1);
  105. CHECK(in_sequence(ranges::begin(rng), result.in, ranges::end(rng)));
  106. CHECK(result.out == a.end());
  107. CHECK(!ranges::equal(a, c));
  108. }
  109. }
  110. {
  111. std::array<int, N> i;
  112. ranges::iota(i, 0);
  113. std::array<int, K> a{}, b{}, c{};
  114. {
  115. auto result = ranges::sample(RandomAccessIterator<int*>(i.data()),
  116. Sentinel<int*>(i.data() + N), a.begin(), K);
  117. CHECK(in_sequence(i.data(), result.in.base(), i.data() + N));
  118. CHECK(result.out == a.end());
  119. CHECK(!ranges::equal(a, b));
  120. }
  121. {
  122. auto result = ranges::sample(i, b.begin(), K);
  123. CHECK(in_sequence(i.begin(), result.in, i.end()));
  124. CHECK(result.out == b.end());
  125. CHECK(!ranges::equal(b, c));
  126. CHECK(!ranges::equal(a, b));
  127. }
  128. }
  129. {
  130. std::array<MoveOnlyString, 10> source;
  131. std::array<MoveOnlyString, 4> dest;
  132. auto result = ranges::sample(ranges::make_move_iterator(source.begin()),
  133. ranges::make_move_sentinel(source.end()),
  134. ForwardIterator<MoveOnlyString*>(dest.data()), dest.size());
  135. CHECK(in_sequence(ranges::make_move_iterator(source.begin()),
  136. result.in,
  137. ranges::make_move_sentinel(source.end())));
  138. CHECK(result.out == ForwardIterator<MoveOnlyString*>(dest.data() + dest.size()));
  139. }
  140. {
  141. std::array<int, N> i;
  142. ranges::iota(i, 0);
  143. std::array<int, K> a{}, b{}, c{};
  144. std::minstd_rand g1, g2 = g1;
  145. {
  146. auto result = ranges::sample(RandomAccessIterator<int*>(i.data()),
  147. Sentinel<int*>(i.data()+N), a, g1);
  148. CHECK(in_sequence(i.data(), result.in.base(), i.data() + N));
  149. CHECK(result.out == a.end());
  150. CHECK(!ranges::equal(a, c));
  151. }
  152. {
  153. auto result = ranges::sample(i.begin(), i.end(), b, g1);
  154. CHECK(in_sequence(i.begin(), result.in, i.end()));
  155. CHECK(result.out == b.end());
  156. CHECK(!ranges::equal(a, b));
  157. CHECK(!ranges::equal(b, c));
  158. }
  159. {
  160. auto result = ranges::sample(i.begin(), i.end(), c, g2);
  161. CHECK(in_sequence(i.begin(), result.in, i.end()));
  162. CHECK(result.out == c.end());
  163. CHECK(ranges::equal(a, c));
  164. }
  165. }
  166. {
  167. std::array<int, N> i;
  168. ranges::iota(i, 0);
  169. std::array<int, K> a{}, b{}, c{};
  170. std::minstd_rand g1, g2 = g1;
  171. auto rng = ranges::make_subrange(RandomAccessIterator<int*>(i.data()), Sentinel<int*>(i.data() + N));
  172. {
  173. auto result = ranges::sample(rng, a, g1);
  174. CHECK(in_sequence(i.data(), result.in.base(), i.data() + N));
  175. CHECK(result.out == a.end());
  176. CHECK(!ranges::equal(a, b));
  177. }
  178. {
  179. auto result = ranges::sample(i, b, g2);
  180. CHECK(in_sequence(i.begin(), result.in, i.end()));
  181. CHECK(result.out == b.end());
  182. CHECK(ranges::equal(a, b));
  183. }
  184. {
  185. auto result = ranges::sample(i, b, g1);
  186. CHECK(in_sequence(i.begin(), result.in, i.end()));
  187. CHECK(result.out == b.end());
  188. CHECK(!ranges::equal(a, b));
  189. CHECK(!ranges::equal(b, c));
  190. }
  191. {
  192. a.fill(0);
  193. auto result = ranges::sample(std::move(rng), a, g1);
  194. CHECK(in_sequence(i.data(), result.in.base(), i.data() + N));
  195. CHECK(result.out == a.end());
  196. CHECK(!ranges::equal(a, c));
  197. }
  198. }
  199. {
  200. std::array<int, N> i;
  201. ranges::iota(i, 0);
  202. std::array<int, K> a{}, b{}, c{};
  203. {
  204. auto result = ranges::sample(RandomAccessIterator<int*>(i.data()),
  205. Sentinel<int*>(i.data() + N), a);
  206. CHECK(in_sequence(i.data(), result.in.base(), i.data() + N));
  207. CHECK(result.out == a.end());
  208. CHECK(!ranges::equal(a, b));
  209. }
  210. {
  211. auto result = ranges::sample(i, b);
  212. CHECK(in_sequence(i.begin(), result.in, i.end()));
  213. CHECK(result.out == b.end());
  214. CHECK(!ranges::equal(b, c));
  215. CHECK(!ranges::equal(a, b));
  216. }
  217. }
  218. {
  219. std::array<MoveOnlyString, 10> source;
  220. std::array<MoveOnlyString, 4> dest;
  221. auto out = ranges::make_subrange(
  222. ForwardIterator<MoveOnlyString*>(dest.data()),
  223. Sentinel<MoveOnlyString*, true>(dest.data() + dest.size()));
  224. auto result = ranges::sample(ranges::make_move_iterator(source.begin()),
  225. ranges::make_move_sentinel(source.end()), out);
  226. CHECK(in_sequence(source.begin(), result.in.base(), source.end()));
  227. CHECK(result.out == ranges::end(out));
  228. }
  229. {
  230. int data[] = {0,1,2,3};
  231. int sample[2];
  232. std::minstd_rand g;
  233. {
  234. auto result = ranges::sample(data, sample, g);
  235. CHECK(in_sequence(ranges::begin(data), result.in, ranges::end(data)));
  236. CHECK(result.out == ranges::end(sample));
  237. }
  238. {
  239. auto result = ranges::sample(data, sample);
  240. CHECK(in_sequence(ranges::begin(data), result.in, ranges::end(data)));
  241. CHECK(result.out == ranges::end(sample));
  242. }
  243. {
  244. auto result = ranges::sample(data + 0, data + 2, sample + 0, 9999);
  245. CHECK(result.in == data + 2);
  246. CHECK(result.out == sample + 2);
  247. }
  248. }
  249. return ::test_result();
  250. }